resolve(): Fix wrong parsing of branch "foo-gbed2-dev"

When parsing a string such as "foo-gbed2" resolve() was assuming the
suffix was from git describe output.  This lead to JGit trying to find
the completion for the object abbreviation "bed2", rather than using
the current value of the reference.  If there was only one such object
in the repository, JGit might actually use the wrong value here, as
resolve() would return the completion of the abbreviation "bed2"
rather than the current value of the reference "refs/heads/foo-gbed2".

Move the parsing of git describe abbreviations out of the operator
portion of the resolve() method and into the simple portion that is
supposed to handle only object ids or reference names, and only do the
describe parsing after all other approaches have already failed to
provide a resolution.

Add new unit tests to verify the behavior is as expected by users.

Bug: 338839
Change-Id: I52054d7b89628700c730f9a4bd7743b16b9042a9
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
Shawn O. Pearce 2011-03-03 16:17:29 -08:00
parent 3ee3588b86
commit b21c82fdb0
2 changed files with 38 additions and 18 deletions

View File

@ -48,6 +48,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
import java.io.IOException;
@ -181,6 +182,24 @@ public void testParseGitDescribeOutput() throws IOException {
assertEquals(db.resolve("b~2"), db.resolve("B-6-g7f82283~2"));
}
@Test
public void testParseNonGitDescribe() throws IOException {
ObjectId id = id("49322bb17d3acc9146f98c97d078513228bbf3c0");
RefUpdate ru = db.updateRef("refs/heads/foo-g032c");
ru.setNewObjectId(id);
assertSame(RefUpdate.Result.NEW, ru.update());
assertEquals(id, db.resolve("refs/heads/foo-g032c"));
assertEquals(id, db.resolve("foo-g032c"));
ru = db.updateRef("refs/heads/foo-g032c-dev");
ru.setNewObjectId(id);
assertSame(RefUpdate.Result.NEW, ru.update());
assertEquals(id, db.resolve("refs/heads/foo-g032c-dev"));
assertEquals(id, db.resolve("foo-g032c-dev"));
}
@Test
public void testParseLookupPath() throws IOException {
ObjectId b2_txt = id("10da5895682013006950e7da534b705252b03be6");

View File

@ -577,24 +577,6 @@ private ObjectId resolve(final RevWalk rw, final String revstr) throws IOExcepti
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;
case ':': {
RevTree tree;
if (ref == null) {
@ -637,6 +619,14 @@ private static boolean isHex(char c) {
|| ('A' <= c && c <= 'F');
}
private static boolean isAllHex(String str, int ptr) {
while (ptr < str.length()) {
if (!isHex(str.charAt(ptr++)))
return false;
}
return true;
}
private RevObject parseSimple(RevWalk rw, String revstr) throws IOException {
ObjectId id = resolveSimple(revstr);
return id != null ? rw.parseAny(id) : null;
@ -653,6 +643,17 @@ private ObjectId resolveSimple(final String revstr) throws IOException {
if (AbbreviatedObjectId.isId(revstr))
return resolveAbbreviation(revstr);
int dashg = revstr.indexOf("-g");
if (4 < revstr.length() && 0 <= dashg
&& isHex(revstr.charAt(dashg + 2))
&& isHex(revstr.charAt(dashg + 3))
&& isAllHex(revstr, dashg + 4)) {
// Possibly output from git describe?
String s = revstr.substring(dashg + 2);
if (AbbreviatedObjectId.isId(s))
return resolveAbbreviation(s);
}
return null;
}