From dbd2d7c83bc8a3a72a9ce6c4d8d0ae575e381588 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 24 Aug 2010 17:52:26 -0700 Subject: [PATCH] Support parsing commit:path style blob references We can now resolve expressions that reference a path within a commit, designating a specific revision of a specific tree or file in the project. Change-Id: Ie6a8be629d264d72209db894bd680c5900035cc0 Signed-off-by: Shawn O. Pearce --- .../jgit/lib/RepositoryResolveTest.java | 21 ++++++++++++++ .../src/org/eclipse/jgit/lib/Repository.java | 29 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java index 4ca9ba020..0aa8db474 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java @@ -160,4 +160,25 @@ public void testParseGitDescribeOutput() throws IOException { assertEquals(db.resolve("b^1"), db.resolve("B-6-g7f82283^1")); assertEquals(db.resolve("b~2"), db.resolve("B-6-g7f82283~2")); } + + public void testParseLookupPath() throws IOException { + ObjectId b2_txt = id("10da5895682013006950e7da534b705252b03be6"); + ObjectId b3_b2_txt = id("e6bfff5c1d0f0ecd501552b43a1e13d8008abc31"); + ObjectId b_root = id("acd0220f06f7e4db50ea5ba242f0dfed297b27af"); + ObjectId master_txt = id("82b1d08466e9505f8666b778744f9a3471a70c81"); + + assertEquals(b2_txt, db.resolve("b:b/b2.txt")); + assertEquals(b_root, db.resolve("b:")); + assertEquals(master_txt, db.resolve(":master.txt")); + assertEquals(b3_b2_txt, db.resolve("b~3:b/b2.txt")); + + assertNull("no FOO", db.resolve("b:FOO")); + assertNull("no b/FOO", db.resolve("b:b/FOO")); + assertNull("no b/FOO", db.resolve(":b/FOO")); + assertNull("no not-a-branch:", db.resolve("not-a-branch:")); + } + + private static ObjectId id(String name) { + return ObjectId.fromString(name); + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java index 8a0420568..c3d1d4948 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -74,8 +74,10 @@ import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevObject; +import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.storage.file.ReflogReader; +import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.RawParseUtils; @@ -577,6 +579,33 @@ && isHex(rev[i + 2]) && isHex(rev[i + 3])) { } } break; + case ':': { + RevTree tree; + if (ref == null) { + // We might not yet have parsed the left hand side. + ObjectId id; + try { + if (i == 0) + id = resolve(rw, Constants.HEAD); + else + id = resolve(rw, new String(rev, 0, i)); + } catch (RevisionSyntaxException badSyntax) { + throw new RevisionSyntaxException(revstr); + } + if (id == null) + return null; + tree = rw.parseTree(id); + } else { + tree = rw.parseTree(ref); + } + + if (i == rev.length - i) + return tree.copy(); + + TreeWalk tw = TreeWalk.forPath(rw.getObjectReader(), + new String(rev, i + 1, rev.length - i - 1), tree); + return tw != null ? tw.getObjectId(0) : null; + } default: if (ref != null)