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:
13
git/repo.go
13
git/repo.go
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user