diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2010-08-24 17:35:52 -0700 |
---|---|---|
committer | Shawn O. Pearce <spearce@spearce.org> | 2010-08-25 17:07:13 -0700 |
commit | 8da17c50469f0864e710faf9d068ce2abe1f92fc (patch) | |
tree | beb9b93bec42df2fb4379c3e449f47f8fb79d8b2 | |
parent | c59e3a493b60e0e1f4a26aaf752737102335a625 (diff) | |
download | jgit-8da17c50469f0864e710faf9d068ce2abe1f92fc.tar.gz jgit-8da17c50469f0864e710faf9d068ce2abe1f92fc.zip |
Support parsing git describe style output
We now match on the -gABBREV style output created by git describe
when its describing a non-tagged commit, and resolve that back to
the full ObjectId using the abbreviation resolution feature that
we already support.
Change-Id: Ib3033f9483d9e1c66c8bb721ff48d4485bcdaef1
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
-rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java | 20 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java | 60 |
2 files changed, 64 insertions, 16 deletions
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 c6ab8ba4f3..4ca9ba0208 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 @@ -48,6 +48,8 @@ package org.eclipse.jgit.lib; import java.io.IOException; +import org.eclipse.jgit.errors.IncorrectObjectTypeException; + public class RepositoryResolveTest extends SampleDataRepositoryTestCase { public void testObjectId_existing() throws IOException { @@ -140,4 +142,22 @@ public class RepositoryResolveTest extends SampleDataRepositoryTestCase { assertEquals("856ec208ae6cadac25a6d74f19b12bb27a24fe24",db.resolve("refs/tags/B10th^{tree}").name()); } + public void testParseGitDescribeOutput() throws IOException { + ObjectId exp = db.resolve("b"); + assertEquals(exp, db.resolve("B-g7f82283")); // old style + assertEquals(exp, db.resolve("B-6-g7f82283")); // new style + + assertEquals(exp, db.resolve("B-6-g7f82283^0")); + assertEquals(exp, db.resolve("B-6-g7f82283^{commit}")); + + try { + db.resolve("B-6-g7f82283^{blob}"); + fail("expected IncorrectObjectTypeException"); + } catch (IncorrectObjectTypeException badType) { + // Expected + } + + assertEquals(db.resolve("b^1"), db.resolve("B-6-g7f82283^1")); + assertEquals(db.resolve("b~2"), db.resolve("B-6-g7f82283~2")); + } } 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 078b293f41..8a04205684 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -375,8 +375,6 @@ public abstract class Repository { * Currently supported is combinations of these. * <ul> * <li>SHA-1 - a SHA-1</li> - * <li>SHA-1 abbreviation - a leading prefix of a SHA-1. At least the first - * two bytes must be supplied.</li> * <li>refs/... - a ref name</li> * <li>ref^n - nth parent reference</li> * <li>ref~n - distance via parent reference</li> @@ -387,7 +385,6 @@ public abstract class Repository { * * Not supported is: * <ul> - * <li>tag-NNN-gcommit - a non tagged revision from git describe</li> * <li>timestamps in reflogs, ref@{full or relative timestamp}</li> * </ul> * @@ -562,6 +559,25 @@ public abstract class Repository { revstr); i = m - 1; break; + case '-': + if (i + 4 < rev.length && rev[i + 1] == 'g' + && isHex(rev[i + 2]) && isHex(rev[i + 3])) { + // Possibly output from git describe? + // Resolve longest valid abbreviation. + int cnt = 2; + while (i + 2 + cnt < rev.length && isHex(rev[i + 2 + cnt])) + cnt++; + String s = new String(rev, i + 2, cnt); + if (AbbreviatedObjectId.isId(s)) { + ObjectId id = resolveAbbreviation(s); + if (id != null) { + ref = rw.parseAny(id); + i += 1 + s.length(); + } + } + } + break; + default: if (ref != null) throw new RevisionSyntaxException(revstr); @@ -570,6 +586,12 @@ public abstract class Repository { return ref != null ? ref.copy() : resolveSimple(revstr); } + private static boolean isHex(char c) { + return ('0' <= c && c <= '9') // + || ('a' <= c && c <= 'f') // + || ('A' <= c && c <= 'F'); + } + private RevObject parseSimple(RevWalk rw, String revstr) throws IOException { ObjectId id = resolveSimple(revstr); return id != null ? rw.parseAny(id) : null; @@ -583,23 +605,29 @@ public abstract class Repository { if (r != null) return r.getObjectId(); - if (AbbreviatedObjectId.isId(revstr)) { - AbbreviatedObjectId id = AbbreviatedObjectId.fromString(revstr); - ObjectReader reader = newObjectReader(); - try { - Collection<ObjectId> matches = reader.resolve(id); - if (matches.size() == 1) - return matches.iterator().next(); - if (1 < matches.size()) - throw new AmbiguousObjectException(id, matches); - } finally { - reader.release(); - } - } + if (AbbreviatedObjectId.isId(revstr)) + return resolveAbbreviation(revstr); return null; } + private ObjectId resolveAbbreviation(final String revstr) throws IOException, + AmbiguousObjectException { + AbbreviatedObjectId id = AbbreviatedObjectId.fromString(revstr); + ObjectReader reader = newObjectReader(); + try { + Collection<ObjectId> matches = reader.resolve(id); + if (matches.size() == 0) + return null; + else if (matches.size() == 1) + return matches.iterator().next(); + else + throw new AmbiguousObjectException(id, matches); + } finally { + reader.release(); + } + } + /** Increment the use counter by one, requiring a matched {@link #close()}. */ public void incrementOpen() { useCnt.incrementAndGet(); |