diff --git a/restore.go b/restore.go index 847d6d9..2c4f725 100644 --- a/restore.go +++ b/restore.go @@ -146,6 +146,22 @@ func download(dep *Dependency) error { if !dep.vcs.exists(dep.root, dep.Rev) { debugln("Updating existing", dep.root) + if dep.vcs.vcs.Name == "Git" { + detached, err := gitDetached(dep.root) + if err != nil { + return err + } + if detached { + db, err := gitDefaultBranch(dep.root) + if err != nil { + return err + } + if err := gitCheckout(dep.root, db); err != nil { + return err + } + } + } + dep.vcs.vcs.Download(dep.root) downloaded[rr.Repo] = true } diff --git a/vcs.go b/vcs.go index 73e6dc0..fcc59e9 100644 --- a/vcs.go +++ b/vcs.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "errors" "fmt" "os" "os/exec" @@ -274,3 +275,33 @@ func hgLink(dir, remote, url string) error { fmt.Fprintf(f, "[paths]\n%s = %s\n", remote, url) return f.Close() } + +func gitDetached(r string) (bool, error) { + o, err := vcsGit.runOutput(r, "status") + if err != nil { + return false, errors.New("unable to determine git status " + err.Error()) + } + return bytes.Contains(o, []byte("HEAD detached at")), nil +} + +func gitDefaultBranch(r string) (string, error) { + e := "Unable to determine default branch: " + hb := []byte("HEAD branch: ") + o, err := vcsGit.runOutput(r, "remote show origin") + if err != nil { + return "", errors.New(e + err.Error()) + } + s := bytes.Index(o, hb) + if s < 0 { + return "", errors.New(e + "git output missing '" + string(hb) + "'") + } + f := bytes.Fields(o[s:]) + if len(f) < 3 { + return "", errors.New(e + "git output too short") + } + return string(f[2]), nil +} + +func gitCheckout(r, b string) error { + return vcsGit.run(r, "checkout "+b) +}