Skip to content
Snippets Groups Projects
Commit 3f05c22f authored by Douwe Maan's avatar Douwe Maan
Browse files

Merge branch 'rs-git-bin-path' into 'master'

Replace all usages of `git` command with configurable binary path

Closes #3311

See merge request !1742
parents 82aa5419 d09d62b6
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -89,7 +89,7 @@ class Repository
 
def find_commits_by_message(query)
# Limited to 1000 commits for now, could be parameterized?
args = %W(git log --pretty=%H --max-count 1000 --grep=#{query})
args = %W(#{Gitlab.config.git.bin_path} log --pretty=%H --max-count 1000 --grep=#{query})
 
git_log_results = Gitlab::Popen.popen(args, path_to_repo).first.lines.map(&:chomp)
commits = git_log_results.map { |c| commit(c) }
Loading
Loading
@@ -296,7 +296,7 @@ class Repository
end
 
def last_commit_for_path(sha, path)
args = %W(git rev-list --max-count=1 #{sha} -- #{path})
args = %W(#{Gitlab.config.git.bin_path} rev-list --max-count=1 #{sha} -- #{path})
sha = Gitlab::Popen.popen(args, path_to_repo).first.strip
commit(sha)
end
Loading
Loading
@@ -347,7 +347,7 @@ class Repository
end
 
def branch_names_contains(sha)
args = %W(git branch --contains #{sha})
args = %W(#{Gitlab.config.git.bin_path} branch --contains #{sha})
names = Gitlab::Popen.popen(args, path_to_repo).first
 
if names.respond_to?(:split)
Loading
Loading
@@ -364,7 +364,7 @@ class Repository
end
 
def tag_names_contains(sha)
args = %W(git tag --contains #{sha})
args = %W(#{Gitlab.config.git.bin_path} tag --contains #{sha})
names = Gitlab::Popen.popen(args, path_to_repo).first
 
if names.respond_to?(:split)
Loading
Loading
@@ -505,7 +505,7 @@ class Repository
 
def search_files(query, ref)
offset = 2
args = %W(git grep -i -n --before-context #{offset} --after-context #{offset} -e #{query} #{ref || root_ref})
args = %W(#{Gitlab.config.git.bin_path} grep -i -n --before-context #{offset} --after-context #{offset} -e #{query} #{ref || root_ref})
Gitlab::Popen.popen(args, path_to_repo).first.scrub.split(/^--$/)
end
 
Loading
Loading
@@ -537,7 +537,7 @@ class Repository
end
 
def fetch_ref(source_path, source_ref, target_ref)
args = %W(git fetch -f #{source_path} #{source_ref}:#{target_ref})
args = %W(#{Gitlab.config.git.bin_path} fetch -f #{source_path} #{source_ref}:#{target_ref})
Gitlab::Popen.popen(args, path_to_repo)
end
 
Loading
Loading
module Gitlab
VERSION = File.read(Rails.root.join("VERSION")).strip
REVISION = Gitlab::Popen.popen(%W(git log --pretty=format:%h -n 1)).first.chomp
def self.config
Settings
end
VERSION = File.read(Rails.root.join("VERSION")).strip
REVISION = Gitlab::Popen.popen(%W(#{config.git.bin_path} log --pretty=format:%h -n 1)).first.chomp
end
Loading
Loading
@@ -35,6 +35,16 @@ Gitlab::Popen.popen(%W(find /some/path -not -path /some/path -mmin +120 -delete)
 
This coding style could have prevented CVE-2013-4490.
 
## Always use the configurable git binary path for git commands
```ruby
# Wrong
system(*%W(git branch -d -- #{branch_name}))
# Correct
system(*%W(#{Gitlab.config.git.bin_path} branch -d -- #{branch_name}))
```
## Bypass the shell by splitting commands into separate tokens
 
When we pass shell commands as a single string to Ruby, Ruby will let `/bin/sh` evaluate the entire string. Essentially, we are asking the shell to evaluate a one-line script. This creates a risk for shell injection attacks. It is better to split the shell command into tokens ourselves. Sometimes we use the scripting capabilities of the shell to change the working directory or set environment variables. All of this can also be achieved securely straight from Ruby
Loading
Loading
@@ -81,9 +91,9 @@ In the GitLab codebase, we avoid the option/argument ambiguity by _always_ using
 
```ruby
# Wrong
system(*%W(git branch -d #{branch_name}))
system(*%W(#{Gitlab.config.git.bin_path} branch -d #{branch_name}))
# Correct
system(*%W(git branch -d -- #{branch_name}))
system(*%W(#{Gitlab.config.git.bin_path} branch -d -- #{branch_name}))
```
 
This coding style could have prevented CVE-2013-4582.
Loading
Loading
@@ -94,9 +104,9 @@ Capturing the output of shell commands with backticks reads nicely, but you are
 
```ruby
# Wrong
logs = `cd #{repo_dir} && git log`
logs = `cd #{repo_dir} && #{Gitlab.config.git.bin_path} log`
# Correct
logs, exit_status = Gitlab::Popen.popen(%W(git log), repo_dir)
logs, exit_status = Gitlab::Popen.popen(%W(#{Gitlab.config.git.bin_path} log), repo_dir)
 
# Wrong
user = `whoami`
Loading
Loading
@@ -108,7 +118,7 @@ In other repositories, such as gitlab-shell you can also use `IO.popen`.
 
```ruby
# Safe IO.popen example
logs = IO.popen(%W(git log), chdir: repo_dir) { |p| p.read }
logs = IO.popen(%W(#{Gitlab.config.git.bin_path} log), chdir: repo_dir) { |p| p.read }
```
 
Note that unlike `Gitlab::Popen.popen`, `IO.popen` does not capture standard error.
Loading
Loading
Loading
Loading
@@ -35,7 +35,7 @@ module Backup
if wiki.repository.empty?
$progress.puts " [SKIPPED]".cyan
else
cmd = %W(git --git-dir=#{path_to_repo(wiki)} bundle create #{path_to_bundle(wiki)} --all)
cmd = %W(#{Gitlab.config.git.bin_path} --git-dir=#{path_to_repo(wiki)} bundle create #{path_to_bundle(wiki)} --all)
output, status = Gitlab::Popen.popen(cmd)
if status.zero?
$progress.puts " [DONE]".green
Loading
Loading
@@ -67,7 +67,7 @@ module Backup
FileUtils.mkdir_p(path_to_repo(project))
cmd = %W(tar -xf #{path_to_bundle(project)} -C #{path_to_repo(project)})
else
cmd = %W(git init --bare #{path_to_repo(project)})
cmd = %W(#{Gitlab.config.git.bin_path} init --bare #{path_to_repo(project)})
end
 
if system(*cmd, silent)
Loading
Loading
@@ -87,7 +87,7 @@ module Backup
# that was initialized with ProjectWiki.new() and then
# try to restore with 'git clone --bare'.
FileUtils.rm_rf(path_to_repo(wiki))
cmd = %W(git clone --bare #{path_to_bundle(wiki)} #{path_to_repo(wiki)})
cmd = %W(#{Gitlab.config.git.bin_path} clone --bare #{path_to_bundle(wiki)} #{path_to_repo(wiki)})
 
if system(*cmd, silent)
$progress.puts " [DONE]".green
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@ module Gitlab
if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev)
false
else
missed_refs, _ = Gitlab::Popen.popen(%W(git --git-dir=#{project.repository.path_to_repo} rev-list #{oldrev} ^#{newrev}))
missed_refs, _ = Gitlab::Popen.popen(%W(#{Gitlab.config.git.bin_path} --git-dir=#{project.repository.path_to_repo} rev-list #{oldrev} ^#{newrev}))
missed_refs.split("\n").size > 0
end
end
Loading
Loading
Loading
Loading
@@ -6,7 +6,7 @@ module Gitlab
# Returns true for a valid reference name, false otherwise
def validate(ref_name)
Gitlab::Utils.system_silent(
%W(git check-ref-format refs/#{ref_name}))
%W(#{Gitlab.config.git.bin_path} check-ref-format refs/#{ref_name}))
end
end
end
Loading
Loading
@@ -50,15 +50,15 @@ module Gitlab
end
 
def fetch_git_tags
remote_tags, _ = Gitlab::Popen.popen(%W(git ls-remote --tags https://gitlab.com/gitlab-org/gitlab-ce.git))
remote_tags, _ = Gitlab::Popen.popen(%W(#{Gitlab.config.git.bin_path} ls-remote --tags https://gitlab.com/gitlab-org/gitlab-ce.git))
remote_tags.split("\n").grep(/tags\/v#{current_version.major}/)
end
 
def update_commands
{
"Stash changed files" => %W(git stash),
"Get latest code" => %W(git fetch),
"Switch to new version" => %W(git checkout v#{latest_version}),
"Stash changed files" => %W(#{Gitlab.config.git.bin_path} stash),
"Get latest code" => %W(#{Gitlab.config.git.bin_path} fetch),
"Switch to new version" => %W(#{Gitlab.config.git.bin_path} checkout v#{latest_version}),
"Install gems" => %W(bundle),
"Migrate DB" => %W(bundle exec rake db:migrate),
"Recompile assets" => %W(bundle exec rake assets:clean assets:precompile),
Loading
Loading
Loading
Loading
@@ -824,7 +824,7 @@ namespace :gitlab do
repo_dirs = Dir.glob(File.join(namespace_dir, '*'))
repo_dirs.each do |dir|
puts "\nChecking repo at #{dir}"
system(*%w(git fsck), chdir: dir)
system(*%W(#{Gitlab.config.git.bin_path} fsck), chdir: dir)
end
end
end
Loading
Loading
Loading
Loading
@@ -17,7 +17,7 @@ namespace :gitlab do
 
# Clone if needed
unless File.directory?(target_dir)
system(*%W(git clone -- #{args.repo} #{target_dir}))
system(*%W(#{Gitlab.config.git.bin_path} clone -- #{args.repo} #{target_dir}))
end
 
# Make sure we're on the right tag
Loading
Loading
@@ -27,7 +27,7 @@ namespace :gitlab do
reseted = reset_to_commit(args)
 
unless reseted
system(*%W(git fetch origin))
system(*%W(#{Gitlab.config.git.bin_path} fetch origin))
reset_to_commit(args)
end
 
Loading
Loading
@@ -128,14 +128,14 @@ namespace :gitlab do
end
 
def reset_to_commit(args)
tag, status = Gitlab::Popen.popen(%W(git describe -- #{args.tag}))
tag, status = Gitlab::Popen.popen(%W(#{Gitlab.config.git.bin_path} describe -- #{args.tag}))
 
unless status.zero?
tag, status = Gitlab::Popen.popen(%W(git describe -- origin/#{args.tag}))
tag, status = Gitlab::Popen.popen(%W(#{Gitlab.config.git.bin_path} describe -- origin/#{args.tag}))
end
 
tag = tag.strip
system(*%W(git reset --hard #{tag}))
system(*%W(#{Gitlab.config.git.bin_path} reset --hard #{tag}))
end
end
 
Loading
Loading
@@ -223,7 +223,7 @@ describe ProjectWiki do
 
def create_temp_repo(path)
FileUtils.mkdir_p path
system(*%W(git init --quiet --bare -- #{path}))
system(*%W(#{Gitlab.config.git.bin_path} init --quiet --bare -- #{path}))
end
 
def remove_temp_repo(path)
Loading
Loading
Loading
Loading
@@ -36,8 +36,8 @@ describe API::API, api: true do
it 'should create a new annotated tag' do
# Identity must be set in .gitconfig to create annotated tag.
repo_path = project.repository.path_to_repo
system(*%W(git --git-dir=#{repo_path} config user.name #{user.name}))
system(*%W(git --git-dir=#{repo_path} config user.email #{user.email}))
system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.name #{user.name}))
system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.email #{user.email}))
 
post api("/projects/#{project.id}/repository/tags", user),
tag_name: 'v7.1.0',
Loading
Loading
Loading
Loading
@@ -96,15 +96,15 @@ module TestEnv
clone_url = "https://gitlab.com/gitlab-org/#{repo_name}.git"
 
unless File.directory?(repo_path)
system(*%W(git clone -q #{clone_url} #{repo_path}))
system(*%W(#{Gitlab.config.git.bin_path} clone -q #{clone_url} #{repo_path}))
end
 
Dir.chdir(repo_path) do
branch_sha.each do |branch, sha|
# Try to reset without fetching to avoid using the network.
reset = %W(git update-ref refs/heads/#{branch} #{sha})
reset = %W(#{Gitlab.config.git.bin_path} update-ref refs/heads/#{branch} #{sha})
unless system(*reset)
if system(*%w(git fetch origin))
if system(*%W(#{Gitlab.config.git.bin_path} fetch origin))
unless system(*reset)
raise 'The fetched test seed '\
'does not contain the required revision.'
Loading
Loading
@@ -117,7 +117,7 @@ module TestEnv
end
 
# We must copy bare repositories because we will push to them.
system(git_env, *%W(git clone -q --bare #{repo_path} #{repo_path_bare}))
system(git_env, *%W(#{Gitlab.config.git.bin_path} clone -q --bare #{repo_path} #{repo_path_bare}))
end
 
def copy_repo(project)
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment