Skip to content

Commit 737c4bb

Browse files
bilbofjcouball
authored andcommitted
ls-tree optional recursion into subtrees
1 parent 676ee17 commit 737c4bb

File tree

4 files changed

+27
-4
lines changed

4 files changed

+27
-4
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ g.index.writable?
236236
g.repo
237237
g.dir
238238

239+
# ls-tree with recursion into subtrees (list files)
240+
g.ls_tree("head", recursive: true)
241+
239242
# log - returns a Git::Log object, which is an Enumerator of Git::Commit objects
240243
# default configuration returns a max of 30 commits
241244
g.log

lib/git/base.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,8 +642,8 @@ def revparse(objectish)
642642
self.lib.revparse(objectish)
643643
end
644644

645-
def ls_tree(objectish)
646-
self.lib.ls_tree(objectish)
645+
def ls_tree(objectish, opts = {})
646+
self.lib.ls_tree(objectish, opts)
647647
end
648648

649649
def cat_file(objectish)

lib/git/lib.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,10 +374,15 @@ def object_contents(sha, &block)
374374
end
375375
end
376376

377-
def ls_tree(sha)
377+
def ls_tree(sha, opts = {})
378378
data = { 'blob' => {}, 'tree' => {}, 'commit' => {} }
379379

380-
command_lines('ls-tree', sha).each do |line|
380+
ls_tree_opts = []
381+
ls_tree_opts << '-r' if opts[:recursive]
382+
# path must be last arg
383+
ls_tree_opts << opts[:path] if opts[:path]
384+
385+
command_lines('ls-tree', sha, *ls_tree_opts).each do |line|
381386
(info, filenm) = line.split("\t")
382387
(mode, type, sha) = info.split
383388
data[type][filenm] = {:mode => mode, :sha => sha}

tests/units/test_ls_tree.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,26 @@ def test_ls_tree_with_submodules
1313
repo.add('README.md')
1414
repo.commit('Add README.md')
1515

16+
Dir.mkdir("repo/subdir")
17+
File.write('repo/subdir/file.md', 'Content in subdir')
18+
repo.add('subdir/file.md')
19+
repo.commit('Add subdir/file.md')
20+
21+
# ls_tree
22+
default_tree = assert_nothing_raised { repo.ls_tree('HEAD') }
23+
assert_equal(default_tree.dig("blob").keys.sort, ["README.md"])
24+
assert_equal(default_tree.dig("tree").keys.sort, ["subdir"])
25+
# ls_tree with recursion into sub-trees
26+
recursive_tree = assert_nothing_raised { repo.ls_tree('HEAD', recursive: true) }
27+
assert_equal(recursive_tree.dig("blob").keys.sort, ["README.md", "subdir/file.md"])
28+
assert_equal(recursive_tree.dig("tree").keys.sort, [])
29+
1630
Dir.chdir('repo') do
1731
assert_child_process_success { `git -c protocol.file.allow=always submodule add ../submodule submodule 2>&1` }
1832
assert_child_process_success { `git commit -am "Add submodule" 2>&1` }
1933
end
2034

35+
2136
expected_submodule_sha = submodule.object('HEAD').sha
2237

2338
# Make sure the ls_tree command can handle submodules (which show up as a commit object in the tree)

0 commit comments

Comments
 (0)