Merge branch '6400-glab-mr-checkout-number-results-in-404-error-if-you-don-t-have-access-to-the-source-repository' into 'main'

feat(checkout): Fixing bug with private forks

Closes #6400

See merge request https://gitlab.com/gitlab-org/cli/-/merge_requests/1324

Merged-by: Jay McCure <jmccure@gitlab.com>
Approved-by: Huzaifa Iftikhar <hiftikhar@gitlab.com>
Approved-by: Jay McCure <jmccure@gitlab.com>
Co-authored-by: Gary Holtz <gholtz@gitlab.com>
This commit is contained in:
Jay McCure 2024-03-25 08:14:45 +00:00
commit 3fc655c970
2 changed files with 74 additions and 3 deletions

View File

@ -6,6 +6,7 @@ import (
"github.com/MakeNowJust/heredoc"
"github.com/spf13/cobra"
"github.com/xanzy/go-gitlab"
"gitlab.com/gitlab-org/cli/api"
"gitlab.com/gitlab-org/cli/commands/cmdutils"
"gitlab.com/gitlab-org/cli/commands/mr/mrutils"
@ -67,12 +68,24 @@ func NewCmdCheckout(f *cmdutils.Factory) *cobra.Command {
mrCheckoutCfg.branch = mr.SourceBranch
}
mrProject, err := api.GetProject(apiClient, mr.SourceProjectID)
var mrRef string
var mrProject *gitlab.Project
mrProject, err = api.GetProject(apiClient, mr.SourceProjectID)
if err != nil {
return err
// If we don't have access to the source project, let's try the target project
mrProject, err = api.GetProject(apiClient, mr.TargetProjectID)
if err != nil {
return err
} else {
// We found the target project, let's find the ref another way
mrRef = fmt.Sprintf("refs/merge-requests/%d/head", mr.IID)
}
} else {
mrRef = fmt.Sprintf("refs/heads/%s", mr.SourceBranch)
}
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

View File

@ -122,6 +122,64 @@ func TestMrCheckout(t *testing.T) {
"git checkout feat-new-mr",
},
},
{
name: "when a valid MR comes from a forked private project",
commandArgs: "123",
branch: "main",
httpMocks: []httpMock{
{
http.MethodGet,
"/api/v4/projects/OWNER/REPO/merge_requests/123",
http.StatusOK,
`{
"id": 123,
"iid": 123,
"project_id": 3,
"source_project_id": 3,
"target_project_id": 4,
"title": "test mr title",
"description": "test mr description",
"allow_collaboration": false,
"state": "opened",
"source_branch":"feat-new-mr"
}`,
},
{
http.MethodGet,
"/api/v4/projects/4",
http.StatusOK,
`{
"id": 4,
"ssh_url_to_repo": "git@gitlab.com:OWNER/REPO.git"
}`,
},
{
http.MethodGet,
"/api/v4/projects/3",
http.StatusNotFound,
`{
"message":"404 Project Not Found"
}`,
},
},
shelloutStubs: []string{
"HEAD branch: master\n",
"\n",
"\n",
heredoc.Doc(`
deadbeef HEAD
deadb00f refs/remotes/upstream/feat-new-mr
deadbeef refs/remotes/origin/feat-new-mr
`),
},
expectedShellouts: []string{
"git fetch git@gitlab.com:OWNER/REPO.git refs/merge-requests/123/head:feat-new-mr",
"git config branch.feat-new-mr.remote git@gitlab.com:OWNER/REPO.git",
"git config branch.feat-new-mr.merge refs/merge-requests/123/head",
"git checkout feat-new-mr",
},
},
{
name: "when a valid MR is checked out using MR id and specifying branch",
commandArgs: "123 --branch foo",