From 94ff3e8faea3624d5e1d357bf3c8469ff0847dd4 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Fri, 28 Oct 2016 16:57:26 +0200 Subject: [PATCH] Fix non-master branches and tags This plus the test should ensure no regressions. Git makes it tricky to do some things on a remote that you would think to do on a local repo. `ls-remote` gives me the info I need with only one test for "HEAD" vs anything else. --- main.go | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index 542f949..1340e36 100644 --- a/main.go +++ b/main.go @@ -250,6 +250,11 @@ func updateSymlink(gitRoot, link, newDir string) error { func addWorktreeAndSwap(gitRoot, dest, branch, rev, hash string) error { log.V(0).Infof("syncing to %s (%s)", rev, hash) + // Update from the remote. + if _, err := runCommand(gitRoot, "git", "fetch", "--tags", "origin", branch); err != nil { + return err + } + // Make a worktree for this exact git hash. worktreePath := path.Join(gitRoot, "rev-"+hash) _, err := runCommand(gitRoot, "git", "worktree", "add", worktreePath, "origin/"+branch) @@ -343,7 +348,7 @@ func syncRepo(repo, branch, rev string, depth int, gitRoot, dest string) error { case err != nil: return fmt.Errorf("error checking if repo exists %q: %v", gitRepoPath, err) default: - local, remote, err := getRevs(target, rev) + local, remote, err := getRevs(target, branch, rev) if err != nil { return err } @@ -362,21 +367,23 @@ func syncRepo(repo, branch, rev string, depth int, gitRoot, dest string) error { } // getRevs returns the local and upstream hashes for rev. -func getRevs(localDir, rev string) (string, string, error) { +func getRevs(localDir, branch, rev string) (string, string, error) { // Ask git what the exact hash is for rev. local, err := hashForRev(rev, localDir) if err != nil { return "", "", err } - // Fetch rev from upstream. - _, err = runCommand(localDir, "git", "fetch", "--tags", "origin", rev) - if err != nil { - return "", "", err + // Build a ref string, depending on whether the user asked to track HEAD or a tag. + ref := "" + if rev == "HEAD" { + ref = "refs/heads/" + branch + } else { + ref = "refs/tags/" + rev + "^{}" } - // Ask git what the exact hash is for upstream rev. - remote, err := hashForRev("FETCH_HEAD", localDir) + // Figure out what hash the remote resolves ref to. + remote, err := remoteHashForRef(ref, localDir) if err != nil { return "", "", err } @@ -384,6 +391,15 @@ func getRevs(localDir, rev string) (string, string, error) { return local, remote, nil } +func remoteHashForRef(ref, gitRoot string) (string, error) { + output, err := runCommand(gitRoot, "git", "ls-remote", "-q", "origin", ref) + if err != nil { + return "", err + } + parts := strings.Split(string(output), "\t") + return parts[0], nil +} + func cmdForLog(command string, args ...string) string { if strings.ContainsAny(command, " \t\n") { command = fmt.Sprintf("%q", command)