diff options
author | Vincent Ambo <tazjin@google.com> | 2019-12-30T04·06+0100 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2019-12-30T04·06+0100 |
commit | 36beb6d43ccfd551c64d0aeaddae47ec3cff0afe (patch) | |
tree | 48a16f87989889beb1e55287dc0c9f8ee06e27d8 /ops | |
parent | 7c52a205ee3c1df423de0c63b30e666815824839 (diff) |
feat(sync-gcsr): Synchronise all remote branches r/318
Explicitly sets all local branches to all equivalent remote branches after each update. Branches deleted on the remote will eventually disappear when the container is restarted.
Diffstat (limited to 'ops')
-rw-r--r-- | ops/sync-gcsr/main.go | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/ops/sync-gcsr/main.go b/ops/sync-gcsr/main.go index 358c54805584..a02f6d552730 100644 --- a/ops/sync-gcsr/main.go +++ b/ops/sync-gcsr/main.go @@ -12,6 +12,7 @@ import ( "time" git "gopkg.in/src-d/go-git.v4" + "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/transport/http" ) @@ -24,8 +25,43 @@ func EnvOr(key, def string) string { return v } -func updateRepo(repo *git.Repository, tree *git.Worktree, opts *git.PullOptions) error { - err := tree.Pull(opts) +// ensure that all remote branches exist locally & are up to date. +func updateBranches(auth *http.BasicAuth, repo *git.Repository) error { + origin, err := repo.Remote("origin") + if err != nil { + return err + } + + refs, err := origin.List(&git.ListOptions{ + Auth: auth, + }) + if err != nil { + return err + } + + for _, ref := range refs { + if !ref.Name().IsBranch() || ref.Type() != plumbing.HashReference { + continue + } + + branch := plumbing.NewHashReference( + plumbing.NewBranchReferenceName(ref.Name().Short()), + ref.Hash(), + ) + + err := repo.Storer.SetReference(branch) + if err != nil { + return err + } + log.Println("Updated branch", ref.Name().String()) + } + + return nil +} + +func updateRepo(auth *http.BasicAuth, repo *git.Repository, opts *git.FetchOptions) error { + err := repo.Fetch(opts) + if err == git.NoErrAlreadyUpToDate { // nothing to do ... return nil @@ -33,8 +69,8 @@ func updateRepo(repo *git.Repository, tree *git.Worktree, opts *git.PullOptions) return err } - log.Println("Updated local repository mirror") - return nil + log.Println("Fetched updates from remote, updating local branches") + return updateBranches(auth, repo) } func cloneRepo(dest, project, repo string, auth *http.BasicAuth) (*git.Repository, error) { @@ -43,13 +79,13 @@ func cloneRepo(dest, project, repo string, auth *http.BasicAuth) (*git.Repositor URL: fmt.Sprintf("https://source.developers.google.com/p/%s/r/%s", project, repo), } - handle, err := git.PlainClone(dest, false, &cloneOpts) + handle, err := git.PlainClone(dest, true, &cloneOpts) if err == git.ErrRepositoryAlreadyExists { handle, err = git.PlainOpen(dest) } - return handle, err + return handle, updateBranches(auth, handle) } func main() { @@ -78,20 +114,16 @@ func main() { log.Println("Initiating update loop") } - tree, err := handle.Worktree() - if err != nil { - log.Fatalln("Failed to open repository worktree:", err) - } - - pullOpts := git.PullOptions{ + fetchOpts := git.FetchOptions{ Auth: auth, Force: true, } for { - if err = updateRepo(handle, tree, &pullOpts); err != nil { + if err = updateRepo(auth, handle, &fetchOpts); err != nil { log.Fatalf("Failed to pull updated repository: %s", err) } - time.Sleep(30 * time.Second) // TODO(tazjin): Config option for pull interval? + + time.Sleep(10 * time.Second) } } |