The number specified is interpreted as relative to the last entry in the reflog. Change-Id: Ie4dd03370bb0d475a0e89d3015113ca98920100ftags/v1.3.0.201202121842-rc4
@@ -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); |
@@ -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 |
@@ -630,14 +630,13 @@ public abstract class Repository { | |||
JGitText.get().invalidReflogRevision, time)); | |||
ReflogReader reader = new ReflogReader(this, ref.getName()); | |||
List<ReflogEntry> 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, |
@@ -77,8 +77,7 @@ public class ReflogReader { | |||
* @throws IOException | |||
*/ | |||
public ReflogEntry getLastEntry() throws IOException { | |||
List<ReflogEntry> 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 | |||
*/ |