Skip to content

Commit c07b3be

Browse files
committed
feat: make Worktree#clone work if clone_to path is not given
Also, use File#realpath to expand worktree and repository paths so that they are determinate.
1 parent d7a3232 commit c07b3be

File tree

5 files changed

+52
-11
lines changed

5 files changed

+52
-11
lines changed

lib/ruby_git/repository.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Repository
2727
# @param [String] repository_path the path to the repository
2828
#
2929
def initialize(repository_path)
30-
@path = File.expand_path(repository_path)
30+
@path = File.realpath(repository_path)
3131
end
3232
end
3333
end

lib/ruby_git/worktree.rb

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,23 @@ def self.open(worktree_path)
9797
#
9898
# @return [RubyGit::Worktree] the Git working tree checked out from the cloned repository
9999
#
100-
def self.clone(repository_url, to_path: '')
101-
command = ['clone', '--', repository_url, to_path]
100+
def self.clone(repository_url, to_path: nil)
101+
command = ['clone', '--', repository_url]
102+
command << to_path if to_path
102103
options = { out: StringIO.new, err: StringIO.new }
103-
RubyGit::CommandLine.run(*command, **options)
104-
new(to_path)
104+
clone_output = RubyGit::CommandLine.run(*command, **options).stderr
105+
new(cloned_to(clone_output))
106+
end
107+
108+
# Get path of the cloned worktree from `git clone` stderr output
109+
#
110+
# @param clone_output [String] the stderr output of the `git clone` command
111+
#
112+
# @return [String] the path of the cloned worktree
113+
#
114+
# @api private
115+
def self.cloned_to(clone_output)
116+
clone_output.match(/Cloning into ['"](.+)['"]\.\.\./)[1]
105117
end
106118

107119
# Show the working tree and index status
@@ -151,7 +163,7 @@ def repository
151163
command = %w[rev-parse --git-dir]
152164
options = { chdir: path, chomp: true, out: StringIO.new, err: StringIO.new }
153165
# rev-parse path might be relative to the worktree, thus the need to expand it
154-
git_dir = File.expand_path(RubyGit::CommandLine.run(*command, **options).stdout, path)
166+
git_dir = File.realpath(RubyGit::CommandLine.run(*command, **options).stdout, path)
155167
Repository.new(git_dir)
156168
end
157169
end
@@ -182,7 +194,7 @@ def initialize(worktree_path)
182194
def root_path(worktree_path)
183195
command = %w[rev-parse --show-toplevel]
184196
options = { chdir: worktree_path, chomp: true, out: StringIO.new, err: StringIO.new }
185-
RubyGit::CommandLine.run(*command, **options).stdout
197+
File.realpath(RubyGit::CommandLine.run(*command, **options).stdout)
186198
end
187199

188200
# Run a Git command in this worktree

spec/lib/ruby_git/repository_spec.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22

33
RSpec.describe RubyGit::Repository do
44
let(:repository) { RubyGit::Repository.new(repository_path) }
5+
let(:repository_path) { File.realpath(@repository_path) }
56

67
describe '#initialize' do
7-
subject { repository }
8-
98
context 'when given a repository path' do
10-
let(:repository_path) { File.expand_path('/path/to/repository') }
9+
around do |example|
10+
in_temp_dir do |repository_path|
11+
@repository_path = repository_path
12+
example.run
13+
end
14+
end
15+
16+
subject { repository }
1117

1218
it 'should set the path to the given repository path' do
1319
expect(subject).to have_attributes(path: repository_path)

spec/lib/ruby_git/worktree_clone_spec.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,29 @@ def make_bare_repository(repository_path)
1616
end
1717

1818
RSpec.describe RubyGit::Worktree do
19+
describe '.clone(url)' do
20+
subject { described_class.clone(repository_url) }
21+
let(:repository_url) { 'repository.git' }
22+
23+
around do |example|
24+
in_temp_dir do |path|
25+
@path = path
26+
27+
in_dir repository_url do
28+
run %w[git init --initial-branch=main]
29+
end
30+
example.run
31+
end
32+
end
33+
34+
let(:expected_worktree_path) { File.realpath(File.join(@path, 'repository')) }
35+
36+
it 'should return a Worktree object with the correct path' do
37+
expect(subject).to be_kind_of(RubyGit::Worktree)
38+
expect(subject).to have_attributes(path: expected_worktree_path)
39+
end
40+
end
41+
1942
describe '.clone(url, to_path: worktree_path)' do
2043
subject { described_class.clone(repository_url, to_path: worktree_path) }
2144
let(:tmpdir) { Dir.mktmpdir }

spec/lib/ruby_git/worktree_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@
1616
subject { worktree.repository }
1717

1818
it { is_expected.to be_a(RubyGit::Repository) }
19-
it { is_expected.to have_attributes(path: File.expand_path('./.git')) }
19+
it { is_expected.to have_attributes(path: File.realpath('./.git')) }
2020
end
2121
end

0 commit comments

Comments
 (0)