Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the directory param to Git.clone optional #578

Merged
merged 1 commit into from Apr 26, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 12 additions & 2 deletions README.md
Expand Up @@ -204,13 +204,23 @@ g = Git.init
{ :repository => '/opt/git/proj.git',
:index => '/tmp/index'} )

g = Git.clone(URI, NAME, :path => '/tmp/checkout')
# Clone from a git url
git_url = 'https://github.com/ruby-git/ruby-git.git'
# Clone into the ruby-git directory
g = Git.clone(git_url)

# Clone into /tmp/clone/ruby-git-clean
name = 'ruby-git-clean'
path = '/tmp/clone'
g = Git.clone(git_url, name, :path => path)
g.dir #=> /tmp/clone/ruby-git-clean

g.config('user.name', 'Scott Chacon')
g.config('user.email', 'email@email.com')

# Clone can take an optional logger
logger = Logger.new
g = Git.clone(URI, NAME, :log => logger)
g = Git.clone(git_url, NAME, :log => logger)

g.add # git add -- "."
g.add(:all=>true) # git add --all -- "."
Expand Down
22 changes: 18 additions & 4 deletions lib/git.rb
Expand Up @@ -107,11 +107,23 @@ def self.bare(git_dir, options = {})
# @see https://git-scm.com/docs/git-clone git clone
# @see https://git-scm.com/docs/git-clone#_git_urls_a_id_urls_a GIT URLs
#
# @param [URI, Pathname] repository The (possibly remote) repository to clone
# @param repository_url [URI, Pathname] The (possibly remote) repository url to clone
# from. See [GIT URLS](https://git-scm.com/docs/git-clone#_git_urls_a_id_urls_a)
# for more information.
#
# @param [Pathname] name The directory to clone into.
# @param directory [Pathname, nil] The directory to clone into
#
# If `directory` is a relative directory it is relative to the `path` option if
# given. If `path` is not given, `directory` is relative to the current working
# directory.
#
# If `nil`, `directory` will be set to the basename of the last component of
# the path from the `repository_url`. For example, for the URL:
# `https://github.com/org/repo.git`, `directory` will be set to `repo`.
#
# If the last component of the path is `.git`, the next-to-last component of
# the path is used. For example, for the URL `/Users/me/foo/.git`, `directory`
# will be set to `foo`.
#
# @param [Hash] options The options for this command (see list of valid
# options below)
Expand Down Expand Up @@ -158,8 +170,10 @@ def self.bare(git_dir, options = {})
# @return [Git::Base] an object that can execute git commands in the context
# of the cloned local working copy or cloned repository.
#
def self.clone(repository, name, options = {})
Base.clone(repository, name, options)
def self.clone(repository_url, directory = nil, options = {})
clone_to_options = options.select { |key, _value| %i[bare mirror].include?(key) }
directory ||= Git::URL.clone_to(repository_url, **clone_to_options)
Base.clone(repository_url, directory, options)
end

# Export the current HEAD (or a branch, if <tt>options[:branch]</tt>
Expand Down
6 changes: 3 additions & 3 deletions lib/git/base.rb
Expand Up @@ -17,10 +17,10 @@ def self.bare(git_dir, options = {})
end

# (see Git.clone)
def self.clone(repository, name, options = {})
new_options = Git::Lib.new(nil, options[:log]).clone(repository, name, options)
def self.clone(repository_url, directory, options = {})
new_options = Git::Lib.new(nil, options[:log]).clone(repository_url, directory, options)
normalize_paths(new_options, bare: options[:bare] || options[:mirror])
self.new(new_options)
new(new_options)
end

# Returns (and initialize if needed) a Git::Config instance
Expand Down
8 changes: 4 additions & 4 deletions lib/git/lib.rb
Expand Up @@ -95,9 +95,9 @@ def init(opts={})
#
# @return [Hash] the options to pass to {Git::Base.new}
#
def clone(repository, name, opts = {})
def clone(repository_url, directory, opts = {})
@path = opts[:path] || '.'
clone_dir = opts[:path] ? File.join(@path, name) : name
clone_dir = opts[:path] ? File.join(@path, directory) : directory

arr_opts = []
arr_opts << '--bare' if opts[:bare]
Expand All @@ -106,11 +106,11 @@ def clone(repository, name, opts = {})
arr_opts << '--config' << opts[:config] if opts[:config]
arr_opts << '--origin' << opts[:remote] || opts[:origin] if opts[:remote] || opts[:origin]
arr_opts << '--recursive' if opts[:recursive]
arr_opts << "--mirror" if opts[:mirror]
arr_opts << '--mirror' if opts[:mirror]

arr_opts << '--'

arr_opts << repository
arr_opts << repository_url
arr_opts << clone_dir

command('clone', arr_opts)
Expand Down
36 changes: 36 additions & 0 deletions tests/units/test_git_clone.rb
@@ -0,0 +1,36 @@
# frozen_string_literal: true

require 'test/unit'
require_relative '../test_helper'

# Tests for Git.clone
class TestGitClone < Test::Unit::TestCase
def setup_repo
Git.init('repository.git', bare: true)
git = Git.clone('repository.git', 'temp')
File.write('temp/test.txt', 'test')
git.add('test.txt')
git.commit('Initial commit')
end

def test_git_clone_with_name
in_temp_dir do |path|
setup_repo
clone_dir = 'clone_to_this_dir'
git = Git.clone('repository.git', clone_dir)
assert(Dir.exist?(clone_dir))
expected_dir = File.realpath(clone_dir)
assert_equal(expected_dir, git.dir.to_s)
end
end

def test_git_clone_with_no_name
in_temp_dir do |path|
setup_repo
git = Git.clone('repository.git')
assert(Dir.exist?('repository'))
expected_dir = File.realpath('repository')
assert_equal(expected_dir, git.dir.to_s)
end
end
end