diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/ReflogReaderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/ReflogReaderTest.java index c0cc0c3b7..f3a6914be 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/ReflogReaderTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/ReflogReaderTest.java @@ -229,6 +229,42 @@ public class ReflogReaderTest extends SampleDataRepositoryTestCase { assertEquals("new/work", checkout.getFromBranch()); } + @Test + public void testSpecificEntryNumber() throws Exception { + setupReflog("logs/refs/heads/master", twoLine); + + ReflogReader reader = new ReflogReader(db, "refs/heads/master"); + ReflogEntry e = reader.getReverseEntry(0); + assertEquals( + ObjectId.fromString("c6734895958052a9dbc396cff4459dc1a25029ab"), + e.getOldId()); + assertEquals( + ObjectId.fromString("54794942a18a237c57a80719afed44bb78172b10"), + e.getNewId()); + assertEquals("Same A U Thor", e.getWho().getName()); + assertEquals("same.author@example.com", e.getWho().getEmailAddress()); + assertEquals(60, e.getWho().getTimeZoneOffset()); + assertEquals("2009-05-22T22:36:42", iso(e.getWho())); + assertEquals( + "rebase finished: refs/heads/rr/renamebranch5 onto c6e3b9fe2da0293f11eae202ec35fb343191a82d", + e.getComment()); + + e = reader.getReverseEntry(1); + assertEquals( + ObjectId.fromString("0000000000000000000000000000000000000000"), + e.getOldId()); + assertEquals( + ObjectId.fromString("c6734895958052a9dbc396cff4459dc1a25029ab"), + e.getNewId()); + assertEquals("A U Thor", e.getWho().getName()); + assertEquals("thor@committer.au", e.getWho().getEmailAddress()); + assertEquals(-60, e.getWho().getTimeZoneOffset()); + assertEquals("2009-05-22T20:36:41", iso(e.getWho())); + assertEquals("branch: Created from rr/renamebranchv4", e.getComment()); + + assertNull(reader.getReverseEntry(3)); + } + private void setupReflog(String logName, byte[] data) throws FileNotFoundException, IOException { File logfile = new File(db.getDirectory(), logName); diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties index d2933c46a..2eb685795 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties @@ -366,7 +366,7 @@ receivingObjects=Receiving objects refAlreadyExists=Ref {0} already exists refNotResolved=Ref {0} can not be resolved refUpdateReturnCodeWas=RefUpdate return code was: {0} -reflogEntryNotFound=Entry {0} not found in reflog for ''{1}'', only {2} entries exist +reflogEntryNotFound=Entry {0} not found in reflog for ''{1}'' remoteConfigHasNoURIAssociated=Remote config "{0}" has no URIs associated remoteDoesNotHaveSpec=Remote does not have {0} available for fetch. remoteDoesNotSupportSmartHTTPPush=remote does not support smart HTTP push diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java index afbde589c..1b649bba5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -630,14 +630,13 @@ public abstract class Repository { JGitText.get().invalidReflogRevision, time)); ReflogReader reader = new ReflogReader(this, ref.getName()); - List entries = reader.getReverseEntries(number + 1); - if (number >= entries.size()) + ReflogEntry entry = reader.getReverseEntry(number); + if (entry == null) throw new RevisionSyntaxException(MessageFormat.format( JGitText.get().reflogEntryNotFound, - Integer.valueOf(number), ref.getName(), - Integer.valueOf(entries.size()))); + Integer.valueOf(number), ref.getName())); - return rw.parseCommit(entries.get(number).getNewId()); + return rw.parseCommit(entry.getNewId()); } private ObjectId resolveAbbreviation(final String revstr) throws IOException, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ReflogReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ReflogReader.java index cec48f516..c60f9e371 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ReflogReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ReflogReader.java @@ -77,8 +77,7 @@ public class ReflogReader { * @throws IOException */ public ReflogEntry getLastEntry() throws IOException { - List entries = getReverseEntries(1); - return entries.size() > 0 ? entries.get(0) : null; + return getReverseEntry(0); } /** @@ -89,9 +88,39 @@ public class ReflogReader { return getReverseEntries(Integer.MAX_VALUE); } + /** + * Get specific entry in the reflog relative to the last entry which is + * considered entry zero. + * + * @param number + * @return reflog entry or null if not found + * @throws IOException + */ + public ReflogEntry getReverseEntry(int number) throws IOException { + if (number < 0) + throw new IllegalArgumentException(); + + final byte[] log; + try { + log = IO.readFully(logName); + } catch (FileNotFoundException e) { + return null; + } + + int rs = RawParseUtils.prevLF(log, log.length); + int current = 0; + while (rs >= 0) { + rs = RawParseUtils.prevLF(log, rs); + if (number == current) + return new ReflogEntry(log, rs < 0 ? 0 : rs + 2); + current++; + } + return null; + } + /** * @param max - * max numer of entries to read + * max number of entries to read * @return all reflog entries in reverse order * @throws IOException */