# HG changeset patch # User Denis Laxalde # Date 1499255693 -7200 # Node ID b2670290eab48cbe7497442a674c6b00ae8bd14b # Parent 634b259079c55e5dc3aaaad38c3c73f87611d0be followlines: join merge parents line ranges in blockdescendants() (issue5595) In blockdescendants(), we had an assertion when line range of a merge changeset was not consistent depending on which parent was considered for computation. For instance, this might occur when file content (in lookup range) is significantly different between parent branches of the merge as demonstrated in added tests (where we almost completely rewrite the "baz" file while also introducing similarities with its content in the other branch we later merge to). Now, in such case, we combine line ranges from all parents by storing the envelope of both line ranges. This is conservative (the line range is extended, possibly unnecessarily) but at least this should avoid missing descendants with changes in a range that would fall in that of one parent but not in another one (the case of "baz: narrow change (2->2+)" changeset in tests). diff -r 634b259079c5 -r b2670290eab4 mercurial/dagop.py --- a/mercurial/dagop.py Tue Jul 04 22:35:52 2017 -0700 +++ b/mercurial/dagop.py Wed Jul 05 13:54:53 2017 +0200 @@ -287,12 +287,13 @@ continue inrangep, linerange1 = _changesrange(c, p, linerange2, diffopts) inrange = inrange or inrangep - # If revision 'i' has been seen (it's a merge), we assume that its - # line range is the same independently of which parents was used - # to compute it. - assert i not in seen or seen[i][1] == linerange1, ( - 'computed line range for %s is not consistent between ' - 'ancestor branches' % c) + # If revision 'i' has been seen (it's a merge) and the line range + # previously computed differs from the one we just got, we take the + # surrounding interval. This is conservative but avoids loosing + # information. + if i in seen and seen[i][1] != linerange1: + lbs, ubs = zip(linerange1, seen[i][1]) + linerange1 = min(lbs), max(ubs) seen[i] = c, linerange1 if inrange: yield c, linerange1 diff -r 634b259079c5 -r b2670290eab4 tests/test-annotate.t --- a/tests/test-annotate.t Tue Jul 04 22:35:52 2017 -0700 +++ b/tests/test-annotate.t Wed Jul 05 13:54:53 2017 +0200 @@ -725,6 +725,65 @@ | ~ +Issue5595: on a merge changeset with different line ranges depending on +parent, be conservative and use the surrounding interval to avoid loosing +track of possible further descendants in specified range. + + $ hg up 23 --quiet + $ hg cat baz -r 24 + 0 + 0 + 1 baz:1 + 2 baz:2 + 3+ baz:3 + 4 baz:4 + 5 + 6 + $ cat > baz << EOF + > 0 + > 0 + > a + > b + > 3+ baz:3 + > 4 baz:4 + > y + > z + > EOF + $ hg ci -m 'baz: mostly rewrite with some content from 24' + created new head + $ hg merge --tool :merge-other 24 + merging baz + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg ci -m 'merge forgetting about baz rewrite' + $ cat > baz << EOF + > 0 + > 0 + > 1 baz:1 + > 2+ baz:2 + > 3+ baz:3 + > 4 baz:4 + > 5 + > 6 + > EOF + $ hg ci -m 'baz: narrow change (2->2+)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:4, startrev=20, descend=True)' --graph + @ 33: baz: narrow change (2->2+) + | + o 32: merge forgetting about baz rewrite + |\ + | o 31: baz: mostly rewrite with some content from 24 + | : + | : o 30: baz:3->+3 + | :/ + +---o 27: baz:3+->3- + | : + o : 24: baz:3->3+ + :/ + o 20: baz:4 + |\ + ~ ~ + check error cases $ hg up 24 --quiet $ hg log -r 'followlines()'