mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 08:47:12 +03:00
27daecb480
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
932 lines
31 KiB
Perl
932 lines
31 KiB
Perl
$ hg init a
|
|
$ cd a
|
|
|
|
Verify checking branch of nullrev before the cache is created doesnt crash
|
|
$ hg log -r 'branch(.)' -T '{branch}\n'
|
|
|
|
Basic test
|
|
$ echo 'root' >root
|
|
$ hg add root
|
|
$ hg commit -d '0 0' -m "Adding root node"
|
|
|
|
$ echo 'a' >a
|
|
$ hg add a
|
|
$ hg branch a
|
|
marked working directory as branch a
|
|
(branches are permanent and global, did you want a bookmark?)
|
|
$ hg commit -d '1 0' -m "Adding a branch"
|
|
|
|
$ hg branch q
|
|
marked working directory as branch q
|
|
$ echo 'aa' >a
|
|
$ hg branch -C
|
|
reset working directory to branch a
|
|
$ hg commit -d '2 0' -m "Adding to a branch"
|
|
|
|
$ hg update -C 0
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ echo 'b' >b
|
|
$ hg add b
|
|
$ hg branch b
|
|
marked working directory as branch b
|
|
$ hg commit -d '2 0' -m "Adding b branch"
|
|
|
|
$ echo 'bh1' >bh1
|
|
$ hg add bh1
|
|
$ hg commit -d '3 0' -m "Adding b branch head 1"
|
|
|
|
$ hg update -C 2
|
|
1 files updated, 0 files merged, 2 files removed, 0 files unresolved
|
|
$ echo 'bh2' >bh2
|
|
$ hg add bh2
|
|
$ hg commit -d '4 0' -m "Adding b branch head 2"
|
|
|
|
$ echo 'c' >c
|
|
$ hg add c
|
|
$ hg branch c
|
|
marked working directory as branch c
|
|
$ hg commit -d '5 0' -m "Adding c branch"
|
|
|
|
reserved names
|
|
|
|
$ hg branch tip
|
|
abort: the name 'tip' is reserved
|
|
[255]
|
|
$ hg branch null
|
|
abort: the name 'null' is reserved
|
|
[255]
|
|
$ hg branch .
|
|
abort: the name '.' is reserved
|
|
[255]
|
|
|
|
invalid characters
|
|
|
|
$ hg branch 'foo:bar'
|
|
abort: ':' cannot be used in a name
|
|
[255]
|
|
|
|
$ hg branch 'foo
|
|
> bar'
|
|
abort: '\n' cannot be used in a name
|
|
[255]
|
|
|
|
trailing or leading spaces should be stripped before testing duplicates
|
|
|
|
$ hg branch 'b '
|
|
abort: a branch of the same name already exists
|
|
(use 'hg update' to switch to it)
|
|
[255]
|
|
|
|
$ hg branch ' b'
|
|
abort: a branch of the same name already exists
|
|
(use 'hg update' to switch to it)
|
|
[255]
|
|
|
|
verify update will accept invalid legacy branch names
|
|
|
|
$ hg init test-invalid-branch-name
|
|
$ cd test-invalid-branch-name
|
|
$ hg pull -u "$TESTDIR"/bundles/test-invalid-branch-name.hg
|
|
pulling from *test-invalid-branch-name.hg (glob)
|
|
requesting all changes
|
|
adding changesets
|
|
adding manifests
|
|
adding file changes
|
|
added 3 changesets with 3 changes to 2 files
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
|
|
$ hg update '"colon:test"'
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
$ cd ..
|
|
|
|
$ echo 'd' >d
|
|
$ hg add d
|
|
$ hg branch 'a branch name much longer than the default justification used by branches'
|
|
marked working directory as branch a branch name much longer than the default justification used by branches
|
|
$ hg commit -d '6 0' -m "Adding d branch"
|
|
|
|
$ hg branches
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
b 4:aee39cd168d0
|
|
c 6:589736a22561 (inactive)
|
|
a 5:d8cbc61dbaa6 (inactive)
|
|
default 0:19709c5a4e75 (inactive)
|
|
|
|
-------
|
|
|
|
$ hg branches -a
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
b 4:aee39cd168d0
|
|
|
|
--- Branch a
|
|
|
|
$ hg log -b a
|
|
changeset: 5:d8cbc61dbaa6
|
|
branch: a
|
|
parent: 2:881fe2b92ad0
|
|
user: test
|
|
date: Thu Jan 01 00:00:04 1970 +0000
|
|
summary: Adding b branch head 2
|
|
|
|
changeset: 2:881fe2b92ad0
|
|
branch: a
|
|
user: test
|
|
date: Thu Jan 01 00:00:02 1970 +0000
|
|
summary: Adding to a branch
|
|
|
|
changeset: 1:dd6b440dd85a
|
|
branch: a
|
|
user: test
|
|
date: Thu Jan 01 00:00:01 1970 +0000
|
|
summary: Adding a branch
|
|
|
|
|
|
---- Branch b
|
|
|
|
$ hg log -b b
|
|
changeset: 4:aee39cd168d0
|
|
branch: b
|
|
user: test
|
|
date: Thu Jan 01 00:00:03 1970 +0000
|
|
summary: Adding b branch head 1
|
|
|
|
changeset: 3:ac22033332d1
|
|
branch: b
|
|
parent: 0:19709c5a4e75
|
|
user: test
|
|
date: Thu Jan 01 00:00:02 1970 +0000
|
|
summary: Adding b branch
|
|
|
|
|
|
---- going to test branch closing
|
|
|
|
$ hg branches
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
b 4:aee39cd168d0
|
|
c 6:589736a22561 (inactive)
|
|
a 5:d8cbc61dbaa6 (inactive)
|
|
default 0:19709c5a4e75 (inactive)
|
|
$ hg up -C b
|
|
2 files updated, 0 files merged, 4 files removed, 0 files unresolved
|
|
$ echo 'xxx1' >> b
|
|
$ hg commit -d '7 0' -m 'adding cset to branch b'
|
|
$ hg up -C aee39cd168d0
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
$ echo 'xxx2' >> b
|
|
$ hg commit -d '8 0' -m 'adding head to branch b'
|
|
created new head
|
|
$ echo 'xxx3' >> b
|
|
$ hg commit -d '9 0' -m 'adding another cset to branch b'
|
|
$ hg branches
|
|
b 10:bfbe841b666e
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
c 6:589736a22561 (inactive)
|
|
a 5:d8cbc61dbaa6 (inactive)
|
|
default 0:19709c5a4e75 (inactive)
|
|
$ hg heads --closed
|
|
changeset: 10:bfbe841b666e
|
|
branch: b
|
|
tag: tip
|
|
user: test
|
|
date: Thu Jan 01 00:00:09 1970 +0000
|
|
summary: adding another cset to branch b
|
|
|
|
changeset: 8:eebb944467c9
|
|
branch: b
|
|
parent: 4:aee39cd168d0
|
|
user: test
|
|
date: Thu Jan 01 00:00:07 1970 +0000
|
|
summary: adding cset to branch b
|
|
|
|
changeset: 7:10ff5895aa57
|
|
branch: a branch name much longer than the default justification used by branches
|
|
user: test
|
|
date: Thu Jan 01 00:00:06 1970 +0000
|
|
summary: Adding d branch
|
|
|
|
changeset: 6:589736a22561
|
|
branch: c
|
|
user: test
|
|
date: Thu Jan 01 00:00:05 1970 +0000
|
|
summary: Adding c branch
|
|
|
|
changeset: 5:d8cbc61dbaa6
|
|
branch: a
|
|
parent: 2:881fe2b92ad0
|
|
user: test
|
|
date: Thu Jan 01 00:00:04 1970 +0000
|
|
summary: Adding b branch head 2
|
|
|
|
changeset: 0:19709c5a4e75
|
|
user: test
|
|
date: Thu Jan 01 00:00:00 1970 +0000
|
|
summary: Adding root node
|
|
|
|
$ hg heads
|
|
changeset: 10:bfbe841b666e
|
|
branch: b
|
|
tag: tip
|
|
user: test
|
|
date: Thu Jan 01 00:00:09 1970 +0000
|
|
summary: adding another cset to branch b
|
|
|
|
changeset: 8:eebb944467c9
|
|
branch: b
|
|
parent: 4:aee39cd168d0
|
|
user: test
|
|
date: Thu Jan 01 00:00:07 1970 +0000
|
|
summary: adding cset to branch b
|
|
|
|
changeset: 7:10ff5895aa57
|
|
branch: a branch name much longer than the default justification used by branches
|
|
user: test
|
|
date: Thu Jan 01 00:00:06 1970 +0000
|
|
summary: Adding d branch
|
|
|
|
changeset: 6:589736a22561
|
|
branch: c
|
|
user: test
|
|
date: Thu Jan 01 00:00:05 1970 +0000
|
|
summary: Adding c branch
|
|
|
|
changeset: 5:d8cbc61dbaa6
|
|
branch: a
|
|
parent: 2:881fe2b92ad0
|
|
user: test
|
|
date: Thu Jan 01 00:00:04 1970 +0000
|
|
summary: Adding b branch head 2
|
|
|
|
changeset: 0:19709c5a4e75
|
|
user: test
|
|
date: Thu Jan 01 00:00:00 1970 +0000
|
|
summary: Adding root node
|
|
|
|
$ hg commit -d '9 0' --close-branch -m 'prune bad branch'
|
|
$ hg branches -a
|
|
b 8:eebb944467c9
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
$ hg up -C b
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
$ hg commit -d '9 0' --close-branch -m 'close this part branch too'
|
|
$ hg commit -d '9 0' --close-branch -m 're-closing this branch'
|
|
abort: can only close branch heads
|
|
[255]
|
|
|
|
$ hg log -r tip --debug
|
|
changeset: 12:e3d49c0575d8fc2cb1cd6859c747c14f5f6d499f
|
|
branch: b
|
|
tag: tip
|
|
phase: draft
|
|
parent: 8:eebb944467c9fb9651ed232aeaf31b3c0a7fc6c1
|
|
parent: -1:0000000000000000000000000000000000000000
|
|
manifest: 8:6f9ed32d2b310e391a4f107d5f0f071df785bfee
|
|
user: test
|
|
date: Thu Jan 01 00:00:09 1970 +0000
|
|
extra: branch=b
|
|
extra: close=1
|
|
description:
|
|
close this part branch too
|
|
|
|
|
|
--- b branch should be inactive
|
|
|
|
$ hg branches
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
c 6:589736a22561 (inactive)
|
|
a 5:d8cbc61dbaa6 (inactive)
|
|
default 0:19709c5a4e75 (inactive)
|
|
$ hg branches -c
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
b 12:e3d49c0575d8 (closed)
|
|
c 6:589736a22561 (inactive)
|
|
a 5:d8cbc61dbaa6 (inactive)
|
|
default 0:19709c5a4e75 (inactive)
|
|
$ hg branches -a
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
$ hg branches -q
|
|
a branch name much longer than the default justification used by branches
|
|
c
|
|
a
|
|
default
|
|
$ hg heads b
|
|
no open branch heads found on branches b
|
|
[1]
|
|
$ hg heads --closed b
|
|
changeset: 12:e3d49c0575d8
|
|
branch: b
|
|
tag: tip
|
|
parent: 8:eebb944467c9
|
|
user: test
|
|
date: Thu Jan 01 00:00:09 1970 +0000
|
|
summary: close this part branch too
|
|
|
|
changeset: 11:d3f163457ebf
|
|
branch: b
|
|
user: test
|
|
date: Thu Jan 01 00:00:09 1970 +0000
|
|
summary: prune bad branch
|
|
|
|
$ echo 'xxx4' >> b
|
|
$ hg commit -d '9 0' -m 'reopen branch with a change'
|
|
reopening closed branch head 12
|
|
|
|
--- branch b is back in action
|
|
|
|
$ hg branches -a
|
|
b 13:e23b5505d1ad
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
|
|
---- test heads listings
|
|
|
|
$ hg heads
|
|
changeset: 13:e23b5505d1ad
|
|
branch: b
|
|
tag: tip
|
|
user: test
|
|
date: Thu Jan 01 00:00:09 1970 +0000
|
|
summary: reopen branch with a change
|
|
|
|
changeset: 7:10ff5895aa57
|
|
branch: a branch name much longer than the default justification used by branches
|
|
user: test
|
|
date: Thu Jan 01 00:00:06 1970 +0000
|
|
summary: Adding d branch
|
|
|
|
changeset: 6:589736a22561
|
|
branch: c
|
|
user: test
|
|
date: Thu Jan 01 00:00:05 1970 +0000
|
|
summary: Adding c branch
|
|
|
|
changeset: 5:d8cbc61dbaa6
|
|
branch: a
|
|
parent: 2:881fe2b92ad0
|
|
user: test
|
|
date: Thu Jan 01 00:00:04 1970 +0000
|
|
summary: Adding b branch head 2
|
|
|
|
changeset: 0:19709c5a4e75
|
|
user: test
|
|
date: Thu Jan 01 00:00:00 1970 +0000
|
|
summary: Adding root node
|
|
|
|
|
|
branch default
|
|
|
|
$ hg heads default
|
|
changeset: 0:19709c5a4e75
|
|
user: test
|
|
date: Thu Jan 01 00:00:00 1970 +0000
|
|
summary: Adding root node
|
|
|
|
|
|
branch a
|
|
|
|
$ hg heads a
|
|
changeset: 5:d8cbc61dbaa6
|
|
branch: a
|
|
parent: 2:881fe2b92ad0
|
|
user: test
|
|
date: Thu Jan 01 00:00:04 1970 +0000
|
|
summary: Adding b branch head 2
|
|
|
|
$ hg heads --active a
|
|
no open branch heads found on branches a
|
|
[1]
|
|
|
|
branch b
|
|
|
|
$ hg heads b
|
|
changeset: 13:e23b5505d1ad
|
|
branch: b
|
|
tag: tip
|
|
user: test
|
|
date: Thu Jan 01 00:00:09 1970 +0000
|
|
summary: reopen branch with a change
|
|
|
|
$ hg heads --closed b
|
|
changeset: 13:e23b5505d1ad
|
|
branch: b
|
|
tag: tip
|
|
user: test
|
|
date: Thu Jan 01 00:00:09 1970 +0000
|
|
summary: reopen branch with a change
|
|
|
|
changeset: 11:d3f163457ebf
|
|
branch: b
|
|
user: test
|
|
date: Thu Jan 01 00:00:09 1970 +0000
|
|
summary: prune bad branch
|
|
|
|
|
|
reclose branch
|
|
|
|
$ hg up -C c
|
|
3 files updated, 0 files merged, 2 files removed, 0 files unresolved
|
|
$ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
|
|
$ hg branches
|
|
b 13:e23b5505d1ad
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
a 5:d8cbc61dbaa6 (inactive)
|
|
default 0:19709c5a4e75 (inactive)
|
|
$ hg branches --closed
|
|
b 13:e23b5505d1ad
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
c 14:f894c25619d3 (closed)
|
|
a 5:d8cbc61dbaa6 (inactive)
|
|
default 0:19709c5a4e75 (inactive)
|
|
|
|
multihead branch
|
|
|
|
$ hg up -C default
|
|
0 files updated, 0 files merged, 3 files removed, 0 files unresolved
|
|
$ hg branch m
|
|
marked working directory as branch m
|
|
$ touch m
|
|
$ hg add m
|
|
$ hg commit -d '10 0' -m 'multihead base'
|
|
$ echo "m1" >m
|
|
$ hg commit -d '10 0' -m 'head 1'
|
|
$ hg up -C '.^'
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
$ echo "m2" >m
|
|
$ hg commit -d '10 0' -m 'head 2'
|
|
created new head
|
|
$ hg log -b m
|
|
changeset: 17:df343b0df04f
|
|
branch: m
|
|
tag: tip
|
|
parent: 15:f3447637f53e
|
|
user: test
|
|
date: Thu Jan 01 00:00:10 1970 +0000
|
|
summary: head 2
|
|
|
|
changeset: 16:a58ca5d3bdf3
|
|
branch: m
|
|
user: test
|
|
date: Thu Jan 01 00:00:10 1970 +0000
|
|
summary: head 1
|
|
|
|
changeset: 15:f3447637f53e
|
|
branch: m
|
|
parent: 0:19709c5a4e75
|
|
user: test
|
|
date: Thu Jan 01 00:00:10 1970 +0000
|
|
summary: multihead base
|
|
|
|
$ hg heads --topo m
|
|
changeset: 17:df343b0df04f
|
|
branch: m
|
|
tag: tip
|
|
parent: 15:f3447637f53e
|
|
user: test
|
|
date: Thu Jan 01 00:00:10 1970 +0000
|
|
summary: head 2
|
|
|
|
changeset: 16:a58ca5d3bdf3
|
|
branch: m
|
|
user: test
|
|
date: Thu Jan 01 00:00:10 1970 +0000
|
|
summary: head 1
|
|
|
|
$ hg branches
|
|
m 17:df343b0df04f
|
|
b 13:e23b5505d1ad
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
a 5:d8cbc61dbaa6 (inactive)
|
|
default 0:19709c5a4e75 (inactive)
|
|
|
|
partially merge multihead branch
|
|
|
|
$ hg up -C default
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg branch md
|
|
marked working directory as branch md
|
|
$ hg merge m
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
(branch merge, don't forget to commit)
|
|
$ hg commit -d '11 0' -m 'merge head 2'
|
|
$ hg heads --topo m
|
|
changeset: 16:a58ca5d3bdf3
|
|
branch: m
|
|
user: test
|
|
date: Thu Jan 01 00:00:10 1970 +0000
|
|
summary: head 1
|
|
|
|
$ hg branches
|
|
md 18:c914c99f1fbb
|
|
m 17:df343b0df04f
|
|
b 13:e23b5505d1ad
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
a 5:d8cbc61dbaa6 (inactive)
|
|
default 0:19709c5a4e75 (inactive)
|
|
|
|
partially close multihead branch
|
|
|
|
$ hg up -C a58ca5d3bdf3
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
$ hg commit -d '12 0' -m 'close head 1' --close-branch
|
|
$ hg heads --topo m
|
|
changeset: 19:cd21a80baa3d
|
|
branch: m
|
|
tag: tip
|
|
parent: 16:a58ca5d3bdf3
|
|
user: test
|
|
date: Thu Jan 01 00:00:12 1970 +0000
|
|
summary: close head 1
|
|
|
|
$ hg branches
|
|
md 18:c914c99f1fbb
|
|
b 13:e23b5505d1ad
|
|
a branch name much longer than the default justification used by branches 7:10ff5895aa57
|
|
m 17:df343b0df04f (inactive)
|
|
a 5:d8cbc61dbaa6 (inactive)
|
|
default 0:19709c5a4e75 (inactive)
|
|
|
|
default branch colors:
|
|
|
|
$ cat <<EOF >> $HGRCPATH
|
|
> [extensions]
|
|
> color =
|
|
> [color]
|
|
> mode = ansi
|
|
> EOF
|
|
|
|
$ hg up -C b
|
|
2 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ hg branches --color=always
|
|
\x1b[0;0mmd\x1b[0m\x1b[0;33m 18:c914c99f1fbb\x1b[0m (esc)
|
|
\x1b[0;32mb\x1b[0m\x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
|
|
\x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m\x1b[0;33m 7:10ff5895aa57\x1b[0m (esc)
|
|
\x1b[0;0mm\x1b[0m\x1b[0;33m 17:df343b0df04f\x1b[0m (inactive) (esc)
|
|
\x1b[0;0ma\x1b[0m\x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
|
|
\x1b[0;0mdefault\x1b[0m\x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
|
|
|
|
default closed branch color:
|
|
|
|
$ hg branches --color=always --closed
|
|
\x1b[0;0mmd\x1b[0m\x1b[0;33m 18:c914c99f1fbb\x1b[0m (esc)
|
|
\x1b[0;32mb\x1b[0m\x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
|
|
\x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m\x1b[0;33m 7:10ff5895aa57\x1b[0m (esc)
|
|
\x1b[0;0mm\x1b[0m\x1b[0;33m 17:df343b0df04f\x1b[0m (inactive) (esc)
|
|
\x1b[0;30;1mc\x1b[0m\x1b[0;33m 14:f894c25619d3\x1b[0m (closed) (esc)
|
|
\x1b[0;0ma\x1b[0m\x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
|
|
\x1b[0;0mdefault\x1b[0m\x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
|
|
|
|
$ cat <<EOF >> $HGRCPATH
|
|
> [extensions]
|
|
> color =
|
|
> [color]
|
|
> branches.active = green
|
|
> branches.closed = blue
|
|
> branches.current = red
|
|
> branches.inactive = magenta
|
|
> log.changeset = cyan
|
|
> EOF
|
|
|
|
custom branch colors:
|
|
|
|
$ hg branches --color=always
|
|
\x1b[0;32mmd\x1b[0m\x1b[0;36m 18:c914c99f1fbb\x1b[0m (esc)
|
|
\x1b[0;31mb\x1b[0m\x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
|
|
\x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m\x1b[0;36m 7:10ff5895aa57\x1b[0m (esc)
|
|
\x1b[0;35mm\x1b[0m\x1b[0;36m 17:df343b0df04f\x1b[0m (inactive) (esc)
|
|
\x1b[0;35ma\x1b[0m\x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
|
|
\x1b[0;35mdefault\x1b[0m\x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
|
|
|
|
custom closed branch color:
|
|
|
|
$ hg branches --color=always --closed
|
|
\x1b[0;32mmd\x1b[0m\x1b[0;36m 18:c914c99f1fbb\x1b[0m (esc)
|
|
\x1b[0;31mb\x1b[0m\x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
|
|
\x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m\x1b[0;36m 7:10ff5895aa57\x1b[0m (esc)
|
|
\x1b[0;35mm\x1b[0m\x1b[0;36m 17:df343b0df04f\x1b[0m (inactive) (esc)
|
|
\x1b[0;34mc\x1b[0m\x1b[0;36m 14:f894c25619d3\x1b[0m (closed) (esc)
|
|
\x1b[0;35ma\x1b[0m\x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
|
|
\x1b[0;35mdefault\x1b[0m\x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
|
|
|
|
template output:
|
|
|
|
$ hg branches -Tjson --closed
|
|
[
|
|
{
|
|
"active": true,
|
|
"branch": "md",
|
|
"closed": false,
|
|
"current": false,
|
|
"node": "c914c99f1fbb2b1d785a0a939ed3f67275df18e9",
|
|
"rev": 18
|
|
},
|
|
{
|
|
"active": true,
|
|
"branch": "b",
|
|
"closed": false,
|
|
"current": true,
|
|
"node": "e23b5505d1ad24aab6f84fd8c7cb8cd8e5e93be0",
|
|
"rev": 13
|
|
},
|
|
{
|
|
"active": true,
|
|
"branch": "a branch name much longer than the default justification used by branches",
|
|
"closed": false,
|
|
"current": false,
|
|
"node": "10ff5895aa5793bd378da574af8cec8ea408d831",
|
|
"rev": 7
|
|
},
|
|
{
|
|
"active": false,
|
|
"branch": "m",
|
|
"closed": false,
|
|
"current": false,
|
|
"node": "df343b0df04feb2a946cd4b6e9520e552fef14ee",
|
|
"rev": 17
|
|
},
|
|
{
|
|
"active": false,
|
|
"branch": "c",
|
|
"closed": true,
|
|
"current": false,
|
|
"node": "f894c25619d3f1484639d81be950e0a07bc6f1f6",
|
|
"rev": 14
|
|
},
|
|
{
|
|
"active": false,
|
|
"branch": "a",
|
|
"closed": false,
|
|
"current": false,
|
|
"node": "d8cbc61dbaa6dc817175d1e301eecb863f280832",
|
|
"rev": 5
|
|
},
|
|
{
|
|
"active": false,
|
|
"branch": "default",
|
|
"closed": false,
|
|
"current": false,
|
|
"node": "19709c5a4e75bf938f8e349aff97438539bb729e",
|
|
"rev": 0
|
|
}
|
|
]
|
|
|
|
$ hg branches --closed -T '{if(closed, "{branch}\n")}'
|
|
c
|
|
|
|
$ hg branches -T '{word(0, branch)}: {desc|firstline}\n'
|
|
md: merge head 2
|
|
b: reopen branch with a change
|
|
a: Adding d branch
|
|
m: head 2
|
|
a: Adding b branch head 2
|
|
default: Adding root node
|
|
|
|
$ cat <<'EOF' > "$TESTTMP/map-myjson"
|
|
> docheader = '\{\n'
|
|
> docfooter = '\n}\n'
|
|
> separator = ',\n'
|
|
> branches = ' {dict(branch, node|short)|json}'
|
|
> EOF
|
|
$ hg branches -T "$TESTTMP/map-myjson"
|
|
{
|
|
{"branch": "md", "node": "c914c99f1fbb"},
|
|
{"branch": "b", "node": "e23b5505d1ad"},
|
|
{"branch": "a branch *", "node": "10ff5895aa57"}, (glob)
|
|
{"branch": "m", "node": "df343b0df04f"},
|
|
{"branch": "a", "node": "d8cbc61dbaa6"},
|
|
{"branch": "default", "node": "19709c5a4e75"}
|
|
}
|
|
|
|
$ cat <<'EOF' >> .hg/hgrc
|
|
> [templates]
|
|
> myjson = ' {dict(branch, node|short)|json}'
|
|
> myjson:docheader = '\{\n'
|
|
> myjson:docfooter = '\n}\n'
|
|
> myjson:separator = ',\n'
|
|
> EOF
|
|
$ hg branches -T myjson
|
|
{
|
|
{"branch": "md", "node": "c914c99f1fbb"},
|
|
{"branch": "b", "node": "e23b5505d1ad"},
|
|
{"branch": "a branch *", "node": "10ff5895aa57"}, (glob)
|
|
{"branch": "m", "node": "df343b0df04f"},
|
|
{"branch": "a", "node": "d8cbc61dbaa6"},
|
|
{"branch": "default", "node": "19709c5a4e75"}
|
|
}
|
|
|
|
$ cat <<'EOF' >> .hg/hgrc
|
|
> [templates]
|
|
> :docheader = 'should not be selected as a docheader for literal templates\n'
|
|
> EOF
|
|
$ hg branches -T '{branch}\n'
|
|
md
|
|
b
|
|
a branch name much longer than the default justification used by branches
|
|
m
|
|
a
|
|
default
|
|
|
|
Tests of revision branch name caching
|
|
|
|
We rev branch cache is updated automatically. In these tests we use a trick to
|
|
trigger rebuilds. We remove the branch head cache and run 'hg head' to cause a
|
|
rebuild that also will populate the rev branch cache.
|
|
|
|
revision branch cache is created when building the branch head cache
|
|
$ rm -rf .hg/cache; hg head a -T '{rev}\n'
|
|
5
|
|
$ f --hexdump --size .hg/cache/rbc-*
|
|
.hg/cache/rbc-names-v1: size=92
|
|
0000: 64 65 66 61 75 6c 74 00 61 00 62 00 63 00 61 20 |default.a.b.c.a |
|
|
0010: 62 72 61 6e 63 68 20 6e 61 6d 65 20 6d 75 63 68 |branch name much|
|
|
0020: 20 6c 6f 6e 67 65 72 20 74 68 61 6e 20 74 68 65 | longer than the|
|
|
0030: 20 64 65 66 61 75 6c 74 20 6a 75 73 74 69 66 69 | default justifi|
|
|
0040: 63 61 74 69 6f 6e 20 75 73 65 64 20 62 79 20 62 |cation used by b|
|
|
0050: 72 61 6e 63 68 65 73 00 6d 00 6d 64 |ranches.m.md|
|
|
.hg/cache/rbc-revs-v1: size=160
|
|
0000: 19 70 9c 5a 00 00 00 00 dd 6b 44 0d 00 00 00 01 |.p.Z.....kD.....|
|
|
0010: 88 1f e2 b9 00 00 00 01 ac 22 03 33 00 00 00 02 |.........".3....|
|
|
0020: ae e3 9c d1 00 00 00 02 d8 cb c6 1d 00 00 00 01 |................|
|
|
0030: 58 97 36 a2 00 00 00 03 10 ff 58 95 00 00 00 04 |X.6.......X.....|
|
|
0040: ee bb 94 44 00 00 00 02 5f 40 61 bb 00 00 00 02 |...D...._@a.....|
|
|
0050: bf be 84 1b 00 00 00 02 d3 f1 63 45 80 00 00 02 |..........cE....|
|
|
0060: e3 d4 9c 05 80 00 00 02 e2 3b 55 05 00 00 00 02 |.........;U.....|
|
|
0070: f8 94 c2 56 80 00 00 03 f3 44 76 37 00 00 00 05 |...V.....Dv7....|
|
|
0080: a5 8c a5 d3 00 00 00 05 df 34 3b 0d 00 00 00 05 |.........4;.....|
|
|
0090: c9 14 c9 9f 00 00 00 06 cd 21 a8 0b 80 00 00 05 |.........!......|
|
|
|
|
no errors when revbranchcache is not writable
|
|
|
|
$ echo >> .hg/cache/rbc-revs-v1
|
|
$ mv .hg/cache/rbc-revs-v1 .hg/cache/rbc-revs-v1_
|
|
$ mkdir .hg/cache/rbc-revs-v1
|
|
$ rm -f .hg/cache/branch* && hg head a -T '{rev}\n'
|
|
5
|
|
$ rmdir .hg/cache/rbc-revs-v1
|
|
$ mv .hg/cache/rbc-revs-v1_ .hg/cache/rbc-revs-v1
|
|
|
|
no errors when wlock cannot be acquired
|
|
|
|
#if unix-permissions
|
|
$ mv .hg/cache/rbc-revs-v1 .hg/cache/rbc-revs-v1_
|
|
$ rm -f .hg/cache/branch*
|
|
$ chmod 555 .hg
|
|
$ hg head a -T '{rev}\n'
|
|
5
|
|
$ chmod 755 .hg
|
|
$ mv .hg/cache/rbc-revs-v1_ .hg/cache/rbc-revs-v1
|
|
#endif
|
|
|
|
recovery from invalid cache revs file with trailing data
|
|
$ echo >> .hg/cache/rbc-revs-v1
|
|
$ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
|
|
5
|
|
truncating cache/rbc-revs-v1 to 160
|
|
$ f --size .hg/cache/rbc-revs*
|
|
.hg/cache/rbc-revs-v1: size=160
|
|
recovery from invalid cache file with partial last record
|
|
$ mv .hg/cache/rbc-revs-v1 .
|
|
$ f -qDB 119 rbc-revs-v1 > .hg/cache/rbc-revs-v1
|
|
$ f --size .hg/cache/rbc-revs*
|
|
.hg/cache/rbc-revs-v1: size=119
|
|
$ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
|
|
5
|
|
truncating cache/rbc-revs-v1 to 112
|
|
$ f --size .hg/cache/rbc-revs*
|
|
.hg/cache/rbc-revs-v1: size=160
|
|
recovery from invalid cache file with missing record - no truncation
|
|
$ mv .hg/cache/rbc-revs-v1 .
|
|
$ f -qDB 112 rbc-revs-v1 > .hg/cache/rbc-revs-v1
|
|
$ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
|
|
5
|
|
$ f --size .hg/cache/rbc-revs*
|
|
.hg/cache/rbc-revs-v1: size=160
|
|
recovery from invalid cache file with some bad records
|
|
$ mv .hg/cache/rbc-revs-v1 .
|
|
$ f -qDB 8 rbc-revs-v1 > .hg/cache/rbc-revs-v1
|
|
$ f --size .hg/cache/rbc-revs*
|
|
.hg/cache/rbc-revs-v1: size=8
|
|
$ f -qDB 112 rbc-revs-v1 >> .hg/cache/rbc-revs-v1
|
|
$ f --size .hg/cache/rbc-revs*
|
|
.hg/cache/rbc-revs-v1: size=120
|
|
$ hg log -r 'branch(.)' -T '{rev} ' --debug
|
|
history modification detected - truncating revision branch cache to revision 13
|
|
history modification detected - truncating revision branch cache to revision 1
|
|
3 4 8 9 10 11 12 13 truncating cache/rbc-revs-v1 to 8
|
|
$ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
|
|
5
|
|
truncating cache/rbc-revs-v1 to 104
|
|
$ f --size --hexdump --bytes=16 .hg/cache/rbc-revs*
|
|
.hg/cache/rbc-revs-v1: size=160
|
|
0000: 19 70 9c 5a 00 00 00 00 dd 6b 44 0d 00 00 00 01 |.p.Z.....kD.....|
|
|
cache is updated when committing
|
|
$ hg branch i-will-regret-this
|
|
marked working directory as branch i-will-regret-this
|
|
$ hg ci -m regrets
|
|
$ f --size .hg/cache/rbc-*
|
|
.hg/cache/rbc-names-v1: size=111
|
|
.hg/cache/rbc-revs-v1: size=168
|
|
update after rollback - the cache will be correct but rbc-names will will still
|
|
contain the branch name even though it no longer is used
|
|
$ hg up -qr '.^'
|
|
$ hg rollback -qf
|
|
$ f --size --hexdump .hg/cache/rbc-*
|
|
.hg/cache/rbc-names-v1: size=111
|
|
0000: 64 65 66 61 75 6c 74 00 61 00 62 00 63 00 61 20 |default.a.b.c.a |
|
|
0010: 62 72 61 6e 63 68 20 6e 61 6d 65 20 6d 75 63 68 |branch name much|
|
|
0020: 20 6c 6f 6e 67 65 72 20 74 68 61 6e 20 74 68 65 | longer than the|
|
|
0030: 20 64 65 66 61 75 6c 74 20 6a 75 73 74 69 66 69 | default justifi|
|
|
0040: 63 61 74 69 6f 6e 20 75 73 65 64 20 62 79 20 62 |cation used by b|
|
|
0050: 72 61 6e 63 68 65 73 00 6d 00 6d 64 00 69 2d 77 |ranches.m.md.i-w|
|
|
0060: 69 6c 6c 2d 72 65 67 72 65 74 2d 74 68 69 73 |ill-regret-this|
|
|
.hg/cache/rbc-revs-v1: size=160
|
|
0000: 19 70 9c 5a 00 00 00 00 dd 6b 44 0d 00 00 00 01 |.p.Z.....kD.....|
|
|
0010: 88 1f e2 b9 00 00 00 01 ac 22 03 33 00 00 00 02 |.........".3....|
|
|
0020: ae e3 9c d1 00 00 00 02 d8 cb c6 1d 00 00 00 01 |................|
|
|
0030: 58 97 36 a2 00 00 00 03 10 ff 58 95 00 00 00 04 |X.6.......X.....|
|
|
0040: ee bb 94 44 00 00 00 02 5f 40 61 bb 00 00 00 02 |...D...._@a.....|
|
|
0050: bf be 84 1b 00 00 00 02 d3 f1 63 45 80 00 00 02 |..........cE....|
|
|
0060: e3 d4 9c 05 80 00 00 02 e2 3b 55 05 00 00 00 02 |.........;U.....|
|
|
0070: f8 94 c2 56 80 00 00 03 f3 44 76 37 00 00 00 05 |...V.....Dv7....|
|
|
0080: a5 8c a5 d3 00 00 00 05 df 34 3b 0d 00 00 00 05 |.........4;.....|
|
|
0090: c9 14 c9 9f 00 00 00 06 cd 21 a8 0b 80 00 00 05 |.........!......|
|
|
cache is updated/truncated when stripping - it is thus very hard to get in a
|
|
situation where the cache is out of sync and the hash check detects it
|
|
$ hg --config extensions.strip= strip -r tip --nob
|
|
$ f --size .hg/cache/rbc-revs*
|
|
.hg/cache/rbc-revs-v1: size=152
|
|
|
|
cache is rebuilt when corruption is detected
|
|
$ echo > .hg/cache/rbc-names-v1
|
|
$ hg log -r '5:&branch(.)' -T '{rev} ' --debug
|
|
referenced branch names not found - rebuilding revision branch cache from scratch
|
|
8 9 10 11 12 13 truncating cache/rbc-revs-v1 to 40
|
|
$ f --size --hexdump .hg/cache/rbc-*
|
|
.hg/cache/rbc-names-v1: size=84
|
|
0000: 62 00 61 00 63 00 61 20 62 72 61 6e 63 68 20 6e |b.a.c.a branch n|
|
|
0010: 61 6d 65 20 6d 75 63 68 20 6c 6f 6e 67 65 72 20 |ame much longer |
|
|
0020: 74 68 61 6e 20 74 68 65 20 64 65 66 61 75 6c 74 |than the default|
|
|
0030: 20 6a 75 73 74 69 66 69 63 61 74 69 6f 6e 20 75 | justification u|
|
|
0040: 73 65 64 20 62 79 20 62 72 61 6e 63 68 65 73 00 |sed by branches.|
|
|
0050: 6d 00 6d 64 |m.md|
|
|
.hg/cache/rbc-revs-v1: size=152
|
|
0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
|
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
|
0020: 00 00 00 00 00 00 00 00 d8 cb c6 1d 00 00 00 01 |................|
|
|
0030: 58 97 36 a2 00 00 00 02 10 ff 58 95 00 00 00 03 |X.6.......X.....|
|
|
0040: ee bb 94 44 00 00 00 00 5f 40 61 bb 00 00 00 00 |...D...._@a.....|
|
|
0050: bf be 84 1b 00 00 00 00 d3 f1 63 45 80 00 00 00 |..........cE....|
|
|
0060: e3 d4 9c 05 80 00 00 00 e2 3b 55 05 00 00 00 00 |.........;U.....|
|
|
0070: f8 94 c2 56 80 00 00 02 f3 44 76 37 00 00 00 04 |...V.....Dv7....|
|
|
0080: a5 8c a5 d3 00 00 00 04 df 34 3b 0d 00 00 00 04 |.........4;.....|
|
|
0090: c9 14 c9 9f 00 00 00 05 |........|
|
|
|
|
Test that cache files are created and grows correctly:
|
|
|
|
$ rm .hg/cache/rbc*
|
|
$ hg log -r "5 & branch(5)" -T "{rev}\n"
|
|
5
|
|
$ f --size --hexdump .hg/cache/rbc-*
|
|
.hg/cache/rbc-names-v1: size=1
|
|
0000: 61 |a|
|
|
.hg/cache/rbc-revs-v1: size=152
|
|
0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
|
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
|
0020: 00 00 00 00 00 00 00 00 d8 cb c6 1d 00 00 00 00 |................|
|
|
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
|
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
|
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
|
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
|
0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
|
0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
|
0090: 00 00 00 00 00 00 00 00 |........|
|
|
|
|
$ cd ..
|
|
|
|
Test for multiple incorrect branch cache entries:
|
|
|
|
$ hg init b
|
|
$ cd b
|
|
$ touch f
|
|
$ hg ci -Aqmf
|
|
$ echo >> f
|
|
$ hg ci -Amf
|
|
$ hg branch -q branch
|
|
$ hg ci -Amf
|
|
|
|
$ f --size --hexdump .hg/cache/rbc-*
|
|
.hg/cache/rbc-names-v1: size=14
|
|
0000: 64 65 66 61 75 6c 74 00 62 72 61 6e 63 68 |default.branch|
|
|
.hg/cache/rbc-revs-v1: size=24
|
|
0000: 66 e5 f5 aa 00 00 00 00 fa 4c 04 e5 00 00 00 00 |f........L......|
|
|
0010: 56 46 78 69 00 00 00 01 |VFxi....|
|
|
$ : > .hg/cache/rbc-revs-v1
|
|
|
|
No superfluous rebuilding of cache:
|
|
$ hg log -r "branch(null)&branch(branch)" --debug
|
|
$ f --size --hexdump .hg/cache/rbc-*
|
|
.hg/cache/rbc-names-v1: size=14
|
|
0000: 64 65 66 61 75 6c 74 00 62 72 61 6e 63 68 |default.branch|
|
|
.hg/cache/rbc-revs-v1: size=24
|
|
0000: 66 e5 f5 aa 00 00 00 00 fa 4c 04 e5 00 00 00 00 |f........L......|
|
|
0010: 56 46 78 69 00 00 00 01 |VFxi....|
|
|
|
|
$ cd ..
|