# # patch "ChangeLog" # from [83de8f650b69109fed31390b06c3e9abf390f387] # to [9f24ec7b811bf80f0b0525a7e6fa091d126c3c7f] # # patch "diff_patch.cc" # from [cbb7be193c75e6716d896a21e1e98ed2f53db348] # to [bc9388bcdf8df0fac37f52aa7a8e0b8b8f94d247] # # patch "tests/t_merge_6.at" # from [b164c34e148c527df216a29d3e9126f52876e5ff] # to [477e2620ce0ac0a34a428d5e0ba384427c0c4848] # --- ChangeLog +++ ChangeLog @@ -1,3 +1,9 @@ +2005-05-01 Matt Johnston + + * diff_patch.cc (normalize_extents): broaden the condition when + changes can be normalised. + * tests/t_merge_6.at: now passes. + 2005-05-01 Emile Snyder * annotate.cc: Fix bug that njs pointed out when a merge has one --- diff_patch.cc +++ diff_patch.cc @@ -184,40 +184,40 @@ while (j > 0 && (a_b_map.at(j-1).type == preserved) && (a_b_map.at(j).type == changed) - && (a.at(j) == a.at(j-1)) - && (b.at(a_b_map.at(j-1).pos) == - b.at(a_b_map.at(j).pos + a_b_map.at(j).len - 1))) + && (a.at(j) == b.at(a_b_map.at(j).pos + a_b_map.at(j).len - 1))) { + // This is implied by (a_b_map.at(j-1).type == preserved) + I(a.at(j-1) == b.at(a_b_map.at(j-1).pos)); + // Coming into loop we have: + // i + // z --pres--> z 0 + // o --pres--> o 1 + // a --chng--> a 2 The important thing here is that 'a' in + // t the LHS matches with ... + // u + // v + // a ... the a on the RHS here. Hence we can + // q --pres--> q 3 'shift' the entire 'changed' block + // e --chng--> d 4 upwards, leaving a 'preserved' line + // g --pres--> g 5 'a'->'a' // - // Coming into this loop, we've identified this situation: + // Want to end up with: + // i + // z --pres--> z 0 + // o --chng--> o 1 + // a + // t + // u + // v + // a --pres--> a 2 + // q --pres--> q 3 + // e --chng--> d 4 + // g --pres--> g 5 // - // A B - // -------- ---------------- - // j-1: foo --preserved--> mapped[j-1]: foo - // j: foo --changed----> mapped[ j]: bar - // foo - // - // The normalization we want to perform is to move all - // "changed" extents to the earliest possible position which - // still causes the same B image to be produced. - // - // A B - // -------- ---------------- - // j-1: foo --changed----> mapped[j-1]: foo - // bar - // j: foo --preserved--> mapped[ j]: foo - // + // Now all the 'changed' extents are normalised to the + // earliest possible position. - // This code is almost untested, because we've only been able to - // find one test case that exercises it! Maybe this text will - // make us look bad when/if someone discovers it, but better to - // have a bad reputation and good software than vice-versa. - W(F("You've found files that trigger a strange edge-case of the merge logic.\n")); - W(F("We believe it works, but don't have many tests; so, if you could send us\n")); - W(F("a note, and, if possible, the files that triggered it for inclusion in our\n")); - W(F("test suite, we'd appreciate it. Address: " PACKAGE_BUGREPORT ". Thanks!\n")); - L(F("exchanging preserved extent [%d+%d] with changed extent [%d+%d]\n") % a_b_map.at(j-1).pos % a_b_map.at(j-1).len --- tests/t_merge_6.at +++ tests/t_merge_6.at @@ -1,14 +1,11 @@ AT_SETUP([test a merge 6]) MONOTONE_SETUP -# This test is a bug report. -AT_XFAIL_IF(true) +NEED_UNB64 -NEED_UNB64 +# This tests a case where file normalisation previously wasn't +# working correctly, leading to: -# Another real merge error. This is the diff between the correct -# result and the file produced by the merge: -# # --- correct Thu Apr 28 15:38:27 2005 # +++ testfile Thu Apr 28 15:38:36 2005 # @@ -5,6 +5,10 @@ @@ -23,9 +20,7 @@ # d # g -# merge(1) can handle this merge correctly. Experimenting with the input files, -# it seems that the second 'a' character in the left and right files has some -# importance. +# merge(1) can handle this merge correctly. AT_DATA(parent, [ o