Skip to content

Commit

Permalink
gitutil: find default remote by tracking branch
Browse files Browse the repository at this point in the history
Using this command resolves remote based on remote
tracking branch of the curently selected branch and
should be more precise in case we can't predict if user
uses origin to mark upstream or their fork.

Signed-off-by: Tonis Tiigi <[email protected]>
  • Loading branch information
tonistiigi committed Dec 1, 2023
1 parent d826375 commit 6028094
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
24 changes: 23 additions & 1 deletion util/gitutil/gitutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,13 @@ func (c *Git) GitDir() (string, error) {
}

func (c *Git) RemoteURL() (string, error) {
// Try to get the remote URL from the origin remote first
// Try default remote based on remote tracking branch
if remote, err := c.currentRemote(); err == nil && remote != "" {
if ru, err := c.clean(c.run("remote", "get-url", remote)); err == nil && ru != "" {
return stripCredentials(ru), nil
}
}
// Next try to get the remote URL from the origin remote first
if ru, err := c.clean(c.run("remote", "get-url", "origin")); err == nil && ru != "" {
return stripCredentials(ru), nil
}
Expand Down Expand Up @@ -149,6 +155,22 @@ func (c *Git) clean(out string, err error) (string, error) {
return out, err
}

func (c *Git) currentRemote() (string, error) {
symref, err := c.clean(c.run("symbolic-ref", "-q", "HEAD"))
if err != nil {
return "", err
}
if symref == "" {
return "", nil
}
// git for-each-ref --format='%(upstream:remotename)'
remote, err := c.clean(c.run("for-each-ref", "--format=%(upstream:remotename)", symref))
if err != nil {
return "", err
}
return remote, nil
}

func IsUnknownRevision(err error) bool {
if err == nil {
return false
Expand Down
38 changes: 36 additions & 2 deletions util/gitutil/gitutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,9 @@ func TestGitDescribeTags(t *testing.T) {

func TestGitRemoteURL(t *testing.T) {
type remote struct {
name string
url string
name string
url string
tracking string
}

cases := []struct {
Expand Down Expand Up @@ -165,6 +166,36 @@ func TestGitRemoteURL(t *testing.T) {
},
fail: true,
},
{
name: "single tracking branch",
remotes: []remote{
{
name: "foo",
url: "https://github.com/tonistiigi/buildx.git",
tracking: "master",
},
},
expected: "https://github.com/tonistiigi/buildx.git",
},
{
name: "fork tracking branch",
remotes: []remote{
{
name: "origin",
url: "[email protected]:crazy-max/buildx.git",
},
{
name: "foobranch",
url: "https://github.com/tonistiigi/buildx.git",
tracking: "master",
},
{
name: "crazymax",
url: "[email protected]:crazy-max/buildx.git",
},
},
expected: "https://github.com/tonistiigi/buildx.git",
},
}
for _, tt := range cases {
tt := tt
Expand All @@ -177,6 +208,9 @@ func TestGitRemoteURL(t *testing.T) {
GitCommit(c, t, "initial commit")
for _, r := range tt.remotes {
GitSetRemote(c, t, r.name, r.url)
if r.tracking != "" {
GitSetMainUpstream(c, t, r.name, r.tracking)
}
}

ru, err := c.RemoteURL()
Expand Down
9 changes: 9 additions & 0 deletions util/gitutil/testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ func GitSetRemote(c *Git, tb testing.TB, name string, url string) {
require.NoError(tb, err)
}

func GitSetMainUpstream(c *Git, tb testing.TB, remote, target string) {
tb.Helper()
_, err := fakeGit(c, "fetch", "--depth", "1", remote, target)
require.NoError(tb, err)

_, err = fakeGit(c, "branch", "--set-upstream-to", remote+"/"+target, "main")
require.NoError(tb, err)
}

func Mktmp(tb testing.TB) string {
tb.Helper()
folder := tb.TempDir()
Expand Down

0 comments on commit 6028094

Please sign in to comment.