]> source.dussan.org Git - jgit.git/commitdiff
Update reflog like C Git during rebase (non-interactive) 17/12517/5
authorRobin Rosenberg <robin.rosenberg@dewire.com>
Sun, 5 May 2013 23:39:25 +0000 (01:39 +0200)
committerChris Aniszczyk <caniszczyk@gmail.com>
Mon, 22 Jul 2013 02:54:41 +0000 (21:54 -0500)
Bug: 346350
Change-Id: I119766a00bc52a810c51cffaa19207cb8555ca22
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java
org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java

index 397fb6151d07a82b4ff7e967cd302712d0b320bb..1f1962a7b163a0f3e8d7cf9645c0302cd8cd014a 100644 (file)
@@ -415,6 +415,7 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
                walk.release();
                // update the HEAD
                RefUpdate refUpdate = db.updateRef(Constants.HEAD);
+               refUpdate.setRefLogMessage("checkout: moving to " + branchName, false);
                refUpdate.link(branchName);
        }
 
index 9aa13caf9440f78f218fa199a16bfd3f0d8177a4..ef5a1eaa0c71be5d4a19ba2f517c38a17bfce353 100644 (file)
@@ -74,6 +74,7 @@ import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.ReflogEntry;
 import org.eclipse.jgit.lib.RepositoryState;
 import org.eclipse.jgit.merge.MergeStrategy;
 import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason;
@@ -107,6 +108,8 @@ public class RebaseCommandTest extends RepositoryTestCase {
                // update the HEAD
                RefUpdate refUpdate = db.updateRef(Constants.HEAD, true);
                refUpdate.setNewObjectId(commit);
+               refUpdate.setRefLogMessage("checkout: moving to " + head.getName(),
+                               false);
                refUpdate.forceUpdate();
        }
 
