From 02dae3f84b80047bef391960eea1350d551e4d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Br=C3=BCckner?= Date: Sun, 29 Oct 2023 13:29:33 +0000 Subject: [PATCH] Fix merge base commit for fast-forwarded GitLab PRs (#27825) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Due to a bug in the GitLab API, the diff_refs field is populated in the response when fetching an individual merge request, but not when fetching a list of them. That field is used to populate the merge base commit SHA. While there is detection for the merge base even when not populated by the downloader, that detection is not flawless. Specifically, when a GitLab merge request has a single commit, and gets merged with the squash strategy, the base branch will be fast-forwarded instead of a separate squash or merge commit being created. The merge base detection attempts to find the last commit on the base branch that is also on the PR branch, but in the fast-forward case that is the PR's only commit. Assuming the head commit is also the merge base results in the import of a PR with 0 commits and no diff. This PR uses the individual merge request endpoint to fetch merge request data with the diff_refs field. With its data, the base merge commit can be properly set, which—by not relying on the detection mentioned above—correctly imports PRs that were "merged" by fast-forwarding the base branch. ref: https://gitlab.com/gitlab-org/gitlab/-/issues/29620 --- services/migrations/gitlab.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go index 53540899a..51dde8b67 100644 --- a/services/migrations/gitlab.go +++ b/services/migrations/gitlab.go @@ -528,11 +528,13 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque perPage = g.maxPerPage } + view := "simple" opt := &gitlab.ListProjectMergeRequestsOptions{ ListOptions: gitlab.ListOptions{ PerPage: perPage, Page: page, }, + View: &view, } allPRs := make([]*base.PullRequest, 0, perPage) @@ -541,7 +543,13 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque if err != nil { return nil, false, fmt.Errorf("error while listing merge requests: %w", err) } - for _, pr := range prs { + for _, simplePR := range prs { + // Load merge request again by itself, as not all fields are populated in the ListProjectMergeRequests endpoint. + // See https://gitlab.com/gitlab-org/gitlab/-/issues/29620 + pr, _, err := g.client.MergeRequests.GetMergeRequest(g.repoID, simplePR.IID, nil) + if err != nil { + return nil, false, fmt.Errorf("error while loading merge request: %w", err) + } labels := make([]*base.Label, 0, len(pr.Labels)) for _, l := range pr.Labels {