Skip to content

Commit dd5a24d

Browse files
authored
Add --filter to Git.clone for partial clones (#663)
Add in support for git clone --filter option so you can do partial clones with. For example, Git.clone(..., filter: 'tree:0') would result in git clone ... --filter tree:0 Signed-off-by: Andy Meneely <andy.meneely@gmail.com>
1 parent cfcf40f commit dd5a24d

File tree

4 files changed

+33
-0
lines changed

4 files changed

+33
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ g.dir #=> /tmp/clone/ruby-git-clean
236236
g.config('user.name', 'Scott Chacon')
237237
g.config('user.email', 'email@email.com')
238238

239+
# Clone can take a filter to tell the serve to send a partial clone
240+
g = Git.clone(git_url, name, :path => path, :filter => 'tree:0')
241+
239242
# Clone can take an optional logger
240243
logger = Logger.new
241244
g = Git.clone(git_url, NAME, :log => logger)

lib/git.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ def self.bare(git_dir, options = {})
139139
# @option options [Integer] :depth Create a shallow clone with a history
140140
# truncated to the specified number of commits.
141141
#
142+
# @option options [String] :filter Request that the server send a partial
143+
# clone according to the given filter
144+
#
142145
# @option options [Logger] :log A logger to use for Git operations. Git
143146
# commands are logged at the `:info` level. Additional logging is done
144147
# at the `:debug` level.

lib/git/lib.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ def init(opts={})
8484
# :bare:: no working directory
8585
# :branch:: name of branch to track (rather than 'master')
8686
# :depth:: the number of commits back to pull
87+
# :filter:: specify partial clone
8788
# :origin:: name of remote (same as remote)
8889
# :path:: directory where the repo will be cloned
8990
# :remote:: name of remote (rather than 'origin')
@@ -101,6 +102,7 @@ def clone(repository_url, directory, opts = {})
101102
arr_opts << '--bare' if opts[:bare]
102103
arr_opts << '--branch' << opts[:branch] if opts[:branch]
103104
arr_opts << '--depth' << opts[:depth].to_i if opts[:depth] && opts[:depth].to_i > 0
105+
arr_opts << '--filter' << opts[:filter] if opts[:filter]
104106
Array(opts[:config]).each { |c| arr_opts << '--config' << c }
105107
arr_opts << '--origin' << opts[:remote] || opts[:origin] if opts[:remote] || opts[:origin]
106108
arr_opts << '--recursive' if opts[:recursive]

tests/units/test_git_clone.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,29 @@ def test_git_clone_with_no_name
8383
assert_equal(expected_command_line, actual_command_line)
8484
end
8585

86+
test 'clone with a filter' do
87+
repository_url = 'https://github.com/ruby-git/ruby-git.git'
88+
destination = 'ruby-git'
89+
90+
actual_command_line = nil
91+
92+
in_temp_dir do |path|
93+
git = Git.init('.')
94+
95+
# Mock the Git::Lib#command method to capture the actual command line args
96+
git.lib.define_singleton_method(:command) do |cmd, *opts, &block|
97+
actual_command_line = [cmd, *opts.flatten]
98+
end
99+
100+
git.lib.clone(repository_url, destination, filter: 'tree:0')
101+
end
102+
103+
expected_command_line = [
104+
'clone',
105+
'--filter', 'tree:0',
106+
'--', repository_url, destination
107+
]
108+
109+
assert_equal(expected_command_line, actual_command_line)
110+
end
86111
end

0 commit comments

Comments
 (0)