Skip to content

Commit

Permalink
Make the directory param to Git.clone optional (#578)
Browse files Browse the repository at this point in the history
Signed-off-by: James Couball <jcouball@yahoo.com>
  • Loading branch information
jcouball committed Apr 26, 2022
1 parent b92130c commit 45b467c
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 13 deletions.
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

0 comments on commit 45b467c

Please sign in to comment.