Browse Source

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>
stable-0.12
Shawn O. Pearce 14 years ago
parent
commit
b21c82fdb0
  1. 19
      org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java
  2. 37
      org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java

19
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java

@ -48,6 +48,7 @@ package org.eclipse.jgit.lib;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import java.io.IOException; import java.io.IOException;
@ -181,6 +182,24 @@ public class RepositoryResolveTest extends SampleDataRepositoryTestCase {
assertEquals(db.resolve("b~2"), db.resolve("B-6-g7f82283~2")); 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 @Test
public void testParseLookupPath() throws IOException { public void testParseLookupPath() throws IOException {
ObjectId b2_txt = id("10da5895682013006950e7da534b705252b03be6"); ObjectId b2_txt = id("10da5895682013006950e7da534b705252b03be6");

37
org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java

@ -577,24 +577,6 @@ public abstract class Repository {
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;
case ':': { case ':': {
RevTree tree; RevTree tree;
if (ref == null) { if (ref == null) {
@ -637,6 +619,14 @@ public abstract class Repository {
|| ('A' <= c && c <= 'F'); || ('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 { 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;
@ -653,6 +643,17 @@ public abstract class Repository {
if (AbbreviatedObjectId.isId(revstr)) if (AbbreviatedObjectId.isId(revstr))
return resolveAbbreviation(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; return null;
} }

Loading…
Cancel
Save