summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStan Hu <stanhu@gmail.com>2019-02-09 04:28:23 -0800
committerStan Hu <stanhu@gmail.com>2019-02-09 04:56:50 -0800
commit36a778326cf8bda454b73f67feb5684663a224cd (patch)
tree10b6faa204f61eada6e988ed0accd9083b9b0709
parent5b23f2b016f4e5d33387d7474148d2a59b213ee6 (diff)
downloadgitlab-ce-sh-import-source-branch-github-forks.tar.gz
Create the source branch for a GitHub importsh-import-source-branch-github-forks
When the GitHub importer creates a merge request, it retrieves the SHA but does not actually create the source branch. This makes it impossible to merge an open merge request, particularly if the source branch were from a forked project. In that case, the branch will never exist because the original `project-name:source-branch` name is never created, nor is it a valid branch name. To prevent possible branch name conflicts, forked source branches are now renamed `github/fork/project-name/source-branch` and created when necessary. Note that we only create the source branch if the merge request is open. For projects that have many merge requests, the project would end up with a lot of possibly dead branches. Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/57370
-rw-r--r--changelogs/unreleased/sh-import-source-branch-github-forks.yml5
-rw-r--r--lib/gitlab/github_import/importer/pull_request_importer.rb23
-rw-r--r--lib/gitlab/github_import/representation/pull_request.rb4
-rw-r--r--spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb24
-rw-r--r--spec/lib/gitlab/github_import/representation/pull_request_spec.rb2
5 files changed, 53 insertions, 5 deletions
diff --git a/changelogs/unreleased/sh-import-source-branch-github-forks.yml b/changelogs/unreleased/sh-import-source-branch-github-forks.yml
new file mode 100644
index 00000000000..b5ea60202c0
--- /dev/null
+++ b/changelogs/unreleased/sh-import-source-branch-github-forks.yml
@@ -0,0 +1,5 @@
+---
+title: Create the source branch for a GitHub import
+merge_request: 25064
+author:
+type: fixed
diff --git a/lib/gitlab/github_import/importer/pull_request_importer.rb b/lib/gitlab/github_import/importer/pull_request_importer.rb
index ae7c4cf1b38..79222a40b6d 100644
--- a/lib/gitlab/github_import/importer/pull_request_importer.rb
+++ b/lib/gitlab/github_import/importer/pull_request_importer.rb
@@ -67,6 +67,29 @@ module Gitlab
def insert_git_data(merge_request, already_exists)
insert_or_replace_git_data(merge_request, pull_request.source_branch_sha, pull_request.target_branch_sha, already_exists)
+ # We need to create the branch after the merge request is
+ # populated to ensure the merge request is in the right state
+ # when the branch is created.
+ create_source_branch_if_not_exists(merge_request)
+ end
+
+ # An imported merge request will not be mergeable unless the
+ # source branch exists. For pull requests from forks, the source
+ # branch will be in the form of
+ # "github/fork/{project-name}/{source_branch}". This branch will never
+ # exist, so we create it here.
+ #
+ # Note that we only create the branch if the merge request is still open.
+ # For projects that have many pull requests, we assume that if it's closed
+ # the branch has already been deleted.
+ def create_source_branch_if_not_exists(merge_request)
+ return unless merge_request.open?
+
+ source_branch = pull_request.formatted_source_branch
+
+ return if project.repository.branch_exists?(source_branch)
+
+ project.repository.add_branch(merge_request.author, source_branch, pull_request.source_branch_sha)
end
end
end
diff --git a/lib/gitlab/github_import/representation/pull_request.rb b/lib/gitlab/github_import/representation/pull_request.rb
index 593b491a837..0ccc4bfaed3 100644
--- a/lib/gitlab/github_import/representation/pull_request.rb
+++ b/lib/gitlab/github_import/representation/pull_request.rb
@@ -76,10 +76,10 @@ module Gitlab
# Returns a formatted source branch.
#
# For cross-project pull requests the branch name will be in the format
- # `owner-name:branch-name`.
+ # `github/fork/owner-name/branch-name`.
def formatted_source_branch
if cross_project? && source_repository_owner
- "#{source_repository_owner}:#{source_branch}"
+ "github/fork/#{source_repository_owner}/#{source_branch}"
elsif source_branch == target_branch
# Sometimes the source and target branch are the same, but GitLab
# doesn't support this. This can happen when both the user and
diff --git a/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb b/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb
index 0f21b8843b6..8511d3e98c2 100644
--- a/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb
@@ -89,7 +89,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi
description: 'This is my pull request',
source_project_id: project.id,
target_project_id: project.id,
- source_branch: 'alice:feature',
+ source_branch: 'github/fork/alice/feature',
target_branch: 'master',
state: :merged,
milestone_id: milestone.id,
@@ -134,7 +134,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi
description: "*Created by: alice*\n\nThis is my pull request",
source_project_id: project.id,
target_project_id: project.id,
- source_branch: 'alice:feature',
+ source_branch: 'github/fork/alice/feature',
target_branch: 'master',
state: :merged,
milestone_id: milestone.id,
@@ -259,6 +259,26 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi
.and_return(user.id)
end
+ it 'does not create the source branch if merge request is merged' do
+ mr, exists = importer.create_merge_request
+
+ importer.insert_git_data(mr, exists)
+
+ expect(project.repository.branch_exists?(mr.source_branch)).to be_falsey
+ expect(project.repository.branch_exists?(mr.target_branch)).to be_truthy
+ end
+
+ it 'creates the source branch if merge request is open' do
+ mr, exists = importer.create_merge_request
+ mr.state = 'opened'
+ mr.save
+
+ importer.insert_git_data(mr, exists)
+
+ expect(project.repository.branch_exists?(mr.source_branch)).to be_truthy
+ expect(project.repository.branch_exists?(mr.target_branch)).to be_truthy
+ end
+
it 'creates the merge request diffs' do
mr, exists = importer.create_merge_request
diff --git a/spec/lib/gitlab/github_import/representation/pull_request_spec.rb b/spec/lib/gitlab/github_import/representation/pull_request_spec.rb
index 33f6ff0ae6a..d478e5ae899 100644
--- a/spec/lib/gitlab/github_import/representation/pull_request_spec.rb
+++ b/spec/lib/gitlab/github_import/representation/pull_request_spec.rb
@@ -238,7 +238,7 @@ describe Gitlab::GithubImport::Representation::PullRequest do
target_repository_id: 2
)
- expect(pr.formatted_source_branch).to eq('foo:branch')
+ expect(pr.formatted_source_branch).to eq('github/fork/foo/branch')
end
end