Skip to content

Commit 6f2b3fd

Browse files
authored
Support the --all option for git fetch (#583)
Signed-off-by: James Couball <jcouball@yahoo.com>
1 parent 1b13ec1 commit 6f2b3fd

File tree

5 files changed

+101
-6
lines changed

5 files changed

+101
-6
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ g.remote(name).merge(branch)
288288
g.fetch
289289
g.fetch(g.remotes.first)
290290
g.fetch('origin', {:ref => 'some/ref/head'} )
291+
g.fetch(all: true, force: true, depth: 2)
291292

292293
g.pull
293294
g.pull(Git::Repo, Git::Branch) # fetch and a merge

lib/git/base.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,11 @@ def checkout_file(version, file)
336336

337337
# fetches changes from a remote branch - this does not modify the working directory,
338338
# it just gets the changes from the remote if there are any
339-
def fetch(remote = 'origin', opts={})
339+
def fetch(remote = 'origin', opts = {})
340+
if remote.is_a?(Hash)
341+
opts = remote
342+
remote = nil
343+
end
340344
self.lib.fetch(remote, opts)
341345
end
342346

lib/git/lib.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,14 +877,15 @@ def tag(name, *opts)
877877

878878
def fetch(remote, opts)
879879
arr_opts = []
880+
arr_opts << '--all' if opts[:all]
880881
arr_opts << '--tags' if opts[:t] || opts[:tags]
881882
arr_opts << '--prune' if opts[:p] || opts[:prune]
882883
arr_opts << '--prune-tags' if opts[:P] || opts[:'prune-tags']
883884
arr_opts << '--force' if opts[:f] || opts[:force]
884885
arr_opts << '--unshallow' if opts[:unshallow]
885886
arr_opts << '--depth' << opts[:depth] if opts[:depth]
886-
arr_opts << '--'
887-
arr_opts << remote
887+
arr_opts << '--' if remote || opts[:ref]
888+
arr_opts << remote if remote
888889
arr_opts << opts[:ref] if opts[:ref]
889890

890891
command('fetch', arr_opts)

tests/test_helper.rb

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,67 @@ def with_custom_env_variables(&block)
9797
Git::Lib::ENV_VARIABLE_NAMES.each { |k| ENV[k] = saved_env[k] }
9898
end
9999
end
100+
101+
# Assert that the expected command line args are generated for a given Git::Lib method
102+
#
103+
# This assertion generates an empty git repository and then runs calls
104+
# Git::Base method named by `git_cmd` passing that method `git_cmd_args`.
105+
#
106+
# Before calling `git_cmd`, this method stubs the `Git::Lib#command` method to
107+
# capture the args sent to it by `git_cmd`. These args are captured into
108+
# `actual_command_line`.
109+
#
110+
# assert_equal is called comparing the given `expected_command_line` to
111+
# `actual_command_line`.
112+
#
113+
# @example Fetch with no args
114+
# expected_command_line = ['fetch', '--', 'origin']
115+
# git_cmd = :fetch
116+
# git_cmd_args = []
117+
# assert_command_line(expected_command_line, git_cmd, git_cmd_args)
118+
#
119+
# @example Fetch with some args
120+
# expected_command_line = ['fetch', '--depth', '2', '--', 'origin', 'master']
121+
# git_cmd = :fetch
122+
# git_cmd_args = ['origin', ref: 'master', depth: '2']
123+
# assert_command_line(expected_command_line, git_cmd, git_cmd_args)
124+
#
125+
# @example Fetch all
126+
# expected_command_line = ['fetch', '--all']
127+
# git_cmd = :fetch
128+
# git_cmd_args = [all: true]
129+
# assert_command_line(expected_command_line, git_cmd, git_cmd_args)
130+
#
131+
# @param expected_command_line [Array<String>] The expected arguments to be sent to Git::Lib#command
132+
# @param git_cmd [Symbol] the method to be called on the Git::Base object
133+
# @param git_cmd_args [Array<Object>] The arguments to be sent to the git_cmd method
134+
#
135+
# @yield [git] An initialization block
136+
# The initialization block is called after a test project is created with Git.init.
137+
# The current working directory is set to the root of the test project's working tree.
138+
# @yieldparam git [Git::Base] The Git::Base object resulting from initializing the test project
139+
# @yieldreturn [void] the return value of the block is ignored
140+
#
141+
# @return [void]
142+
#
143+
def assert_command_line(expected_command_line, git_cmd, git_cmd_args)
144+
actual_command_line = nil
145+
146+
in_temp_dir do |path|
147+
git = Git.init('test_project')
148+
149+
Dir.chdir 'test_project' do
150+
yield(git) if block_given?
151+
152+
# Mock the Git::Lib#command method to capture the actual command line args
153+
git.lib.define_singleton_method(:command) do |cmd, *opts, &block|
154+
actual_command_line = [cmd, *opts.flatten]
155+
end
156+
157+
git.send(git_cmd, *git_cmd_args)
158+
end
159+
end
160+
161+
assert_equal(expected_command_line, actual_command_line)
162+
end
100163
end

tests/units/test_remotes.rb

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env ruby
22

3-
require File.dirname(__FILE__) + '/../test_helper'
3+
require_relative '../test_helper'
44

55
class TestRemotes < Test::Unit::TestCase
66
def setup
@@ -123,6 +123,34 @@ def test_fetch
123123
end
124124
end
125125

126+
def test_fetch_cmd_with_no_args
127+
expected_command_line = ['fetch', '--', 'origin']
128+
git_cmd = :fetch
129+
git_cmd_args = []
130+
assert_command_line(expected_command_line, git_cmd, git_cmd_args)
131+
end
132+
133+
def test_fetch_cmd_with_origin_and_branch
134+
expected_command_line = ['fetch', '--depth', '2', '--', 'origin', 'master']
135+
git_cmd = :fetch
136+
git_cmd_args = ['origin', ref: 'master', depth: '2']
137+
assert_command_line(expected_command_line, git_cmd, git_cmd_args)
138+
end
139+
140+
def test_fetch_cmd_with_all
141+
expected_command_line = ['fetch', '--all']
142+
git_cmd = :fetch
143+
git_cmd_args = [all: true]
144+
assert_command_line(expected_command_line, git_cmd, git_cmd_args)
145+
end
146+
147+
def test_fetch_cmd_with_all_with_other_args
148+
expected_command_line = ['fetch', '--all', '--force', '--depth', '2']
149+
git_cmd = :fetch
150+
git_cmd_args = [all: true, force: true, depth: '2']
151+
assert_command_line(expected_command_line, git_cmd, git_cmd_args)
152+
end
153+
126154
def test_fetch_command_injection
127155
test_file = 'VULNERABILITY_EXISTS'
128156
vulnerability_exists = false
@@ -208,6 +236,4 @@ def test_push
208236
assert(rem.tag('test-tag'))
209237
end
210238
end
211-
212-
213239
end

0 commit comments

Comments
 (0)