Skip to content

Add --filter to Git.clone for partial clones #663

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ g.dir #=> /tmp/clone/ruby-git-clean
g.config('user.name', 'Scott Chacon')
g.config('user.email', 'email@email.com')

# Clone can take a filter to tell the serve to send a partial clone
g = Git.clone(git_url, name, :path => path, :filter => 'tree:0')

# Clone can take an optional logger
logger = Logger.new
g = Git.clone(git_url, NAME, :log => logger)
Expand Down
3 changes: 3 additions & 0 deletions lib/git.rb
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ def self.bare(git_dir, options = {})
# @option options [Integer] :depth Create a shallow clone with a history
# truncated to the specified number of commits.
#
# @option options [String] :filter Request that the server send a partial
# clone according to the given filter
#
# @option options [Logger] :log A logger to use for Git operations. Git
# commands are logged at the `:info` level. Additional logging is done
# at the `:debug` level.
Expand Down
2 changes: 2 additions & 0 deletions lib/git/lib.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def init(opts={})
# :bare:: no working directory
# :branch:: name of branch to track (rather than 'master')
# :depth:: the number of commits back to pull
# :filter:: specify partial clone
# :origin:: name of remote (same as remote)
# :path:: directory where the repo will be cloned
# :remote:: name of remote (rather than 'origin')
Expand All @@ -101,6 +102,7 @@ def clone(repository_url, directory, opts = {})
arr_opts << '--bare' if opts[:bare]
arr_opts << '--branch' << opts[:branch] if opts[:branch]
arr_opts << '--depth' << opts[:depth].to_i if opts[:depth] && opts[:depth].to_i > 0
arr_opts << '--filter' << opts[:filter] if opts[:filter]
Array(opts[:config]).each { |c| arr_opts << '--config' << c }
arr_opts << '--origin' << opts[:remote] || opts[:origin] if opts[:remote] || opts[:origin]
arr_opts << '--recursive' if opts[:recursive]
Expand Down
25 changes: 25 additions & 0 deletions tests/units/test_git_clone.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,29 @@ def test_git_clone_with_no_name
assert_equal(expected_command_line, actual_command_line)
end

test 'clone with a filter' do
repository_url = 'https://github.com/ruby-git/ruby-git.git'
destination = 'ruby-git'

actual_command_line = nil

in_temp_dir do |path|
git = Git.init('.')

# Mock the Git::Lib#command method to capture the actual command line args
git.lib.define_singleton_method(:command) do |cmd, *opts, &block|
actual_command_line = [cmd, *opts.flatten]
end

git.lib.clone(repository_url, destination, filter: 'tree:0')
end

expected_command_line = [
'clone',
'--filter', 'tree:0',
'--', repository_url, destination
]

assert_equal(expected_command_line, actual_command_line)
end
end