aboutsummaryrefslogtreecommitdiffstats
path: root/_examples/checkout-branch/main.go
diff options
context:
space:
mode:
Diffstat (limited to '_examples/checkout-branch/main.go')
-rw-r--r--_examples/checkout-branch/main.go85
1 files changed, 85 insertions, 0 deletions
diff --git a/_examples/checkout-branch/main.go b/_examples/checkout-branch/main.go
new file mode 100644
index 0000000..c7e1333
--- /dev/null
+++ b/_examples/checkout-branch/main.go
@@ -0,0 +1,85 @@
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/go-git/go-git/v5"
+ . "github.com/go-git/go-git/v5/_examples"
+ "github.com/go-git/go-git/v5/config"
+ "github.com/go-git/go-git/v5/plumbing"
+)
+
+// Checkout a branch
+func main() {
+ CheckArgs("<url>", "<directory>", "<branch>")
+ url, directory, branch := os.Args[1], os.Args[2], os.Args[3]
+
+ // Clone the given repository to the given directory
+ Info("git clone %s %s", url, directory)
+ r, err := git.PlainClone(directory, false, &git.CloneOptions{
+ URL: url,
+ })
+ CheckIfError(err)
+
+ // ... retrieving the commit being pointed by HEAD
+ Info("git show-ref --head HEAD")
+ ref, err := r.Head()
+ CheckIfError(err)
+
+ fmt.Println(ref.Hash())
+
+ w, err := r.Worktree()
+ CheckIfError(err)
+
+ // ... checking out branch
+ Info("git checkout %s", branch)
+
+ branchRefName := fmt.Sprintf("refs/heads/%s", branch)
+ branchCoOpts := git.CheckoutOptions{
+ Branch: plumbing.ReferenceName(branchRefName),
+ Force: true,
+ }
+ if err := w.Checkout(&branchCoOpts); err != nil {
+ Warning("local checkout of branch '%s' failed, will attempt to fetch remote branch of same name.", branch)
+ Warning("like `git checkout <branch>` defaulting to `git checkout -b <branch> --track <remote>/<branch>`")
+
+ mirrorRemoteBranchRefSpec := fmt.Sprintf("refs/heads/%s:refs/heads/%s", branch, branch)
+ err = fetchOrigin(r, mirrorRemoteBranchRefSpec)
+ CheckIfError(err)
+
+ err = w.Checkout(&branchCoOpts)
+ CheckIfError(err)
+ }
+ CheckIfError(err)
+
+ Info("checked out branch: %s", branch)
+
+ // ... retrieving the commit being pointed by HEAD (branch now)
+ Info("git show-ref --head HEAD")
+ ref, err = r.Head()
+ CheckIfError(err)
+ fmt.Println(ref.Hash())
+}
+
+func fetchOrigin(repo *git.Repository, refSpecStr string) error {
+ remote, err := repo.Remote("origin")
+ CheckIfError(err)
+
+ var refSpecs []config.RefSpec
+ if refSpecStr != "" {
+ refSpecs = []config.RefSpec{config.RefSpec(refSpecStr)}
+ }
+
+ if err = remote.Fetch(&git.FetchOptions{
+ RefSpecs: refSpecs,
+ }); err != nil {
+ if err == git.NoErrAlreadyUpToDate {
+ fmt.Print("refs already up to date")
+ } else {
+ return fmt.Errorf("fetch origin failed: %v", err)
+ }
+ }
+
+ return nil
+}