Fix CanonicalTreeParser.back to parse all trees correctly
commita52211d20dc53445c52dd7f56ca152f6b1b1eb13
authorShawn O. Pearce <spearce@spearce.org>
Sun, 7 Jun 2009 22:01:56 +0000 (7 15:01 -0700)
committerRobin Rosenberg <robin.rosenberg@dewire.com>
Fri, 12 Jun 2009 17:14:13 +0000 (12 19:14 +0200)
tree4a856ceb0854d1fb6e6d79c662e43681b18880f7
parent07463ab6375b29c1eb63c7627249f69e18131704
Fix CanonicalTreeParser.back to parse all trees correctly

The back(int delta) method needs to walk backwards delta entries in
the tree we are iterating.  Unfortunately, despite my attempts to do
so, there is no reliable way to parse a canonical tree in reverse.

New test cases testBackwords_Prebuilts1 and testBackwords_Prebuilts2
show trees where the parser silently fails and jumps over an entry
it should not have skipped.  These came from real world trees that
caused NameConflictTreeWalk to get stuck in an infinite loop.

The only reliable way to parse a canonical tree backwards is to
actually do a parse from the beginning, and keeping track of the N
prior positions in the tree, until we reach the current position,
and then use the 0th index from that temporary N position buffer.

Most of the time, we only need to walk a parser back 1 entry, to
examine the last path name it produced, before deciding we don't
need to handle a D/F conflict, and walk the parser forward again.

This is typical because most Git trees do not have a potential D/F
conflict looming during a NameConflictTreeWalk, as it is rare that
tree entries have the same leading base name such that a directory
could appear between two files.  Usually stepping back just one
entry is sufficient to detemine a D/F conflict can't happen, and
the parser runs forward again.  So we optimize for this delta = 1
case by saving a prevPtr field.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
org.spearce.jgit.test/tst/org/spearce/jgit/treewalk/CanonicalTreeParserTest.java
org.spearce.jgit/src/org/spearce/jgit/treewalk/CanonicalTreeParser.java