@@ -123,7 +126,7 @@ public class RebaseCommandTest extends RepositoryTestCase {
                // create file2 on master
                File file2 = writeTrashFile("file2", "file2");
                git.add().addFilepattern("file2").call();
-               git.commit().setMessage("Add file2").call();
+               RevCommit second = git.commit().setMessage("Add file2").call();
                assertTrue(new File(db.getWorkTree(), "file2").exists());
 
                checkoutBranch("refs/heads/topic");
@@ -133,6 +136,22 @@ public class RebaseCommandTest extends RepositoryTestCase {
                assertTrue(new File(db.getWorkTree(), "file2").exists());
                checkFile(file2, "file2");
                assertEquals(Status.FAST_FORWARD, res.getStatus());
+
+               List<ReflogEntry> headLog = db.getReflogReader(Constants.HEAD)
+                               .getReverseEntries();
+               List<ReflogEntry> topicLog = db.getReflogReader("refs/heads/topic")
+                               .getReverseEntries();
+               List<ReflogEntry> masterLog = db.getReflogReader("refs/heads/master")
+                               .getReverseEntries();
+               assertEquals("rebase finished: returning to refs/heads/topic", headLog
+                               .get(0).getComment());
+               assertEquals("checkout: moving from topic to " + second.getName(),
+                               headLog.get(1).getComment());
+               assertEquals(2, masterLog.size());
+               assertEquals(2, topicLog.size());
+               assertEquals(
+                               "rebase finished: refs/heads/topic onto " + second.getName(),
+                               topicLog.get(0).getComment());
        }
 
        @Test
@@ -153,7 +172,8 @@ public class RebaseCommandTest extends RepositoryTestCase {
                // write a second commit
                writeTrashFile("file2", "file2 new content");
                git.add().addFilepattern("file2").call();
-               git.commit().setMessage("Change content of file2").call();
+               RevCommit second = git.commit().setMessage("Change content of file2")
+                               .call();
 
                checkoutBranch("refs/heads/topic");
                assertFalse(new File(db.getWorkTree(), "file2").exists());
@@ -162,6 +182,22 @@ public class RebaseCommandTest extends RepositoryTestCase {
                assertTrue(new File(db.getWorkTree(), "file2").exists());
                checkFile(file2, "file2 new content");
                assertEquals(Status.FAST_FORWARD, res.getStatus());
+
+               List<ReflogEntry> headLog = db.getReflogReader(Constants.HEAD)
+                               .getReverseEntries();
+               List<ReflogEntry> topicLog = db.getReflogReader("refs/heads/topic")
+                               .getReverseEntries();
+               List<ReflogEntry> masterLog = db.getReflogReader("refs/heads/master")
+                               .getReverseEntries();
+               assertEquals("rebase finished: returning to refs/heads/topic", headLog
+                               .get(0).getComment());
+               assertEquals("checkout: moving from topic to " + second.getName(),
+                               headLog.get(1).getComment());
+               assertEquals(3, masterLog.size());
+               assertEquals(2, topicLog.size());
+               assertEquals(
+                               "rebase finished: refs/heads/topic onto " + second.getName(),
+                               topicLog.get(0).getComment());
        }
 
        /**
@@ -242,6 +278,29 @@ public class RebaseCommandTest extends RepositoryTestCase {
                assertDerivedFrom(rw.next(), c);
                assertEquals(b, rw.next());
                assertEquals(a, rw.next());
+
+               List<ReflogEntry> headLog = db.getReflogReader(Constants.HEAD)
+                               .getReverseEntries();
+               List<ReflogEntry> sideLog = db.getReflogReader("refs/heads/side")
+                               .getReverseEntries();
+               List<ReflogEntry> topicLog = db.getReflogReader("refs/heads/topic")
+                               .getReverseEntries();
+               List<ReflogEntry> masterLog = db.getReflogReader("refs/heads/master")
+                               .getReverseEntries();
+               assertEquals("rebase finished: returning to refs/heads/topic", headLog
+                               .get(0).getComment());
+               assertEquals("rebase: update file2 on side", headLog.get(1)
+                               .getComment());
+               assertEquals("rebase: Add file2", headLog.get(2).getComment());
+               assertEquals("rebase: update file3 on topic", headLog.get(3)
+                               .getComment());
+               assertEquals("checkout: moving from topic to " + b.getName(), headLog
+                               .get(4).getComment());
+               assertEquals(2, masterLog.size());
+               assertEquals(2, sideLog.size());
+               assertEquals(5, topicLog.size());
+               assertEquals("rebase finished: refs/heads/topic onto " + b.getName(),
+                               topicLog.get(0).getComment());
        }
 
        static void assertDerivedFrom(RevCommit derived, RevCommit original) {
@@ -261,6 +320,11 @@ public class RebaseCommandTest extends RepositoryTestCase {
 
                RebaseResult result = git.rebase().setUpstream(parent).call();
                assertEquals(Status.UP_TO_DATE, result.getStatus());
+
+               assertEquals(2, db.getReflogReader(Constants.HEAD).getReverseEntries()
+                               .size());
+               assertEquals(2, db.getReflogReader("refs/heads/master")
+                               .getReverseEntries().size());
        }
 
        @Test
@@ -274,6 +338,11 @@ public class RebaseCommandTest extends RepositoryTestCase {
 
                RebaseResult res = git.rebase().setUpstream(first).call();
                assertEquals(Status.UP_TO_DATE, res.getStatus());
+
+               assertEquals(1, db.getReflogReader(Constants.HEAD).getReverseEntries()
+                               .size());
+               assertEquals(1, db.getReflogReader("refs/heads/master")
+                               .getReverseEntries().size());
        }
 
        @Test
@@ -328,6 +397,18 @@ public class RebaseCommandTest extends RepositoryTestCase {
                assertEquals(lastMasterChange, new RevWalk(db).parseCommit(
                                db.resolve(Constants.HEAD)).getParent(0));
                assertEquals(origHead, db.readOrigHead());
+               List<ReflogEntry> headLog = db.getReflogReader(Constants.HEAD)
+                               .getReverseEntries();
+               List<ReflogEntry> topicLog = db.getReflogReader("refs/heads/topic")
+                               .getReverseEntries();
+               List<ReflogEntry> masterLog = db.getReflogReader("refs/heads/master")
+                               .getReverseEntries();
+               assertEquals(2, masterLog.size());
+               assertEquals(3, topicLog.size());
+               assertEquals("rebase finished: refs/heads/topic onto "
+                               + lastMasterChange.getName(), topicLog.get(0).getComment());
+               assertEquals("rebase finished: returning to refs/heads/topic", headLog
+                               .get(0).getComment());
        }
 
        @Test
@@ -366,6 +447,13 @@ public class RebaseCommandTest extends RepositoryTestCase {
                assertEquals(lastMasterChange, new RevWalk(db).parseCommit(
                                db.resolve(Constants.HEAD)).getParent(0));
 
+               List<ReflogEntry> headLog = db.getReflogReader(Constants.HEAD)
+                               .getReverseEntries();
+               assertEquals(8, headLog.size());
+               assertEquals("rebase: change file1 in topic", headLog.get(0)
+                               .getComment());
+               assertEquals("checkout: moving from " + topicCommit.getName() + " to "
+                               + lastMasterChange.getName(), headLog.get(1).getComment());
        }
 
        @Test
index 2ebff14f9c789a56916596fb4a2ed961c9bb7a81..1b8441170ce28120c925465c689821db59b2e991 100644 (file)
@@ -82,6 +82,8 @@ import org.eclipse.jgit.treewalk.FileTreeIterator;
  *      >Git documentation about cherry-pick</a>
  */
 public class CherryPickCommand extends GitCommand<CherryPickResult> {
+       private String reflogPrefix = "cherry-pick:"; //$NON-NLS-1$
+
        private List<Ref> commits = new LinkedList<Ref>();
 
        private String ourCommitName = null;
@@ -166,9 +168,8 @@ public class CherryPickCommand extends GitCommand<CherryPickResult> {
                                        dco.checkout();
                                        newHead = new Git(getRepository()).commit()
                                                        .setMessage(srcCommit.getFullMessage())
-                                                       .setReflogComment(
-                                                                       "cherry-pick: " //$NON-NLS-1$
-                                                                                       + srcCommit.getShortMessage())
+                                                       .setReflogComment(reflogPrefix + " " //$NON-NLS-1$
+                                                                       + srcCommit.getShortMessage())
                                                        .setAuthor(srcCommit.getAuthorIdent()).call();
                                        cherryPickedRefs.add(src);
                                } else {
@@ -242,6 +243,21 @@ public class CherryPickCommand extends GitCommand<CherryPickResult> {
                return this;
        }
 
+       /**
+        * Set the prefix to use in the reflog.
+        * <p>
+        * This is primarily needed for implementing rebase in terms of
+        * cherry-picking
+        *
+        * @param prefix
+        *            including ":"
+        * @return {@code this}
+        */
+       public CherryPickCommand setReflogPrefix(final String prefix) {
+               this.reflogPrefix = prefix;
+               return this;
+       }
+
        private String calculateOurName(Ref headRef) {
                if (ourCommitName != null)
                        return ourCommitName;
index 911a4e6294810b9f4b19aa9322b3c5298014925c..592a01287077f303c84a045bf2338eb504fc692b 100644 (file)
@@ -319,7 +319,8 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
                                                String ourCommitName = getOurCommitName();
                                                CherryPickResult cherryPickResult = new Git(repo)
                                                                .cherryPick().include(commitToPick)
-                                                               .setOurCommitName(ourCommitName).call();
+                                                               .setOurCommitName(ourCommitName)
+                                                               .setReflogPrefix("rebase:").call(); //$NON-NLS-1$
                                                switch (cherryPickResult.getStatus()) {
                                                case FAILED:
                                                        if (operation == Operation.BEGIN)
@@ -353,7 +354,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
                        }
                        if (newHead != null) {
                                String headName = rebaseState.readFile(HEAD_NAME);
-                               updateHead(headName, newHead);
+                               updateHead(headName, newHead, upstreamCommit);
                                FileUtils.delete(rebaseState.getDir(), FileUtils.RECURSIVE);
                                if (lastStepWasForward)
                                        return RebaseResult.FAST_FORWARD_RESULT;
@@ -370,18 +371,20 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
        private String getOurCommitName() {
                // If onto is different from upstream, this should say "onto", but
                // RebaseCommand doesn't support a different "onto" at the moment.
-               String ourCommitName = "Upstream, based on "
+               String ourCommitName = "Upstream, based on " //$NON-NLS-1$
                                + Repository.shortenRefName(upstreamCommitName);
                return ourCommitName;
        }
 
-       private void updateHead(String headName, RevCommit newHead)
+       private void updateHead(String headName, RevCommit newHead, RevCommit onto)
                        throws IOException {
                // point the previous head (if any) to the new commit
 
                if (headName.startsWith(Constants.R_REFS)) {
                        RefUpdate rup = repo.updateRef(headName);
                        rup.setNewObjectId(newHead);
+                       rup.setRefLogMessage("rebase finished: " + headName + " onto " //$NON-NLS-1$
+                                       + onto.getName(), false);
                        Result res = rup.forceUpdate();
                        switch (res) {
                        case FAST_FORWARD:
@@ -392,6 +395,8 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
                                throw new JGitInternalException("Updating HEAD failed");
                        }
                        rup = repo.updateRef(Constants.HEAD);
+                       rup.setRefLogMessage("rebase finished: returning to " + headName, //$NON-NLS-1$
+                                       false);
                        res = rup.link(headName);
                        switch (res) {
                        case FAST_FORWARD:
@@ -614,7 +619,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
                if (head.isSymbolic())
                        headName = head.getTarget().getName();
                else
-                       headName = "detached HEAD";
+                       headName = head.getObjectId().getName();
                ObjectId headId = head.getObjectId();
                if (headId == null)
                        throw new RefNotFoundException(MessageFormat.format(
@@ -629,10 +634,10 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
                        monitor.beginTask(MessageFormat.format(
                                        JGitText.get().resettingHead,
                                        upstreamCommit.getShortMessage()), ProgressMonitor.UNKNOWN);
-                       checkoutCommit(upstreamCommit);
+                       checkoutCommit(headName, upstreamCommit);
                        monitor.endTask();
 
-                       updateHead(headName, upstreamCommit);
+                       updateHead(headName, upstreamCommit, upstream);
                        return RebaseResult.FAST_FORWARD_RESULT;
                }
 
@@ -691,7 +696,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
                                upstreamCommit.getShortMessage()), ProgressMonitor.UNKNOWN);
                boolean checkoutOk = false;
                try {
-                       checkoutOk = checkoutCommit(upstreamCommit);
+                       checkoutOk = checkoutCommit(headName, upstreamCommit);
                } finally {
                        if (!checkoutOk)
                                FileUtils.delete(rebaseState.getDir(), FileUtils.RECURSIVE);
@@ -732,7 +737,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
                if (head.isSymbolic())
                        headName = head.getTarget().getName();
                else
-                       headName = "detached HEAD";
+                       headName = head.getObjectId().getName();
                return tryFastForward(headName, headCommit, newCommit);
        }
 
@@ -843,6 +848,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
 
                                // update the HEAD
                                RefUpdate refUpdate = repo.updateRef(Constants.HEAD, false);
+                               refUpdate.setRefLogMessage("rebase: aborting", false); //$NON-NLS-1$
                                Result res = refUpdate.link(headName);
                                switch (res) {
                                case FAST_FORWARD:
@@ -864,7 +870,8 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
                }
        }
 
-       private boolean checkoutCommit(RevCommit commit) throws IOException,
+       private boolean checkoutCommit(String headName, RevCommit commit)
+                       throws IOException,
                        CheckoutConflictException {
                try {
                        RevCommit head = walk.parseCommit(repo.resolve(Constants.HEAD));
@@ -880,6 +887,10 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
                        RefUpdate refUpdate = repo.updateRef(Constants.HEAD, true);
                        refUpdate.setExpectedOldObjectId(head);
                        refUpdate.setNewObjectId(commit);
+                       refUpdate.setRefLogMessage(
+                                       "checkout: moving from " //$NON-NLS-1$
+                                                       + Repository.shortenRefName(headName)
+                                                       + " to " + commit.getName(), false); //$NON-NLS-1$
                        Result res = refUpdate.forceUpdate();
                        switch (res) {
                        case FAST_FORWARD: