Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

checkout-branch example #446

Merged
merged 4 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ build-git:
test:
@echo "running against `git version`"; \
$(GOTEST) -race ./...
$(GOTEST) -v _examples/common_test.go _examples/common.go --examples

TEMP_REPO := $(shell mktemp)
test-sha256:
Expand Down
85 changes: 85 additions & 0 deletions _examples/checkout-branch/main.go
Original file line number Diff line number Diff line change
@@ -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 := plumbing.NewBranchReferenceName(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
}
73 changes: 38 additions & 35 deletions _examples/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package examples

import (
"flag"
"go/build"
"os"
"os/exec"
"path/filepath"
"runtime"
"testing"
)

Expand All @@ -14,26 +14,43 @@ var examplesTest = flag.Bool("examples", false, "run the examples tests")
var defaultURL = "https://github.com/git-fixtures/basic.git"

var args = map[string][]string{
"branch": {defaultURL, tempFolder()},
"checkout": {defaultURL, tempFolder(), "35e85108805c84807bc66a02d91535e1e24b38b9"},
"clone": {defaultURL, tempFolder()},
"context": {defaultURL, tempFolder()},
"commit": {cloneRepository(defaultURL, tempFolder())},
"custom_http": {defaultURL},
"open": {cloneRepository(defaultURL, tempFolder())},
"progress": {defaultURL, tempFolder()},
"push": {setEmptyRemote(cloneRepository(defaultURL, tempFolder()))},
"revision": {cloneRepository(defaultURL, tempFolder()), "master~2^"},
"showcase": {defaultURL, tempFolder()},
"tag": {cloneRepository(defaultURL, tempFolder())},
"pull": {createRepositoryWithRemote(tempFolder(), defaultURL)},
"ls": {cloneRepository(defaultURL, tempFolder()), "HEAD", "vendor"},
"merge_base": {cloneRepository(defaultURL, tempFolder()), "--is-ancestor", "HEAD~3", "HEAD^"},
"blame": {defaultURL, "CHANGELOG"},
"branch": {defaultURL, tempFolder()},
"checkout": {defaultURL, tempFolder(), "35e85108805c84807bc66a02d91535e1e24b38b9"},
"checkout-branch": {defaultURL, tempFolder(), "branch"},
"clone": {defaultURL, tempFolder()},
"commit": {cloneRepository(defaultURL, tempFolder())},
"context": {defaultURL, tempFolder()},
"custom_http": {defaultURL},
"find-if-any-tag-point-head": {cloneRepository(defaultURL, tempFolder())},
"ls": {cloneRepository(defaultURL, tempFolder()), "HEAD", "vendor"},
"ls-remote": {defaultURL},
"merge_base": {cloneRepository(defaultURL, tempFolder()), "--is-ancestor", "HEAD~3", "HEAD^"},
"open": {cloneRepository(defaultURL, tempFolder())},
"progress": {defaultURL, tempFolder()},
"pull": {createRepositoryWithRemote(tempFolder(), defaultURL)},
"push": {setEmptyRemote(cloneRepository(defaultURL, tempFolder()))},
"revision": {cloneRepository(defaultURL, tempFolder()), "master~2^"},
"sha256": {tempFolder()},
"showcase": {defaultURL, tempFolder()},
"tag": {cloneRepository(defaultURL, tempFolder())},
}

var ignored = map[string]bool{}
// tests not working / set-up
var ignored = map[string]bool{
"azure_devops": true,
"ls": true,
"sha256": true,
"submodule": true,
"tag-create-push": true,
}

var (
tempFolders = []string{}

var tempFolders = []string{}
_, callingFile, _, _ = runtime.Caller(0)
basepath = filepath.Dir(callingFile)
)

func TestExamples(t *testing.T) {
flag.Parse()
Expand All @@ -44,13 +61,13 @@ func TestExamples(t *testing.T) {

defer deleteTempFolders()

examples, err := filepath.Glob(examplesFolder())
exampleMains, err := filepath.Glob(filepath.Join(basepath, "*", "main.go"))
if err != nil {
t.Errorf("error finding tests: %s", err)
}

for _, example := range examples {
dir := filepath.Dir(example)
for _, main := range exampleMains {
dir := filepath.Dir(main)
_, name := filepath.Split(dir)

if ignored[name] {
Expand All @@ -71,20 +88,6 @@ func tempFolder() string {
return path
}

func packageFolder() string {
return filepath.Join(
build.Default.GOPATH,
"src", "github.com/go-git/go-git/v5",
)
}

func examplesFolder() string {
return filepath.Join(
packageFolder(),
"_examples", "*", "main.go",
)
}

func cloneRepository(url, folder string) string {
cmd := exec.Command("git", "clone", url, folder)
err := cmd.Run()
Expand Down