Issue being fixed here: hg branches incorrectly renders inactive multiheaded
branches as active if they have closed heads.
Example:
$ hg log --template '{rev}:{node|short} "{desc}" ({branch}) [parents: {parents}]\n' 4:2e2fa7af8357 "merge" (default) [parents: 0:c94e548c8c7d 3:7be622ae5832 ] 3:7be622ae5832 "2" (somebranch) [parents: 1:81c1d9458987 ] 2:be82cf30409c "close" (somebranch) [parents: ] 1:81c1d9458987 "1" (somebranch) [parents: ] 0:c94e548c8c7d "initial" (default) [parents: ] $ hg branches default 4:2e2fa7af8357 somebranch 3:7be622ae5832
Branch somebranch have two heads, the 1st one being closed (rev 2) and
the other one being merged into default (rev 3). This branch should be shown as
inactive one.
This happens because we intersect branch heads with repo heads to check branch
activity. In this case intersection in a set with one node (rev 2). This head
is closed but the branch is marked as active nevertheless.
Fix is to check branch activity by intersecting only open heads set.
Fixed output:
$ hg branches default 4:2e2fa7af8357 somebranch 3:7be622ae5832 (inactive)
Relevant tests for multihead branches added to test-branches suite.
Implentation note about adding iteropen method:
At first I have tried to modify iterbranches is such a way that it would
filter out closed heads itself. For example it could have closed=False
parameter. But in this case we would have to filter closed tips as well.
Reasoning in terms of hg branches we actually are not allowed to do this.
Also, we need to do heads filtering only if tip is not closed itself. But if it
is - we are ok to skip filtering, because branch is already known to be inactive.
So we can't implement heads filtering in iterbranches in elegant way, because
we will end up with something like closed_heads=False or even
closed_heads_is_tip_is_open. Finally I decided to move this logic to the
branches function, adding iteropen helper method.
iterbranches() could have closed=False option to filter out
closed heads, but in which case, the tip would have to follow
it as well.
I'm not sure which will be a better API.