mirror of https://gitlab.com/gitlab-org/cli.git
feat(mr/checkout): Track by default without adding extra remotes
This commit is contained in:
parent
b4c5bba711
commit
9a450081b9
|
@ -1,7 +1,6 @@
|
|||
package checkout
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
@ -28,7 +27,7 @@ func NewCmdCheckout(f *cmdutils.Factory) *cobra.Command {
|
|||
Long: ``,
|
||||
Example: heredoc.Doc(`
|
||||
glab mr checkout 1
|
||||
glab mr checkout branch --track
|
||||
glab mr checkout branch
|
||||
glab mr checkout 12 --branch todo-fix
|
||||
glab mr checkout new-feature --set-upstream-to=upstream/main
|
||||
glab mr checkout # use checked out branch
|
||||
|
@ -39,11 +38,6 @@ func NewCmdCheckout(f *cmdutils.Factory) *cobra.Command {
|
|||
var upstream string
|
||||
|
||||
if mrCheckoutCfg.upstream != "" {
|
||||
// Make sure we don't have the mutually exclusive flags --track and --set-upstream-to
|
||||
if mrCheckoutCfg.track {
|
||||
return &cmdutils.FlagError{Err: errors.New("--track and --set-upstream-to are mutually exclusive")}
|
||||
}
|
||||
|
||||
upstream = mrCheckoutCfg.upstream
|
||||
|
||||
if val := strings.Split(mrCheckoutCfg.upstream, "/"); len(val) > 1 {
|
||||
|
@ -64,7 +58,7 @@ func NewCmdCheckout(f *cmdutils.Factory) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
mr, repo, err := mrutils.MRFromArgs(f, args, "any")
|
||||
mr, _, err := mrutils.MRFromArgs(f, args, "any")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -72,40 +66,32 @@ func NewCmdCheckout(f *cmdutils.Factory) *cobra.Command {
|
|||
if mrCheckoutCfg.branch == "" {
|
||||
mrCheckoutCfg.branch = mr.SourceBranch
|
||||
}
|
||||
fetchToRef := mrCheckoutCfg.branch
|
||||
|
||||
if mrCheckoutCfg.track {
|
||||
if _, err := git.Config("remote." + mr.Author.Username + ".url"); err != nil {
|
||||
mrProject, err := api.GetProject(apiClient, mr.SourceProjectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := git.AddRemote(mr.Author.Username, mrProject.SSHURLToRepo); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
fetchToRef = fmt.Sprintf("refs/remotes/%s/%s", mr.Author.Username, mr.SourceBranch)
|
||||
}
|
||||
remotes, err := f.Remotes()
|
||||
mrProject, err := api.GetProject(apiClient, mr.SourceProjectID)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
repoRemote, err := remotes.FindByRepo(repo.RepoOwner(), repo.RepoName())
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
mrRef := fmt.Sprintf("refs/merge-requests/%d/head", mr.IID)
|
||||
fetchRefSpec := fmt.Sprintf("%s:%s", mrRef, fetchToRef)
|
||||
if err := git.RunCmd([]string{"fetch", repoRemote.Name, fetchRefSpec}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mrCheckoutCfg.track {
|
||||
if err := git.RunCmd([]string{"branch", "--track", mrCheckoutCfg.branch, fetchToRef}); err != nil {
|
||||
mrRef := fmt.Sprintf("refs/heads/%s", mr.SourceBranch)
|
||||
fetchRefSpec := fmt.Sprintf("%s:%s", mrRef, mrCheckoutCfg.branch)
|
||||
if err := git.RunCmd([]string{"fetch", mrProject.SSHURLToRepo, fetchRefSpec}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// .remote is needed for `git pull` to work
|
||||
// .pushRemote is needed for `git push` to work, if user has set `remote.pushDefault`.
|
||||
// see https://git-scm.com/docs/git-config#Documentation/git-config.txt-branchltnamegtremote
|
||||
if err := git.RunCmd([]string{"config", fmt.Sprintf("branch.%s.remote", mrCheckoutCfg.branch), mrProject.SSHURLToRepo}); err != nil {
|
||||
return err
|
||||
}
|
||||
if mr.AllowCollaboration {
|
||||
if err := git.RunCmd([]string{"config", fmt.Sprintf("branch.%s.pushRemote", mrCheckoutCfg.branch), mrProject.SSHURLToRepo}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := git.RunCmd([]string{"config", fmt.Sprintf("branch.%s.merge", mrCheckoutCfg.branch), mrRef}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check out branch
|
||||
if err := git.CheckoutBranch(mrCheckoutCfg.branch); err != nil {
|
||||
|
@ -122,7 +108,8 @@ func NewCmdCheckout(f *cmdutils.Factory) *cobra.Command {
|
|||
},
|
||||
}
|
||||
mrCheckoutCmd.Flags().StringVarP(&mrCheckoutCfg.branch, "branch", "b", "", "checkout merge request with <branch> name")
|
||||
mrCheckoutCmd.Flags().BoolVarP(&mrCheckoutCfg.track, "track", "t", false, "set checked out branch to track remote branch, adds remote if needed")
|
||||
mrCheckoutCmd.Flags().BoolVarP(&mrCheckoutCfg.track, "track", "t", true, "set checked out branch to track remote branch")
|
||||
_ = mrCheckoutCmd.Flags().MarkDeprecated("track", "Now enabled by default")
|
||||
mrCheckoutCmd.Flags().StringVarP(&mrCheckoutCfg.upstream, "set-upstream-to", "u", "", "set tracking of checked out branch to [REMOTE/]BRANCH")
|
||||
return mrCheckoutCmd
|
||||
}
|
||||
|
|
|
@ -86,15 +86,28 @@ func TestMrCheckout(t *testing.T) {
|
|||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"source_project_id": 3,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"allow_collaboration": false,
|
||||
"state": "opened",
|
||||
"source_branch":"feat-new-mr"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/3",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 3,
|
||||
"ssh_url_to_repo": "git@gitlab.com:OWNER/REPO.git"
|
||||
}`,
|
||||
},
|
||||
},
|
||||
shelloutStubs: []string{
|
||||
"HEAD branch: master\n",
|
||||
"\n",
|
||||
"\n",
|
||||
heredoc.Doc(`
|
||||
deadbeef HEAD
|
||||
deadb00f refs/remotes/upstream/feat-new-mr
|
||||
|
@ -102,7 +115,12 @@ func TestMrCheckout(t *testing.T) {
|
|||
`),
|
||||
},
|
||||
|
||||
expectedShellouts: []string{"git fetch upstream refs/merge-requests/123/head:feat-new-mr", "git checkout feat-new-mr"},
|
||||
expectedShellouts: []string{
|
||||
"git fetch git@gitlab.com:OWNER/REPO.git refs/heads/feat-new-mr:feat-new-mr",
|
||||
"git config branch.feat-new-mr.remote git@gitlab.com:OWNER/REPO.git",
|
||||
"git config branch.feat-new-mr.merge refs/heads/feat-new-mr",
|
||||
"git checkout feat-new-mr",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "when a valid MR is checked out using MR id and specifying branch",
|
||||
|
@ -117,15 +135,29 @@ func TestMrCheckout(t *testing.T) {
|
|||
"id": 123,
|
||||
"iid": 123,
|
||||
"project_id": 3,
|
||||
"source_project_id": 4,
|
||||
"title": "test mr title",
|
||||
"description": "test mr description",
|
||||
"allow_collaboration": true,
|
||||
"state": "opened",
|
||||
"source_branch":"feat-new-mr"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/4",
|
||||
http.StatusOK,
|
||||
`{
|
||||
"id": 3,
|
||||
"ssh_url_to_repo": "git@gitlab.com:FORK_OWNER/REPO.git"
|
||||
}`,
|
||||
},
|
||||
},
|
||||
shelloutStubs: []string{
|
||||
"HEAD branch: master\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
heredoc.Doc(`
|
||||
deadbeef HEAD
|
||||
deadb00f refs/remotes/upstream/feat-new-mr
|
||||
|
@ -133,7 +165,13 @@ func TestMrCheckout(t *testing.T) {
|
|||
`),
|
||||
},
|
||||
|
||||
expectedShellouts: []string{"git fetch upstream refs/merge-requests/123/head:foo", "git checkout foo"},
|
||||
expectedShellouts: []string{
|
||||
"git fetch git@gitlab.com:FORK_OWNER/REPO.git refs/heads/feat-new-mr:foo",
|
||||
"git config branch.foo.remote git@gitlab.com:FORK_OWNER/REPO.git",
|
||||
"git config branch.foo.pushRemote git@gitlab.com:FORK_OWNER/REPO.git",
|
||||
"git config branch.foo.merge refs/heads/feat-new-mr",
|
||||
"git checkout foo",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ glab mr checkout [<id> | <branch>] [flags]
|
|||
|
||||
```plaintext
|
||||
glab mr checkout 1
|
||||
glab mr checkout branch --track
|
||||
glab mr checkout branch
|
||||
glab mr checkout 12 --branch todo-fix
|
||||
glab mr checkout new-feature --set-upstream-to=upstream/main
|
||||
glab mr checkout # use checked out branch
|
||||
|
@ -33,7 +33,6 @@ glab mr checkout # use checked out branch
|
|||
```plaintext
|
||||
-b, --branch string checkout merge request with <branch> name
|
||||
-u, --set-upstream-to string set tracking of checked out branch to [REMOTE/]BRANCH
|
||||
-t, --track set checked out branch to track remote branch, adds remote if needed
|
||||
```
|
||||
|
||||
## Options inherited from parent commands
|
||||
|
|
Loading…
Reference in New Issue