summaryrefslogtreecommitdiff
path: root/src/edit/git.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/edit/git.go')
-rw-r--r--src/edit/git.go111
1 files changed, 66 insertions, 45 deletions
diff --git a/src/edit/git.go b/src/edit/git.go
index 1f8f8ba..4ced7b7 100644
--- a/src/edit/git.go
+++ b/src/edit/git.go
@@ -8,22 +8,73 @@ import (
"os/exec"
"strconv"
"time"
+
+ "os"
)
-// Use .Output() instead of .Run() so that it populates
-// ExitError.Stderr.
+type GitDir string
+
+func (dir GitDir) cmd(args ...string) *exec.Cmd {
+ cmd := exec.Command(args[0], args[1:]...)
+ cmd.Dir = string(dir)
+ return cmd
+}
+
+func (dir GitDir) output(args ...string) ([]byte, error) {
+ return dir.cmd(args...).Output()
+}
-func GitPull() error {
- _, err := exec.Command("git", "fetch").Output()
+func (dir GitDir) run(args ...string) error {
+ // Use .Output() instead of .Run() so that it populates
+ // ExitError.Stderr.
+ _, err := dir.output(args...)
return err
+}
+
+func (dir GitDir) Pull() error {
+ return dir.run("git", "fetch")
+}
+
+func (dir GitDir) Push() error {
+ return dir.run("git", "push")
}
-func GitPush() error {
- _, err := exec.Command("git", "push").Output()
+func (dir GitDir) Commit(commit GitCommit) error {
+ cmd := dir.cmd("git", "fast-import", "--done")
+
+ // stdin
+ pw, err := cmd.StdinPipe()
+ if err != nil {
+ return err
+ }
+
+ // stderr
+ var buf bytes.Buffer
+ cmd.Stderr = &buf
+
+ // run
+ if err = cmd.Start(); err != nil {
+ return err
+ }
+ werr := commit.FastExport(pw)
+ if werr != nil { goto end; }
+ _, werr = io.WriteString(pw, "done\n")
+ if werr != nil { goto end; }
+end:
+ cerr := pw.Close()
+ if err = cmd.Wait(); err != nil {
+ if ee, ok := err.(*exec.ExitError); ok {
+ ee.Stderr = buf.Bytes()
+ }
+ } else if werr != nil {
+ err = werr
+ } else {
+ err = cerr
+ }
return err
}
-type Edit struct {
+type GitCommit struct {
UserName string
UserEmail string
Time time.Time
@@ -35,7 +86,7 @@ func gitTime(t time.Time) string {
return fmt.Sprintf("%d %s", t.Unix(), t.Format("-0700"))
}
-func (edit Edit) WriteTo(w io.WriteCloser) error {
+func (edit GitCommit) FastExport(w io.Writer) error {
var err error
commit := make([]string, len(edit.Files))
i := 0
@@ -70,42 +121,11 @@ data %d
}
}
}
- _, err = fmt.Fprintf(w, "done\n")
- if err != nil {
- return err
- }
- return w.Close()
-}
-
-func GitCommit(edit Edit) error {
- cmd := exec.Command("git", "fast-import", "--done")
-
- // stdin
- pw, err := cmd.StdinPipe()
- if err != nil {
- return err
- }
-
- // stderr
- var buf bytes.Buffer
- cmd.Stderr = &buf
-
- // run
- if err = cmd.Start(); err != nil {
- return err
- }
- werr := edit.WriteTo(pw)
- if err = cmd.Wait(); err != nil {
- if ee, ok := err.(*exec.ExitError); ok {
- ee.Stderr = buf.Bytes()
- }
- } else {
- err = werr
- }
- return err
+ return nil
}
type GitFile struct {
+ Dir GitDir
Mode int32 // 18 bits unsigned
Type string
Hash string
@@ -113,7 +133,7 @@ type GitFile struct {
}
func (f GitFile) Cat() ([]byte, error) {
- return exec.Command("git", "cat-file", "blob", f.Hash).Output()
+ return f.Dir.output("git", "cat-file", "blob", f.Hash)
}
type GitTree map[string]GitFile
@@ -168,16 +188,16 @@ func parseGitTreeLine(line []byte) (rname string, rfile GitFile, err error) {
return
}
-func GitLsTree() (GitTree, error) {
+func (dir GitDir) LsTree() (GitTree, error) {
// Get the root tree-ish
- data, err := exec.Command("git", "rev-parse", "HEAD:").Output()
+ data, err := dir.output("git", "rev-parse", "HEAD:")
if err != nil {
return nil, err
}
treeish := string(bytes.TrimSuffix(data, []byte{'\n'}))
// Recursively read said tree-ish
- data, err = exec.Command("git", "ls-tree", "-trlz", treeish).Output()
+ data, err = dir.output("git", "ls-tree", "-trlz", treeish)
if err != nil {
return nil, err
}
@@ -203,6 +223,7 @@ func GitLsTree() (GitTree, error) {
panic(err)
return nil, err
}
+ file.Dir = dir
ret["/"+name] = file
}
return ret, nil