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>
This commit is contained in:
parent
c59e3a493b
commit
8da17c5046
|
@ -48,6 +48,8 @@
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||||
|
|
||||||
public class RepositoryResolveTest extends SampleDataRepositoryTestCase {
|
public class RepositoryResolveTest extends SampleDataRepositoryTestCase {
|
||||||
|
|
||||||
public void testObjectId_existing() throws IOException {
|
public void testObjectId_existing() throws IOException {
|
||||||
|
@ -140,4 +142,22 @@ public void testDerefTree() throws IOException {
|
||||||
assertEquals("856ec208ae6cadac25a6d74f19b12bb27a24fe24",db.resolve("refs/tags/B10th^{tree}").name());
|
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"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -375,8 +375,6 @@ public RefRename renameRef(final String fromRef, final String toRef) throws IOEx
|
||||||
* Currently supported is combinations of these.
|
* Currently supported is combinations of these.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>SHA-1 - a SHA-1</li>
|
* <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>refs/... - a ref name</li>
|
||||||
* <li>ref^n - nth parent reference</li>
|
* <li>ref^n - nth parent reference</li>
|
||||||
* <li>ref~n - distance via parent reference</li>
|
* <li>ref~n - distance via parent reference</li>
|
||||||
|
@ -387,7 +385,6 @@ public RefRename renameRef(final String fromRef, final String toRef) throws IOEx
|
||||||
*
|
*
|
||||||
* Not supported is:
|
* Not supported is:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>tag-NNN-gcommit - a non tagged revision from git describe</li>
|
|
||||||
* <li>timestamps in reflogs, ref@{full or relative timestamp}</li>
|
* <li>timestamps in reflogs, ref@{full or relative timestamp}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
|
@ -562,6 +559,25 @@ private ObjectId resolve(final RevWalk rw, final String revstr) throws IOExcepti
|
||||||
revstr);
|
revstr);
|
||||||
i = m - 1;
|
i = m - 1;
|
||||||
break;
|
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:
|
default:
|
||||||
if (ref != null)
|
if (ref != null)
|
||||||
throw new RevisionSyntaxException(revstr);
|
throw new RevisionSyntaxException(revstr);
|
||||||
|
@ -570,6 +586,12 @@ private ObjectId resolve(final RevWalk rw, final String revstr) throws IOExcepti
|
||||||
return ref != null ? ref.copy() : resolveSimple(revstr);
|
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 {
|
private RevObject parseSimple(RevWalk rw, String revstr) throws IOException {
|
||||||
ObjectId id = resolveSimple(revstr);
|
ObjectId id = resolveSimple(revstr);
|
||||||
return id != null ? rw.parseAny(id) : null;
|
return id != null ? rw.parseAny(id) : null;
|
||||||
|
@ -583,23 +605,29 @@ private ObjectId resolveSimple(final String revstr) throws IOException {
|
||||||
if (r != null)
|
if (r != null)
|
||||||
return r.getObjectId();
|
return r.getObjectId();
|
||||||
|
|
||||||
if (AbbreviatedObjectId.isId(revstr)) {
|
if (AbbreviatedObjectId.isId(revstr))
|
||||||
AbbreviatedObjectId id = AbbreviatedObjectId.fromString(revstr);
|
return resolveAbbreviation(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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
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()}. */
|
/** Increment the use counter by one, requiring a matched {@link #close()}. */
|
||||||
public void incrementOpen() {
|
public void incrementOpen() {
|
||||||
useCnt.incrementAndGet();
|
useCnt.incrementAndGet();
|
||||||
|
|
Loading…
Reference in New Issue