Browse Source

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>
tags/v0.9.1
Shawn O. Pearce 13 years ago
parent
commit
8da17c5046

+ 20
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java View File

@@ -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"));
}
}

+ 44
- 16
org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java View File

@@ -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();

Loading…
Cancel
Save