RebaseCommand: fix commit message in "fixup" case
JGit accumulated in MESSAGE_FIXUP commit messages of a fixup sequence, just like it did in MESSAGE_SQUASH, and on the last step of a sequence of fixups used that file, after stripping all comment lines, as the commit message. That also stripped any lines from the original commit message that happened to start with the comment character. This is not how this is supposed to work. MESSAGE_FIXUP must contain the original commit message of the base commit that is amended, and the file contains the verbatim commit message for the final fixup.[1] Change the implementation accordingly, and add new tests. [1] https://github.com/git/git/blob/df3c41adeb/sequencer.c#L86 ff. Bug: 513726 Change-Id: I885a2b7f10d6c74460a8693aa6cbf867ee0494a1 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
This commit is contained in:
parent
92158af52e
commit
035d24097d
|
@ -2927,8 +2927,8 @@ public String modifyCommitMessage(String commit) {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRebaseInteractiveFixupWithBlankLines() throws Exception {
|
||||
private void simpleFixup(String firstMessage, String secondMessage)
|
||||
throws Exception {
|
||||
// create file1 on master
|
||||
writeTrashFile(FILE1, FILE1);
|
||||
git.add().addFilepattern(FILE1).call();
|
||||
|
@ -2938,13 +2938,13 @@ public void testRebaseInteractiveFixupWithBlankLines() throws Exception {
|
|||
// create file2 on master
|
||||
writeTrashFile("file2", "file2");
|
||||
git.add().addFilepattern("file2").call();
|
||||
git.commit().setMessage("Add file2").call();
|
||||
git.commit().setMessage(firstMessage).call();
|
||||
assertTrue(new File(db.getWorkTree(), "file2").exists());
|
||||
|
||||
// update FILE1 on master
|
||||
writeTrashFile(FILE1, "blah");
|
||||
git.add().addFilepattern(FILE1).call();
|
||||
git.commit().setMessage("updated file1 on master\n\nsome text").call();
|
||||
git.commit().setMessage(secondMessage).call();
|
||||
|
||||
git.rebase().setUpstream("HEAD~2")
|
||||
.runInteractively(new InteractiveHandler() {
|
||||
|
@ -2968,9 +2968,31 @@ public String modifyCommitMessage(String commit) {
|
|||
try (RevWalk walk = new RevWalk(db)) {
|
||||
ObjectId headId = db.resolve(Constants.HEAD);
|
||||
RevCommit headCommit = walk.parseCommit(headId);
|
||||
assertEquals("Add file2",
|
||||
headCommit.getFullMessage());
|
||||
assertEquals(firstMessage, headCommit.getFullMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRebaseInteractiveFixupWithBlankLines() throws Exception {
|
||||
simpleFixup("Add file2", "updated file1 on master\n\nsome text");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRebaseInteractiveFixupWithBlankLines2() throws Exception {
|
||||
simpleFixup("Add file2\n\nBody\n",
|
||||
"updated file1 on master\n\nsome text");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRebaseInteractiveFixupWithHash() throws Exception {
|
||||
simpleFixup("#Add file2", "updated file1 on master");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRebaseInteractiveFixupWithHash2() throws Exception {
|
||||
simpleFixup("#Add file2\n\nHeader has hash\n",
|
||||
"#updated file1 on master");
|
||||
}
|
||||
|
||||
@Test(expected = InvalidRebaseStepException.class)
|
||||
|
|
|
@ -466,12 +466,23 @@ private RebaseResult processStep(RebaseTodoLine step, boolean shouldPick)
|
|||
resetSoftToParent();
|
||||
List<RebaseTodoLine> steps = repo.readRebaseTodo(
|
||||
rebaseState.getPath(GIT_REBASE_TODO), false);
|
||||
RebaseTodoLine nextStep = steps.isEmpty() ? null : steps.get(0);
|
||||
boolean isLast = steps.isEmpty();
|
||||
if (!isLast) {
|
||||
switch (steps.get(0).getAction()) {
|
||||
case FIXUP:
|
||||
case SQUASH:
|
||||
break;
|
||||
default:
|
||||
isLast = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
File messageFixupFile = rebaseState.getFile(MESSAGE_FIXUP);
|
||||
File messageSquashFile = rebaseState.getFile(MESSAGE_SQUASH);
|
||||
if (isSquash && messageFixupFile.exists())
|
||||
if (isSquash && messageFixupFile.exists()) {
|
||||
messageFixupFile.delete();
|
||||
newHead = doSquashFixup(isSquash, commitToPick, nextStep,
|
||||
}
|
||||
newHead = doSquashFixup(isSquash, commitToPick, isLast,
|
||||
messageFixupFile, messageSquashFile);
|
||||
}
|
||||
return null;
|
||||
|
@ -732,7 +743,7 @@ private void checkSteps(List<RebaseTodoLine> steps)
|
|||
}
|
||||
|
||||
private RevCommit doSquashFixup(boolean isSquash, RevCommit commitToPick,
|
||||
RebaseTodoLine nextStep, File messageFixup, File messageSquash)
|
||||
boolean isLast, File messageFixup, File messageSquash)
|
||||
throws IOException, GitAPIException {
|
||||
|
||||
if (!messageSquash.exists()) {
|
||||
|
@ -742,24 +753,20 @@ private RevCommit doSquashFixup(boolean isSquash, RevCommit commitToPick,
|
|||
|
||||
initializeSquashFixupFile(MESSAGE_SQUASH,
|
||||
previousCommit.getFullMessage());
|
||||
if (!isSquash)
|
||||
initializeSquashFixupFile(MESSAGE_FIXUP,
|
||||
if (!isSquash) {
|
||||
rebaseState.createFile(MESSAGE_FIXUP,
|
||||
previousCommit.getFullMessage());
|
||||
}
|
||||
String currSquashMessage = rebaseState
|
||||
.readFile(MESSAGE_SQUASH);
|
||||
}
|
||||
String currSquashMessage = rebaseState.readFile(MESSAGE_SQUASH);
|
||||
|
||||
int count = parseSquashFixupSequenceCount(currSquashMessage) + 1;
|
||||
|
||||
String content = composeSquashMessage(isSquash,
|
||||
commitToPick, currSquashMessage, count);
|
||||
rebaseState.createFile(MESSAGE_SQUASH, content);
|
||||
if (messageFixup.exists())
|
||||
rebaseState.createFile(MESSAGE_FIXUP, content);
|
||||
|
||||
return squashIntoPrevious(
|
||||
!messageFixup.exists(),
|
||||
nextStep);
|
||||
return squashIntoPrevious(!messageFixup.exists(), isLast);
|
||||
}
|
||||
|
||||
private void resetSoftToParent() throws IOException,
|
||||
|
@ -781,29 +788,26 @@ private void resetSoftToParent() throws IOException,
|
|||
}
|
||||
|
||||
private RevCommit squashIntoPrevious(boolean sequenceContainsSquash,
|
||||
RebaseTodoLine nextStep)
|
||||
boolean isLast)
|
||||
throws IOException, GitAPIException {
|
||||
RevCommit retNewHead;
|
||||
String commitMessage = rebaseState
|
||||
.readFile(MESSAGE_SQUASH);
|
||||
|
||||
String commitMessage;
|
||||
if (!isLast || sequenceContainsSquash) {
|
||||
commitMessage = rebaseState.readFile(MESSAGE_SQUASH);
|
||||
} else {
|
||||
commitMessage = rebaseState.readFile(MESSAGE_FIXUP);
|
||||
}
|
||||
try (Git git = new Git(repo)) {
|
||||
if (nextStep == null || ((nextStep.getAction() != Action.FIXUP)
|
||||
&& (nextStep.getAction() != Action.SQUASH))) {
|
||||
// this is the last step in this sequence
|
||||
if (isLast) {
|
||||
if (sequenceContainsSquash) {
|
||||
commitMessage = editCommitMessage(commitMessage,
|
||||
CleanupMode.STRIP);
|
||||
} else {
|
||||
commitMessage = CommitConfig.cleanText(commitMessage,
|
||||
CleanupMode.STRIP, '#');
|
||||
}
|
||||
retNewHead = git.commit()
|
||||
.setMessage(commitMessage)
|
||||
.setAmend(true).setNoVerify(true).call();
|
||||
rebaseState.getFile(MESSAGE_SQUASH).delete();
|
||||
rebaseState.getFile(MESSAGE_FIXUP).delete();
|
||||
|
||||
} else {
|
||||
// Next step is either Squash or Fixup
|
||||
retNewHead = git.commit().setMessage(commitMessage)
|
||||
|
|
Loading…
Reference in New Issue