Skip to content

Commit 1e2265a

Browse files
committed
fixed critical bug in traverse_trees_recursive, implemented IndexFile.new including simple test, it may be simple as the methods it uses are throroughly tested
1 parent aea0243 commit 1e2265a

File tree

5 files changed

+31
-17
lines changed

5 files changed

+31
-17
lines changed

lib/git/index/base.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,16 @@
5959
)
6060

6161
from fun import (
62+
entry_key,
6263
write_cache,
6364
read_cache,
64-
write_tree_from_cache,
65-
entry_key
65+
aggressive_tree_merge,
66+
write_tree_from_cache
6667
)
6768

6869
from gitdb.base import IStream
6970
from gitdb.db import MemoryDB
71+
from itertools import izip
7072

7173
__all__ = ( 'IndexFile', 'CheckoutError' )
7274

@@ -253,10 +255,15 @@ def new(cls, repo, *tree_sha):
253255
New IndexFile instance. Its path will be undefined.
254256
If you intend to write such a merged Index, supply an alternate file_path
255257
to its 'write' method."""
256-
base_entries = aggressive_tree_merge(repo.odb, tree_sha)
258+
base_entries = aggressive_tree_merge(repo.odb, [str(t) for t in tree_sha])
257259

258-
inst = cls(self.repo)
259-
raise NotImplementedError("convert to entries")
260+
inst = cls(repo)
261+
# convert to entries dict
262+
entries = dict(izip(((e.path, e.stage) for e in base_entries),
263+
(IndexEntry.from_base(e) for e in base_entries)))
264+
265+
inst.entries = entries
266+
return inst
260267

261268

262269
@classmethod

lib/git/index/fun.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,16 @@ def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1
7878
def read_entry(stream):
7979
"""Return: One entry of the given stream"""
8080
beginoffset = stream.tell()
81-
ctime = unpack(">8s", stream.read(8))[0]
82-
mtime = unpack(">8s", stream.read(8))[0]
81+
read = stream.read
82+
ctime = unpack(">8s", read(8))[0]
83+
mtime = unpack(">8s", read(8))[0]
8384
(dev, ino, mode, uid, gid, size, sha, flags) = \
84-
unpack(">LLLLLL20sH", stream.read(20 + 4 * 6 + 2))
85+
unpack(">LLLLLL20sH", read(20 + 4 * 6 + 2))
8586
path_size = flags & CE_NAMEMASK
86-
path = stream.read(path_size)
87+
path = read(path_size)
8788

8889
real_size = ((stream.tell() - beginoffset + 8) & ~7)
89-
data = stream.read((beginoffset + real_size) - stream.tell())
90+
data = read((beginoffset + real_size) - stream.tell())
9091
return IndexEntry((mode, sha, flags, path, ctime, mtime, dev, ino, uid, gid, size))
9192

9293
def read_header(stream):

lib/git/objects/fun.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def traverse_trees_recursive(odb, tree_shas, path_prefix):
148148

149149
# if we are a directory, enter recursion
150150
if is_dir:
151-
out.extend(traverse_trees_recursive(odb, [ei[0] for ei in entries if ei], path_prefix+name+'/'))
151+
out.extend(traverse_trees_recursive(odb, [((ei and ei[0]) or None) for ei in entries], path_prefix+name+'/'))
152152
else:
153153
out_append(tuple(_to_full_path(e, path_prefix) for e in entries))
154154
# END handle recursion

test/git/test_fun.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ def test_aggressive_tree_merge(self):
6060
M = tree("44a601a068f4f543f73fd9c49e264c931b1e1652")
6161
trees = [B.sha, H.sha, M.sha]
6262
self._assert_index_entries(aggressive_tree_merge(odb, trees), trees)
63+
64+
# too many trees
65+
self.failUnlessRaises(ValueError, aggressive_tree_merge, odb, trees*2)
6366

6467
def mktree(self, odb, entries):
6568
"""create a tree from the given tree entries and safe it to the database"""
@@ -164,14 +167,10 @@ def assert_entries(entries, num_entries, has_conflict=False):
164167
# as one is deleted, there are only 2 entries
165168
assert_entries(aggressive_tree_merge(odb, trees), 2, True)
166169
# END handle ours, theirs
167-
168-
169-
170-
171170

172171
def _assert_tree_entries(self, entries, num_trees):
173-
assert len(entries[0]) == num_trees
174172
for entry in entries:
173+
assert len(entry) == num_trees
175174
paths = set(e[2] for e in entry if e)
176175

177176
# only one path per set of entries

test/git/test_index.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,13 @@ def write_tree(index):
594594
# END for each commit
595595

596596
def test_index_new(self):
597-
self.fail("todo index new")
597+
B = self.rorepo.tree("6d9b1f4f9fa8c9f030e3207e7deacc5d5f8bba4e")
598+
H = self.rorepo.tree("25dca42bac17d511b7e2ebdd9d1d679e7626db5f")
599+
M = self.rorepo.tree("e746f96bcc29238b79118123028ca170adc4ff0f")
600+
601+
for args in ((B,), (B,H), (B,H,M)):
602+
index = IndexFile.new(self.rorepo, *args)
603+
assert isinstance(index, IndexFile)
604+
# END for each arg tuple
598605

599606

0 commit comments

Comments
 (0)