Browse Source

blame: Fix merges, where merge result differs only by whitespace

When blaming a merge commit with "Ignore whitespace changes" enabled,
don't discard blame candidates for other parents when we encounter a
parent that only has whitespace changes compared to the merge result.

The algorithm early prepares parents for blaming, removing the
appropriate blame regions from the list of regions still to blame. Only
at the end, the prepared blame candidates are submitted for blaming.

When looking at a non-first parent which only differs in whitespace to
the merge result, it submitted that parent, but only to blame it for the
(usually few) lines not already prepared to blame on other parents. Due
to an early return the blame candidates for the previous parents were
forgotten, leaving many lines unannotated.

bug: 433024
Change-Id: I43c9caf2078b92b05e652dbed2192568907bf199
Signed-off-by: Konrad Kügler <swamblumat-eclipsebugs@yahoo.de>
stable-3.4
Konrad Kügler 11 years ago
parent
commit
c2fb432cde
  1. 31
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BlameCommandTest.java
  2. 5
      org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java

31
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BlameCommandTest.java

@ -47,8 +47,10 @@ import static org.junit.Assert.assertNotNull;
import java.io.File;
import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
import org.eclipse.jgit.api.ResetCommand.ResetType;
import org.eclipse.jgit.blame.BlameResult;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.CoreConfig.AutoCRLF;
@ -456,4 +458,33 @@ public class BlameCommandTest extends RepositoryTestCase {
assertEquals(merge, lines.getSourceCommit(3));
assertEquals(base, lines.getSourceCommit(4));
}
@Test
public void testWhitespaceMerge() throws Exception {
Git git = new Git(db);
RevCommit base = commitFile("file.txt", join("0", "1", "2"), "master");
RevCommit side = commitFile("file.txt", join("0", "1", " 2 side "),
"side");
checkoutBranch("refs/heads/master");
git.merge().setFastForward(FastForwardMode.NO_FF).include(side).call();
// change whitespace, so the merge content is not identical to side, but
// is the same when ignoring whitespace
writeTrashFile("file.txt", join("0", "1", "2 side"));
RevCommit merge = git.commit().setAll(true).setMessage("merge")
.setAmend(true)
.call();
BlameCommand command = new BlameCommand(db);
command.setFilePath("file.txt")
.setTextComparator(RawTextComparator.WS_IGNORE_ALL)
.setStartCommit(merge.getId());
BlameResult lines = command.call();
assertEquals(3, lines.getResultContents().size());
assertEquals(base, lines.getSourceCommit(0));
assertEquals(base, lines.getSourceCommit(1));
assertEquals(side, lines.getSourceCommit(2));
}
}

5
org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java

@ -768,8 +768,9 @@ public class BlameGenerator {
}
p.regionList = n.regionList;
push(p);
return false;
n.regionList = null;
parents[pIdx] = p;
break;
}
p.takeBlame(editList, n);

Loading…
Cancel
Save