From 571f1dda17203d162dac65270a6b68366de1f101 Mon Sep 17 00:00:00 2001 From: "Jacob Vosmaer (GitLab)" Date: Wed, 22 Nov 2017 10:19:42 +0000 Subject: Add FetchSourceBranch Gitaly call --- lib/gitlab/git/repository.rb | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'lib/gitlab/git') diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index 3cb9b254e6e..dcca20c75ef 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -1058,12 +1058,11 @@ module Gitlab end def fetch_source_branch!(source_repository, source_branch, local_ref) - with_repo_branch_commit(source_repository, source_branch) do |commit| - if commit - write_ref(local_ref, commit.sha) - true + Gitlab::GitalyClient.migrate(:fetch_source_branch) do |is_enabled| + if is_enabled + gitaly_repository_client.fetch_source_branch(source_repository, source_branch, local_ref) else - false + rugged_fetch_source_branch(source_repository, source_branch, local_ref) end end end @@ -1216,6 +1215,17 @@ module Gitlab private + def rugged_fetch_source_branch(source_repository, source_branch, local_ref) + with_repo_branch_commit(source_repository, source_branch) do |commit| + if commit + write_ref(local_ref, commit.sha) + true + else + false + end + end + end + # Gitaly note: JV: Trying to get rid of the 'filter' option so we can implement this with 'git'. def branches_filter(filter: nil, sort_by: nil) # n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/37464 -- cgit v1.2.1 From 7df1cb528e5d977f5f18b1c82433b3c76220d6db Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Sat, 18 Nov 2017 02:13:45 +0800 Subject: Move identical merged branch check to merged_branch_names --- lib/gitlab/git/repository.rb | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'lib/gitlab/git') diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index dcca20c75ef..ff408c0c4dd 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -1243,11 +1243,21 @@ module Gitlab sort_branches(branches, sort_by) end + # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/695 def git_merged_branch_names(branch_names = []) - lines = run_git(['branch', '--merged', root_ref] + branch_names) - .first.lines + root_sha = find_branch(root_ref).target - lines.map(&:strip) + git_arguments = + %W[branch --merged #{root_sha} + --format=%(refname:short)\ %(objectname)] + branch_names + + lines = run_git(git_arguments).first.lines + + lines.each_with_object([]) do |line, branches| + name, sha = line.strip.split(' ', 2) + + branches << name if sha != root_sha + end end def log_using_shell?(options) -- cgit v1.2.1 From 4cfcc97544c231c2baf8dc3ab232ed394355b62c Mon Sep 17 00:00:00 2001 From: "Jacob Vosmaer (GitLab)" Date: Thu, 23 Nov 2017 10:48:57 +0000 Subject: Fix encoding bugs in Gitlab::Git::User --- lib/gitlab/git/user.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'lib/gitlab/git') diff --git a/lib/gitlab/git/user.rb b/lib/gitlab/git/user.rb index e6b61417de1..e573cd0e143 100644 --- a/lib/gitlab/git/user.rb +++ b/lib/gitlab/git/user.rb @@ -8,7 +8,12 @@ module Gitlab end def self.from_gitaly(gitaly_user) - new(gitaly_user.gl_username, gitaly_user.name, gitaly_user.email, gitaly_user.gl_id) + new( + gitaly_user.gl_username, + Gitlab::EncodingHelper.encode!(gitaly_user.name), + Gitlab::EncodingHelper.encode!(gitaly_user.email), + gitaly_user.gl_id + ) end def initialize(username, name, email, gl_id) @@ -23,7 +28,7 @@ module Gitlab end def to_gitaly - Gitaly::User.new(gl_username: username, gl_id: gl_id, name: name, email: email) + Gitaly::User.new(gl_username: username, gl_id: gl_id, name: name.b, email: email.b) end end end -- cgit v1.2.1 From 0e6beaf50c9233ca03083691856dea2883f71773 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 15 Nov 2017 16:46:08 +0100 Subject: Clean up repository fetch and mirror methods --- lib/gitlab/git/repository.rb | 10 +++++--- lib/gitlab/git/repository_mirroring.rb | 46 ++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 23 deletions(-) (limited to 'lib/gitlab/git') diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index dcca20c75ef..69897bf1402 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -1150,10 +1150,12 @@ module Gitlab @has_visible_content = has_local_branches? end - def fetch(remote = 'origin') - args = %W(#{Gitlab.config.git.bin_path} fetch #{remote}) - - popen(args, @path).last.zero? + # Like all public `Gitlab::Git::Repository` methods, this method is part + # of `Repository`'s interface through `method_missing`. + # `Repository` has its own `fetch_remote` which uses `gitlab-shell` and + # takes some extra attributes, so we qualify this method name to prevent confusion. + def fetch_remote_without_shell(remote = 'origin') + run_git(['fetch', remote]).last.zero? end def blob_at(sha, path) diff --git a/lib/gitlab/git/repository_mirroring.rb b/lib/gitlab/git/repository_mirroring.rb index 4500482d68f..49e2b833fa7 100644 --- a/lib/gitlab/git/repository_mirroring.rb +++ b/lib/gitlab/git/repository_mirroring.rb @@ -1,24 +1,26 @@ module Gitlab module Git module RepositoryMirroring - IMPORT_HEAD_REFS = '+refs/heads/*:refs/heads/*'.freeze - IMPORT_TAG_REFS = '+refs/tags/*:refs/tags/*'.freeze - MIRROR_REMOTE = 'mirror'.freeze + FETCH_REFS = { + # `:all` is used to define repository as equivalent as "git clone --mirror" + all: '+refs/*:refs/*', + heads: '+refs/heads/*:refs/heads/*', + tags: '+refs/tags/*:refs/tags/*' + }.freeze RemoteError = Class.new(StandardError) - def set_remote_as_mirror(remote_name) - # This is used to define repository as equivalent as "git clone --mirror" - rugged.config["remote.#{remote_name}.fetch"] = 'refs/*:refs/*' - rugged.config["remote.#{remote_name}.mirror"] = true - rugged.config["remote.#{remote_name}.prune"] = true - end + def set_remote_as_mirror(remote_name, fetch_refs: :all) + Array(fetch_refs).each_with_index do |fetch_ref, i| + fetch_ref = FETCH_REFS[fetch_ref] || fetch_ref - def set_import_remote_as_mirror(remote_name) - # Add first fetch with Rugged so it does not create its own. - rugged.config["remote.#{remote_name}.fetch"] = IMPORT_HEAD_REFS - - add_remote_fetch_config(remote_name, IMPORT_TAG_REFS) + # Add first fetch with Rugged so it does not create its own. + if i == 0 + rugged.config["remote.#{remote_name}.fetch"] = fetch_ref + else + add_remote_fetch_config(remote_name, fetch_ref) + end + end rugged.config["remote.#{remote_name}.mirror"] = true rugged.config["remote.#{remote_name}.prune"] = true @@ -28,11 +30,17 @@ module Gitlab run_git(%W[config --add remote.#{remote_name}.fetch #{refspec}]) end - def fetch_mirror(url) - add_remote(MIRROR_REMOTE, url) - set_remote_as_mirror(MIRROR_REMOTE) - fetch(MIRROR_REMOTE) - remove_remote(MIRROR_REMOTE) + # Like all public `Gitlab::Git::Repository` methods, this method is part + # of `Repository`'s interface through `method_missing`. + # `Repository` has its own `fetch_as_mirror` which uses `gitlab-shell` and + # takes some extra attributes, so we qualify this method name to prevent confusion. + def fetch_as_mirror_without_shell(url) + remote_name = "tmp-#{SecureRandom.hex}" + add_remote(remote_name, url) + set_remote_as_mirror(remote_name) + fetch_remote_without_shell(remote_name) + ensure + remove_remote(remote_name) if remote_name end def remote_tags(remote) -- cgit v1.2.1 From 7a1e93d35b7280db8bc4128862c86223d76a8d6d Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 23 Nov 2017 16:51:55 +0100 Subject: Rename fetch_refs to refmap --- lib/gitlab/git/repository_mirroring.rb | 35 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'lib/gitlab/git') diff --git a/lib/gitlab/git/repository_mirroring.rb b/lib/gitlab/git/repository_mirroring.rb index 49e2b833fa7..392bef69e80 100644 --- a/lib/gitlab/git/repository_mirroring.rb +++ b/lib/gitlab/git/repository_mirroring.rb @@ -1,36 +1,37 @@ module Gitlab module Git module RepositoryMirroring - FETCH_REFS = { - # `:all` is used to define repository as equivalent as "git clone --mirror" - all: '+refs/*:refs/*', + REFMAPS = { + # With `:all_refs`, the repository is equivalent to the result of `git clone --mirror` + all_refs: '+refs/*:refs/*', heads: '+refs/heads/*:refs/heads/*', tags: '+refs/tags/*:refs/tags/*' }.freeze RemoteError = Class.new(StandardError) - def set_remote_as_mirror(remote_name, fetch_refs: :all) - Array(fetch_refs).each_with_index do |fetch_ref, i| - fetch_ref = FETCH_REFS[fetch_ref] || fetch_ref - - # Add first fetch with Rugged so it does not create its own. - if i == 0 - rugged.config["remote.#{remote_name}.fetch"] = fetch_ref - else - add_remote_fetch_config(remote_name, fetch_ref) - end - end + def set_remote_as_mirror(remote_name, refmap: :all_refs) + set_remote_refmap(remote_name, refmap) rugged.config["remote.#{remote_name}.mirror"] = true rugged.config["remote.#{remote_name}.prune"] = true end - def add_remote_fetch_config(remote_name, refspec) - run_git(%W[config --add remote.#{remote_name}.fetch #{refspec}]) + def set_remote_refmap(remote_name, refmap) + Array(refmap).each_with_index do |refspec, i| + refspec = REFMAPS[refspec] || refspec + + # We need multiple `fetch` entries, but Rugged only allows replacing a config, not adding to it. + # To make sure we start from scratch, we set the first using rugged, and use `git` for any others + if i == 0 + rugged.config["remote.#{remote_name}.fetch"] = refspec + else + run_git(%W[config --add remote.#{remote_name}.fetch #{refspec}]) + end + end end - # Like all public `Gitlab::Git::Repository` methods, this method is part + # Like all_refs public `Gitlab::Git::Repository` methods, this method is part # of `Repository`'s interface through `method_missing`. # `Repository` has its own `fetch_as_mirror` which uses `gitlab-shell` and # takes some extra attributes, so we qualify this method name to prevent confusion. -- cgit v1.2.1 From 3c6a4d63636ba41dad0ce63cf536761fc3b5ef64 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Fri, 24 Nov 2017 11:58:05 +0000 Subject: Ensure MRs always use branch refs for comparison If a merge request was created with a branch name that also matched a tag name, we'd generate a comparison to or from the tag respectively, rather than the branch. Merging would still use the branch, of course. To avoid this, ensure that when we get the branch heads, we prepend the reference prefix for branches, which will ensure that we generate the correct comparison. --- lib/gitlab/git/repository.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/gitlab/git') diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index a6e7c410bdd..d399636bb28 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -1046,9 +1046,15 @@ module Gitlab end def with_repo_tmp_commit(start_repository, start_branch_name, sha) + source_ref = start_branch_name + + unless Gitlab::Git.branch_ref?(source_ref) + source_ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}#{source_ref}" + end + tmp_ref = fetch_ref( start_repository, - source_ref: "#{Gitlab::Git::BRANCH_REF_PREFIX}#{start_branch_name}", + source_ref: source_ref, target_ref: "refs/tmp/#{SecureRandom.hex}" ) -- cgit v1.2.1