}
@Test
public void testComplexHistoryAnnotate() throws Exception {
HgRepository repo = Configuration.get().find("test-annotate");
HgDataFile df = repo.getFileNode("file1");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DiffOutInspector dump = new DiffOutInspector(new PrintStream(bos));
HgDiffCommand diffCmd = new HgDiffCommand(repo);
diffCmd.file(df).range(0, TIP).order(OldToNew);
diffCmd.executeAnnotate(dump);
LinkedList<String> apiResult = new LinkedList<String>(Arrays.asList(splitLines(bos.toString())));
/*
* FIXME this is an ugly hack to deal with the way `hg diff -c <mergeRev>` describes the change
* and our merge handling approach. For merged revision m, and lines changed both in p1 and p2
* we report lines from p2 as pure additions, regardless of intersecting p1 changes (which
* are reported as deletions, if no sufficient changed lines in m found)
* So, here we try to combine deletion that follows a change (based on identical insertionPoint)
* into a single change
* To fix, need to find better approach to find out reference info (i.e. `hg diff -c` is flawed in this case,
* as it uses first parent only).
*/
Pattern fix = Pattern.compile("@@ -(\\d+),(\\d+) \\+(\\d+),(\\d+) @@");
int v1, v2, v3, v4;
v1 = v2 = v3 = v4 = -1;
for (ListIterator<String> it = apiResult.listIterator(); it.hasNext();) {
String n = it.next();
Matcher m = fix.matcher(n);
if (m.find()) {
int d1 = Integer.parseInt(m.group(1));
int d2 = Integer.parseInt(m.group(2));
int d3 = Integer.parseInt(m.group(3));
int d4 = Integer.parseInt(m.group(4));
if (v1 == d1 && d4 == 0) {
it.previous(); // shift to current element
it.previous(); // to real previous
it.remove();
it.next();
it.set(String.format("@@ -%d,%d +%d,%d @@", v1, v2+d2, v3, v4));
}
v1 = d1;
v2 = d2;
v3 = d3;
v4 = d4;
}
}
LineGrepOutputParser gp = new LineGrepOutputParser("^@@.+");
ExecHelper eh = new ExecHelper(gp, repo.getWorkingDir());
for (int cs : dump.getReportedTargetRevisions()) {
gp.reset();
eh.run("hg", "diff", "-c", String.valueOf(cs), "-U", "0", df.getPath().toString());
for (String expected : splitLines(gp.result())) {
if (!apiResult.remove(expected)) {
errorCollector.fail(String.format("Expected diff output '%s' for changes in revision %d", expected, cs));
}
}