summaryrefslogtreecommitdiff
path: root/fi-sponge/sponge.go
diff options
context:
space:
mode:
Diffstat (limited to 'fi-sponge/sponge.go')
-rw-r--r--fi-sponge/sponge.go108
1 files changed, 108 insertions, 0 deletions
diff --git a/fi-sponge/sponge.go b/fi-sponge/sponge.go
new file mode 100644
index 0000000..1d42143
--- /dev/null
+++ b/fi-sponge/sponge.go
@@ -0,0 +1,108 @@
+// Copyright 2019 Luke Shumaker <lukeshu@parabola.nu>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+// Command fi-sponge soaks up a fast-import stream, and re-emits it,
+// potentially with different flags.
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "syscall"
+)
+
+func usage() {
+ fmt.Printf("Usage: git fast-export | %s [FAST-IMPORT-FLAGS] -- [FAST-EXPORT-FLAGS] | git fast-import\n", os.Args[0])
+}
+
+func main() {
+ var split int
+ for i := range os.Args {
+ switch os.Args[i] {
+ case "--":
+ split = i
+ case "-h", "--help":
+ usage()
+ os.Exit(0)
+ }
+ }
+ if split == 0 {
+ fmt.Fprintf(os.Stderr, "%s: must give a '--' argument\n", os.Args[0])
+ fmt.Fprintf(os.Stderr, "Try '%s --help' for more information\n", os.Args[0])
+ os.Exit(2)
+ }
+ inargs := os.Args[1:split]
+ outargs := os.Args[split+1:]
+ err := sponge(inargs, outargs)
+ if err != nil {
+ if ee, ok := err.(*exec.ExitError); ok {
+ ws := ee.ProcessState.Sys().(syscall.WaitStatus)
+ switch {
+ case ws.Exited():
+ os.Exit(ws.ExitStatus())
+ case ws.Signaled():
+ os.Exit(128 + int(ws.Signal()))
+ }
+ } else {
+ fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err)
+ os.Exit(255)
+ }
+ }
+}
+
+func sponge(inargs, outargs []string) error {
+ tmpdir, err := ioutil.TempDir("", filepath.Base(os.Args[0])+".")
+ if err != nil {
+ return err
+ }
+ defer os.RemoveAll(tmpdir)
+
+ cmd := exec.Command("git", "init", ".")
+ cmd.Dir = tmpdir
+ cmd.Stdout = os.Stderr
+ cmd.Stderr = os.Stderr
+ if err := cmd.Run(); err != nil {
+ return err
+ }
+
+ cmd = exec.Command("git", append([]string{"fast-import", "--cat-blob-fd=0"}, inargs...)...)
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stderr
+ cmd.Stderr = os.Stderr
+ if err := cmd.Run(); err != nil {
+ return err
+ }
+
+ cmd = exec.Command("git", "for-each-ref", "--format=%(refname)")
+ cmd.Stderr = os.Stderr
+ b, err := cmd.Output()
+ if err != nil {
+ return err
+ }
+ refs := strings.Split(strings.TrimSuffix(string(b), "\n"), "\n")
+
+ cmd = exec.Command("git", append(append([]string{"fast-export"}, outargs...), refs...)...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ if err := cmd.Run(); err != nil {
+ return err
+ }
+
+ return nil
+}