]> source.dussan.org Git - jgit.git/commitdiff
Support parsing git describe style output 08/1408/2
authorShawn O. Pearce <spearce@spearce.org>
Wed, 25 Aug 2010 00:35:52 +0000 (17:35 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Thu, 26 Aug 2010 00:07:13 +0000 (17:07 -0700)
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>
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java
org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java

index c6ab8ba4f3de028eaa68b1c1fb3c818196933c45..4ca9ba02085302972330ec5d833c8920d4b16dfd 100644 (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"));
+       }
 }
index 078b293f41cb95e8c633ce5b8723f2921eae7167..8a0420568410abfe795ec4986c1b59c9e92ce158 100644 (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();