6
0
mirror of https://github.com/grdl/git-get.git synced 2026-02-05 15:58:47 +00:00

Add a --branch flag that specifies which branch or tag to check out after cloning

This commit is contained in:
Grzegorz Dlugoszewski
2020-06-08 21:37:26 +02:00
parent 919359f26f
commit dfef6151d1
5 changed files with 72 additions and 12 deletions

View File

@@ -4,6 +4,8 @@ import (
"fmt"
"git-get/cfg"
"github.com/go-git/go-git/v5/plumbing"
"io"
"io/ioutil"
"net/url"
@@ -24,7 +26,7 @@ type Repo struct {
Status *RepoStatus
}
func CloneRepo(url *url.URL, path string, quiet bool) (*Repo, error) {
func CloneRepo(url *url.URL, path string, branch string, quiet bool) (*Repo, error) {
var progress io.Writer
if !quiet {
progress = os.Stdout
@@ -40,11 +42,18 @@ func CloneRepo(url *url.URL, path string, quiet bool) (*Repo, error) {
}
}
// If branch name is actually a tag (ie. is prefixed with refs/tags) - check out that tag.
// Otherwise, assume it's a branch name and check it out.
refName := plumbing.ReferenceName(branch)
if !refName.IsTag() {
refName = plumbing.NewBranchReferenceName(branch)
}
opts := &git.CloneOptions{
URL: url.String(),
Auth: auth,
RemoteName: git.DefaultRemoteName,
ReferenceName: "",
ReferenceName: refName,
SingleBranch: false,
NoCheckout: false,
Depth: 0,

View File

@@ -83,7 +83,7 @@ func newRepoWithLocalBranch(t *testing.T) *Repo {
func newRepoWithClonedBranch(t *testing.T) *Repo {
origin := newRepoWithCommit(t)
r := origin.clone(t)
r := origin.clone(t, "master")
r.newBranch(t, "local")
r.checkoutBranch(t, "local")
@@ -105,7 +105,7 @@ func newRepoWithDetachedHead(t *testing.T) *Repo {
func newRepoWithBranchAhead(t *testing.T) *Repo {
origin := newRepoWithCommit(t)
r := origin.clone(t)
r := origin.clone(t, "master")
r.writeFile(t, "new", "I'm a new file")
r.addFile(t, "new")
r.newCommit(t, "new commit")
@@ -116,7 +116,7 @@ func newRepoWithBranchAhead(t *testing.T) *Repo {
func newRepoWithBranchBehind(t *testing.T) *Repo {
origin := newRepoWithCommit(t)
r := origin.clone(t)
r := origin.clone(t, "master")
origin.writeFile(t, "origin.new", "I'm a new file on origin")
origin.addFile(t, "origin.new")
@@ -130,7 +130,7 @@ func newRepoWithBranchBehind(t *testing.T) *Repo {
func newRepoWithBranchAheadAndBehind(t *testing.T) *Repo {
origin := newRepoWithCommit(t)
r := origin.clone(t)
r := origin.clone(t, "master")
r.writeFile(t, "local.new", "local 1")
r.addFile(t, "local.new")
r.newCommit(t, "1st local commit")
@@ -155,6 +155,22 @@ func newRepoWithBranchAheadAndBehind(t *testing.T) *Repo {
return r
}
func newRepoWithCheckedOutBranch(t *testing.T) *Repo {
origin := newRepoWithCommit(t)
origin.newBranch(t, "feature/branch1")
r := origin.clone(t, "feature/branch1")
return r
}
func newRepoWithCheckedOutTag(t *testing.T) *Repo {
origin := newRepoWithCommit(t)
origin.newTag(t, "v1.0.0")
r := origin.clone(t, "refs/tags/v1.0.0")
return r
}
func newTempDir(t *testing.T) string {
dir, err := ioutil.TempDir("", "git-get-repo-")
checkFatal(t, errors.Wrap(err, "Failed creating test repo directory"))
@@ -216,12 +232,22 @@ func (r *Repo) newBranch(t *testing.T, name string) {
checkFatal(t, err)
}
func (r *Repo) clone(t *testing.T) *Repo {
func (r *Repo) newTag(t *testing.T, name string) {
head, err := r.Head()
checkFatal(t, err)
ref := plumbing.NewHashReference(plumbing.NewTagReferenceName(name), head.Hash())
err = r.Storer.SetReference(ref)
checkFatal(t, err)
}
func (r *Repo) clone(t *testing.T, branch string) *Repo {
dir := newTempDir(t)
repoURL, err := url.Parse("file://" + r.Path)
checkFatal(t, err)
repo, err := CloneRepo(repoURL, dir, true)
repo, err := CloneRepo(repoURL, dir, branch, true)
checkFatal(t, err)
return repo

View File

@@ -155,16 +155,36 @@ func TestStatus(t *testing.T) {
},
},
}},
{newRepoWithCheckedOutBranch, &RepoStatus{
HasUntrackedFiles: false,
HasUncommittedChanges: false,
CurrentBranch: "feature/branch1",
Branches: []*BranchStatus{
{
Name: "feature/branch1",
Upstream: "origin/feature/branch1",
Behind: 0,
Ahead: 0,
},
},
}},
{newRepoWithCheckedOutTag, &RepoStatus{
HasUntrackedFiles: false,
HasUncommittedChanges: false,
// TODO: is this correct? Can we show tag name instead of "detached HEAD"?
CurrentBranch: StatusDetached,
Branches: nil,
}},
}
for _, test := range tests {
for i, test := range tests {
repo := test.makeTestRepo(t)
err := repo.LoadStatus()
checkFatal(t, err)
if !reflect.DeepEqual(repo.Status, test.want) {
t.Errorf("Wrong repo status, got: %+v; want: %+v", repo.Status, test.want)
t.Errorf("Failed test case %d, got: %+v; want: %+v", i, repo.Status, test.want)
}
}
}