Skip to content

Commit f590869

Browse files
author
scott Chacon
committed
added the tree functions and tests
1 parent 852a0e6 commit f590869

File tree

5 files changed

+84
-14
lines changed

5 files changed

+84
-14
lines changed

README

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ Here are the operations that need read permission only.
6767
commit.date.strftime("%m-%d-%y")
6868
commit.message
6969

70+
tree = g.gtree("HEAD^{tree}")
71+
tree.blobs
72+
tree.subtrees
73+
tree.children # blobs and subtrees
7074

7175
g.revparse('v2.5:Makefile')
7276

lib/git/lib.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ def object_contents(sha)
109109
command('cat-file', ['-p', sha])
110110
end
111111

112+
def ls_tree(sha)
113+
data = {'blob' => {}, 'tree' => {}}
114+
command_lines('ls-tree', sha.to_s).each do |line|
115+
(info, filenm) = line.split("\t")
116+
(mode, type, sha) = info.split
117+
data[type][filenm] = {:mode => mode, :sha => sha}
118+
end
119+
data
120+
end
121+
112122
def branches_all
113123
arr = []
114124
command_lines('branch', '-a').each do |b|

lib/git/object.rb

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,61 @@ def log(count = 30)
5151

5252

5353
class Blob < AbstractObject
54+
55+
def initialize(base, sha, mode = nil)
56+
super(base, sha)
57+
@mode = mode
58+
end
59+
5460
def setup
5561
@type = 'blob'
5662
end
5763
end
5864

5965
class Tree < AbstractObject
66+
67+
@trees = nil
68+
@blobs = nil
69+
70+
def initialize(base, sha, mode = nil)
71+
super(base, sha)
72+
@mode = mode
73+
end
74+
6075
def setup
6176
@type = 'tree'
6277
end
78+
79+
def children
80+
blobs.merge(subtrees)
81+
end
82+
83+
def blobs
84+
check_tree
85+
@blobs
86+
end
87+
alias_method :files, :blobs
88+
89+
def trees
90+
check_tree
91+
@trees
92+
end
93+
alias_method :subtrees, :trees
94+
alias_method :subdirectories, :trees
95+
96+
private
97+
98+
# actually run the git command
99+
def check_tree
100+
if !@trees
101+
@trees = {}
102+
@blobs = {}
103+
data = @base.lib.ls_tree(@sha)
104+
data['tree'].each { |k, d| @trees[k] = Tree.new(@base, d[:sha], d[:mode]) }
105+
data['blob'].each { |k, d| @blobs[k] = Blob.new(@base, d[:sha], d[:mode]) }
106+
end
107+
end
108+
63109
end
64110

65111
class Commit < AbstractObject
@@ -123,12 +169,14 @@ def diff_parent
123169

124170
# see if this object has been initialized and do so if not
125171
def check_commit
126-
data = @base.lib.commit_data(@sha)
127-
@committer = Git::Author.new(data['committer'])
128-
@author = Git::Author.new(data['author'])
129-
@tree = Tree.new(@base, data['tree'])
130-
@parents = data['parent'].map{ |sha| Commit.new(@base, sha) }
131-
@message = data['message'].chomp
172+
if !@tree
173+
data = @base.lib.commit_data(@sha)
174+
@committer = Git::Author.new(data['committer'])
175+
@author = Git::Author.new(data['author'])
176+
@tree = Tree.new(@base, data['tree'])
177+
@parents = data['parent'].map{ |sha| Commit.new(@base, sha) }
178+
@message = data['message'].chomp
179+
end
132180
end
133181

134182
end

tests/test_helper.rb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,26 @@ def set_file_paths
2222
end
2323

2424
def teardown
25-
if @wdir
26-
FileUtils.rm_r(@wdir)
25+
if @tmp_path
26+
#puts "teardown #{@tmp_path}"
27+
FileUtils.rm_r(@tmp_path)
2728
end
2829
end
2930

3031
def create_temp_repo(clone_path)
31-
filename = 'git_test' + Time.now.to_i.to_s + rand(300).to_s
32-
tmp_path = File.join("/tmp/", filename)
33-
FileUtils.mkdir_p(tmp_path)
34-
FileUtils.cp_r(clone_path, tmp_path)
35-
tmp_path = File.join(tmp_path, 'working')
32+
filename = 'git_test' + Time.now.to_i.to_s + rand(300).to_s.rjust(3, '0')
33+
@tmp_path = File.join("/tmp/", filename)
34+
FileUtils.mkdir_p(@tmp_path)
35+
FileUtils.cp_r(clone_path, @tmp_path)
36+
tmp_path = File.join(@tmp_path, 'working')
3637
Dir.chdir(tmp_path) do
3738
FileUtils.mv('dot_git', '.git')
3839
end
3940
tmp_path
4041
end
4142

4243
def in_temp_dir(remove_after = true)
43-
filename = 'git_test' + Time.now.to_i.to_s + rand(300).to_s
44+
filename = 'git_test' + Time.now.to_i.to_s + rand(300).to_s.rjust(3, '0')
4445
tmp_path = File.join("/tmp/", filename)
4546
FileUtils.mkdir(tmp_path)
4647
Dir.chdir tmp_path do

tests/units/test_object.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ def test_tree
5959
o = @git.object('1cc8667014381^{tree}')
6060
assert(o.is_a?(Git::Object::Tree))
6161

62+
o = @git.object('v2.7^{tree}')
63+
64+
assert_equal(2, o.children.size)
65+
assert_equal(1, o.blobs.size)
66+
assert_equal(1, o.subtrees.size)
67+
assert_equal(1, o.trees['ex_dir'].blobs.size)
68+
6269
o = @git.object('94c827875e2cadb8bc8d4cdd900f19aa9e8634c7')
6370
assert(o.is_a?(Git::Object::Tree))
6471
assert_equal('tree', o.type)

0 commit comments

Comments
 (0)