Set upstream remote to track all branches after initial fetch (#7542)
This commit is contained in:
parent
63a4319f6c
commit
fac497108b
6 changed files with 145 additions and 50 deletions
|
|
@ -36,6 +36,19 @@ type Client struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) Copy() *Client {
|
||||||
|
return &Client{
|
||||||
|
GhPath: c.GhPath,
|
||||||
|
RepoDir: c.RepoDir,
|
||||||
|
GitPath: c.GitPath,
|
||||||
|
Stderr: c.Stderr,
|
||||||
|
Stdin: c.Stdin,
|
||||||
|
Stdout: c.Stdout,
|
||||||
|
|
||||||
|
commandContext: c.commandContext,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) Command(ctx context.Context, args ...string) (*Command, error) {
|
func (c *Client) Command(ctx context.Context, args ...string) (*Command, error) {
|
||||||
if c.RepoDir != "" {
|
if c.RepoDir != "" {
|
||||||
args = append([]string{"-C", c.RepoDir}, args...)
|
args = append([]string{"-C", c.RepoDir}, args...)
|
||||||
|
|
@ -408,6 +421,44 @@ func (c *Client) revParse(ctx context.Context, args ...string) ([]byte, error) {
|
||||||
return cmd.Output()
|
return cmd.Output()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) IsLocalGitRepo(ctx context.Context) (bool, error) {
|
||||||
|
_, err := c.GitDir(ctx)
|
||||||
|
if err != nil {
|
||||||
|
var execError errWithExitCode
|
||||||
|
if errors.As(err, &execError) && execError.ExitCode() == 128 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) UnsetRemoteResolution(ctx context.Context, name string) error {
|
||||||
|
args := []string{"config", "--unset", fmt.Sprintf("remote.%s.gh-resolved", name)}
|
||||||
|
cmd, err := c.Command(ctx, args...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) SetRemoteBranches(ctx context.Context, remote string, refspec string) error {
|
||||||
|
args := []string{"remote", "set-branches", remote, refspec}
|
||||||
|
cmd, err := c.Command(ctx, args...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Below are commands that make network calls and need authentication credentials supplied from gh.
|
// Below are commands that make network calls and need authentication credentials supplied from gh.
|
||||||
|
|
||||||
func (c *Client) Fetch(ctx context.Context, remote string, refspec string, mods ...CommandModifier) error {
|
func (c *Client) Fetch(ctx context.Context, remote string, refspec string, mods ...CommandModifier) error {
|
||||||
|
|
@ -513,31 +564,6 @@ func (c *Client) AddRemote(ctx context.Context, name, urlStr string, trackingBra
|
||||||
return remote, nil
|
return remote, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) IsLocalGitRepo(ctx context.Context) (bool, error) {
|
|
||||||
_, err := c.GitDir(ctx)
|
|
||||||
if err != nil {
|
|
||||||
var execError errWithExitCode
|
|
||||||
if errors.As(err, &execError) && execError.ExitCode() == 128 {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) UnsetRemoteResolution(ctx context.Context, name string) error {
|
|
||||||
args := []string{"config", "--unset", fmt.Sprintf("remote.%s.gh-resolved", name)}
|
|
||||||
cmd, err := c.Command(ctx, args...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolveGitPath() (string, error) {
|
func resolveGitPath() (string, error) {
|
||||||
path, err := safeexec.LookPath("git")
|
path, err := safeexec.LookPath("git")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -834,6 +834,84 @@ func TestClientPathFromRoot(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClientUnsetRemoteResolution(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
cmdExitStatus int
|
||||||
|
cmdStdout string
|
||||||
|
cmdStderr string
|
||||||
|
wantCmdArgs string
|
||||||
|
wantErrorMsg string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "unset remote resolution",
|
||||||
|
wantCmdArgs: `path/to/git config --unset remote.origin.gh-resolved`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "git error",
|
||||||
|
cmdExitStatus: 1,
|
||||||
|
cmdStderr: "git error message",
|
||||||
|
wantCmdArgs: `path/to/git config --unset remote.origin.gh-resolved`,
|
||||||
|
wantErrorMsg: "failed to run git: git error message",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
cmd, cmdCtx := createCommandContext(t, tt.cmdExitStatus, tt.cmdStdout, tt.cmdStderr)
|
||||||
|
client := Client{
|
||||||
|
GitPath: "path/to/git",
|
||||||
|
commandContext: cmdCtx,
|
||||||
|
}
|
||||||
|
err := client.UnsetRemoteResolution(context.Background(), "origin")
|
||||||
|
assert.Equal(t, tt.wantCmdArgs, strings.Join(cmd.Args[3:], " "))
|
||||||
|
if tt.wantErrorMsg == "" {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
} else {
|
||||||
|
assert.EqualError(t, err, tt.wantErrorMsg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClientSetRemoteBranches(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
cmdExitStatus int
|
||||||
|
cmdStdout string
|
||||||
|
cmdStderr string
|
||||||
|
wantCmdArgs string
|
||||||
|
wantErrorMsg string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "set remote branches",
|
||||||
|
wantCmdArgs: `path/to/git remote set-branches origin trunk`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "git error",
|
||||||
|
cmdExitStatus: 1,
|
||||||
|
cmdStderr: "git error message",
|
||||||
|
wantCmdArgs: `path/to/git remote set-branches origin trunk`,
|
||||||
|
wantErrorMsg: "failed to run git: git error message",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
cmd, cmdCtx := createCommandContext(t, tt.cmdExitStatus, tt.cmdStdout, tt.cmdStderr)
|
||||||
|
client := Client{
|
||||||
|
GitPath: "path/to/git",
|
||||||
|
commandContext: cmdCtx,
|
||||||
|
}
|
||||||
|
err := client.SetRemoteBranches(context.Background(), "origin", "trunk")
|
||||||
|
assert.Equal(t, tt.wantCmdArgs, strings.Join(cmd.Args[3:], " "))
|
||||||
|
if tt.wantErrorMsg == "" {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
} else {
|
||||||
|
assert.EqualError(t, err, tt.wantErrorMsg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestClientFetch(t *testing.T) {
|
func TestClientFetch(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
||||||
|
|
@ -46,16 +46,9 @@ func (g *gitExecuter) Fetch(remote string, refspec string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *gitExecuter) ForRepo(repoDir string) gitClient {
|
func (g *gitExecuter) ForRepo(repoDir string) gitClient {
|
||||||
return &gitExecuter{
|
gc := g.client.Copy()
|
||||||
client: &git.Client{
|
gc.RepoDir = repoDir
|
||||||
GhPath: g.client.GhPath,
|
return &gitExecuter{client: gc}
|
||||||
RepoDir: repoDir,
|
|
||||||
GitPath: g.client.GitPath,
|
|
||||||
Stderr: g.client.Stderr,
|
|
||||||
Stdin: g.client.Stdin,
|
|
||||||
Stdout: g.client.Stdout,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *gitExecuter) Pull(remote, branch string) error {
|
func (g *gitExecuter) Pull(remote, branch string) error {
|
||||||
|
|
|
||||||
|
|
@ -175,12 +175,19 @@ func cloneRun(opts *CloneOptions) error {
|
||||||
upstreamName = canonicalRepo.Parent.RepoOwner()
|
upstreamName = canonicalRepo.Parent.RepoOwner()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = gitClient.AddRemote(ctx, upstreamName, upstreamURL, []string{canonicalRepo.Parent.DefaultBranchRef.Name}, git.WithRepoDir(cloneDir))
|
gc := gitClient.Copy()
|
||||||
|
gc.RepoDir = cloneDir
|
||||||
|
|
||||||
|
_, err = gc.AddRemote(ctx, upstreamName, upstreamURL, []string{canonicalRepo.Parent.DefaultBranchRef.Name})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gitClient.Fetch(ctx, upstreamName, "", git.WithRepoDir(cloneDir)); err != nil {
|
if err := gc.Fetch(ctx, upstreamName, ""); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gc.SetRemoteBranches(ctx, upstreamName, `*`); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -247,6 +247,7 @@ func Test_RepoClone_hasParent(t *testing.T) {
|
||||||
cs.Register(`git clone https://github.com/OWNER/REPO.git`, 0, "")
|
cs.Register(`git clone https://github.com/OWNER/REPO.git`, 0, "")
|
||||||
cs.Register(`git -C REPO remote add -t trunk upstream https://github.com/hubot/ORIG.git`, 0, "")
|
cs.Register(`git -C REPO remote add -t trunk upstream https://github.com/hubot/ORIG.git`, 0, "")
|
||||||
cs.Register(`git -C REPO fetch upstream`, 0, "")
|
cs.Register(`git -C REPO fetch upstream`, 0, "")
|
||||||
|
cs.Register(`git -C REPO remote set-branches upstream *`, 0, "")
|
||||||
|
|
||||||
_, err := runCloneCommand(httpClient, "OWNER/REPO")
|
_, err := runCloneCommand(httpClient, "OWNER/REPO")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -284,6 +285,7 @@ func Test_RepoClone_hasParent_upstreamRemoteName(t *testing.T) {
|
||||||
cs.Register(`git clone https://github.com/OWNER/REPO.git`, 0, "")
|
cs.Register(`git clone https://github.com/OWNER/REPO.git`, 0, "")
|
||||||
cs.Register(`git -C REPO remote add -t trunk test https://github.com/hubot/ORIG.git`, 0, "")
|
cs.Register(`git -C REPO remote add -t trunk test https://github.com/hubot/ORIG.git`, 0, "")
|
||||||
cs.Register(`git -C REPO fetch test`, 0, "")
|
cs.Register(`git -C REPO fetch test`, 0, "")
|
||||||
|
cs.Register(`git -C REPO remote set-branches test *`, 0, "")
|
||||||
|
|
||||||
_, err := runCloneCommand(httpClient, "OWNER/REPO --upstream-remote-name test")
|
_, err := runCloneCommand(httpClient, "OWNER/REPO --upstream-remote-name test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -662,8 +662,8 @@ func localInit(gitClient *git.Client, remoteURL, path string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone the client so we do not modify the original client's RepoDir.
|
// Copy the client so we do not modify the original client's RepoDir.
|
||||||
gc := cloneGitClient(gitClient)
|
gc := gitClient.Copy()
|
||||||
gc.RepoDir = path
|
gc.RepoDir = path
|
||||||
|
|
||||||
gitRemoteAdd, err := gc.Command(ctx, "remote", "add", "origin", remoteURL)
|
gitRemoteAdd, err := gc.Command(ctx, "remote", "add", "origin", remoteURL)
|
||||||
|
|
@ -794,14 +794,3 @@ func splitNameAndOwner(name string) (string, string, error) {
|
||||||
}
|
}
|
||||||
return repo.RepoName(), repo.RepoOwner(), nil
|
return repo.RepoName(), repo.RepoOwner(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func cloneGitClient(c *git.Client) *git.Client {
|
|
||||||
return &git.Client{
|
|
||||||
GhPath: c.GhPath,
|
|
||||||
RepoDir: c.RepoDir,
|
|
||||||
GitPath: c.GitPath,
|
|
||||||
Stderr: c.Stderr,
|
|
||||||
Stdin: c.Stdin,
|
|
||||||
Stdout: c.Stdout,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue