Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/branchmap.py @ 34091:abf91c4f9608
branches: correctly show inactive multiheaded branches
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.
Differential Revision: https://phab.mercurial-scm.org/D583
author | the31k <the31k@thethirty.one> |
---|---|
date | Thu, 31 Aug 2017 18:24:08 +0300 |
parents | 1814ca418b30 |
children | d0db41af73c0 |
comparison
equal
deleted
inserted
replaced
34090:7bbc4e113e5f | 34091:abf91c4f9608 |
---|---|
209 '''Return the tipmost open head on branch head, otherwise return the | 209 '''Return the tipmost open head on branch head, otherwise return the |
210 tipmost closed head on branch. | 210 tipmost closed head on branch. |
211 Raise KeyError for unknown branch.''' | 211 Raise KeyError for unknown branch.''' |
212 return self._branchtip(self[branch])[0] | 212 return self._branchtip(self[branch])[0] |
213 | 213 |
214 def iteropen(self, nodes): | |
215 return (n for n in nodes if n not in self._closednodes) | |
216 | |
214 def branchheads(self, branch, closed=False): | 217 def branchheads(self, branch, closed=False): |
215 heads = self[branch] | 218 heads = self[branch] |
216 if not closed: | 219 if not closed: |
217 heads = [h for h in heads if h not in self._closednodes] | 220 heads = list(self.iteropen(heads)) |
218 return heads | 221 return heads |
219 | 222 |
220 def iterbranches(self): | 223 def iterbranches(self): |
221 for bn, heads in self.iteritems(): | 224 for bn, heads in self.iteritems(): |
222 yield (bn, heads) + self._branchtip(heads) | 225 yield (bn, heads) + self._branchtip(heads) |