##// END OF EJS Templates
discovery: port _postprocessobsolete() changes from evolve, add tests...
av6 -
r49537:053a5bf5 default
parent child Browse files
Show More
@@ -0,0 +1,114 b''
1 =========================================
2 Testing single head enforcement: Case A-1
3 =========================================
4
5 A repository is set to only accept a single head per name (typically named
6 branch). However, obsolete changesets can make this enforcement more
7 complicated, because they can be kept visible by other changeset on other
8 branch.
9
10 This case is part of a series of tests checking this behavior.
11
12 Category A: Involving obsolescence
13 TestCase 1: A fully obsolete branch kept visible by another one
14
15 .. old-state:
16 ..
17 .. * 2 changesets on branch default
18 .. * 2 changesets on branch Z on top of them
19 ..
20 .. new-state:
21 ..
22 .. * 2 changesets on branch Z at the same location
23 .. * 2 changesets on branch default superseding the other ones
24 ..
25 .. expected-result:
26 ..
27 .. * only one head detected
28 ..
29 .. graph-summary:
30 ..
31 .. D (branch Z)
32 .. |
33 .. C (branch Z)
34 .. |
35 .. B ø⇠◔ B'
36 .. | |
37 .. A ø⇠◔ A'
38 .. |/
39 ..
40
41 $ . $TESTDIR/testlib/push-checkheads-util.sh
42
43 $ cat >> $HGRCPATH << EOF
44 > [command-templates]
45 > log = "{node|short} [{branch}] ({phase}): {desc}\n"
46 > EOF
47
48 Test setup
49 ----------
50
51 $ mkdir A1
52 $ cd A1
53 $ setuprepos single-head
54 creating basic server and client repo
55 updating to branch default
56 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
57 $ cd client
58 $ mkcommit B0
59 $ hg branch Z
60 marked working directory as branch Z
61 (branches are permanent and global, did you want a bookmark?)
62 $ mkcommit C0
63 $ mkcommit D0
64 $ hg push --new-branch
65 pushing to $TESTTMP/A1/server
66 searching for changes
67 adding changesets
68 adding manifests
69 adding file changes
70 added 3 changesets with 3 changes to 3 files
71 $ hg up 0
72 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
73 $ mkcommit A1
74 created new head
75 $ mkcommit B1
76 $ hg debugobsolete `getid "desc(A0)"` `getid "desc(A1)"`
77 1 new obsolescence markers
78 obsoleted 1 changesets
79 3 new orphan changesets
80 $ hg debugobsolete `getid "desc(B0)"` `getid "desc(B1)"`
81 1 new obsolescence markers
82 obsoleted 1 changesets
83 $ hg heads
84 262c8c798096 [default] (draft): B1
85 cdf1dbb37a67 [Z] (draft): D0
86 $ hg log -G --hidden
87 @ 262c8c798096 [default] (draft): B1
88 |
89 o f6082bc4ffef [default] (draft): A1
90 |
91 | * cdf1dbb37a67 [Z] (draft): D0
92 | |
93 | * 3213e3e16c67 [Z] (draft): C0
94 | |
95 | x d73caddc5533 [default] (draft): B0
96 | |
97 | x 8aaa48160adc [default] (draft): A0
98 |/
99 o 1e4be0697311 [default] (public): root
100
101
102 Actual testing
103 --------------
104
105 $ hg push -r 'desc("B1")'
106 pushing to $TESTTMP/A1/server
107 searching for changes
108 adding changesets
109 adding manifests
110 adding file changes
111 added 2 changesets with 2 changes to 2 files (+1 heads)
112 2 new obsolescence markers
113 obsoleted 2 changesets
114 2 new orphan changesets
@@ -0,0 +1,113 b''
1 =========================================
2 Testing single head enforcement: Case A-2
3 =========================================
4
5 A repository is set to only accept a single head per name (typically named
6 branch). However, obsolete changesets can make this enforcement more
7 complicated, because they can be kept visible by other changeset on other
8 branch.
9
10 This case is part of a series of tests checking this behavior.
11
12 Category A: Involving obsolescence
13 TestCase 2: A branch is split in two, effectively creating two heads
14
15 .. old-state:
16 ..
17 .. * 2 changesets on branch default
18 .. * 2 changesets on branch Z on top of them
19 ..
20 .. new-state:
21 ..
22 .. * 2 changesets on branch Z at the same location
23 .. * 1 changeset on branch default unchanged
24 .. * 1 changeset on branch default superseding the other ones
25 ..
26 .. expected-result:
27 ..
28 .. * two heads detected
29 ..
30 .. graph-summary:
31 ..
32 .. D (branch Z)
33 .. |
34 .. C (branch Z)
35 .. |
36 .. B ø⇠◔ B'
37 .. | |
38 .. A ● |
39 .. |/
40 .. ●
41
42 $ . $TESTDIR/testlib/push-checkheads-util.sh
43
44 $ cat >> $HGRCPATH << EOF
45 > [command-templates]
46 > log = "{node|short} [{branch}] ({phase}): {desc}\n"
47 > EOF
48
49 Test setup
50 ----------
51
52 $ mkdir A2
53 $ cd A2
54 $ setuprepos single-head
55 creating basic server and client repo
56 updating to branch default
57 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 $ cd client
59 $ mkcommit B0
60 $ hg branch Z
61 marked working directory as branch Z
62 (branches are permanent and global, did you want a bookmark?)
63 $ mkcommit C0
64 $ mkcommit D0
65 $ hg push --new-branch
66 pushing to $TESTTMP/A2/server
67 searching for changes
68 adding changesets
69 adding manifests
70 adding file changes
71 added 3 changesets with 3 changes to 3 files
72 $ hg up 0
73 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
74 $ mkcommit B1
75 created new head
76 $ hg debugobsolete `getid "desc(B0)"` `getid "desc(B1)"`
77 1 new obsolescence markers
78 obsoleted 1 changesets
79 2 new orphan changesets
80 $ hg heads
81 25c56d33e4c4 [default] (draft): B1
82 cdf1dbb37a67 [Z] (draft): D0
83 8aaa48160adc [default] (draft): A0
84 $ hg log -G --hidden
85 @ 25c56d33e4c4 [default] (draft): B1
86 |
87 | * cdf1dbb37a67 [Z] (draft): D0
88 | |
89 | * 3213e3e16c67 [Z] (draft): C0
90 | |
91 | x d73caddc5533 [default] (draft): B0
92 | |
93 | o 8aaa48160adc [default] (draft): A0
94 |/
95 o 1e4be0697311 [default] (public): root
96
97
98 Actual testing
99 --------------
100
101 (force push to make sure we get the changeset on the remote)
102
103 $ hg push -r 'desc("B1")' --force
104 pushing to $TESTTMP/A2/server
105 searching for changes
106 adding changesets
107 adding manifests
108 adding file changes
109 transaction abort!
110 rollback completed
111 abort: rejecting multiple heads on branch "default"
112 (2 heads: 8aaa48160adc 25c56d33e4c4)
113 [255]
@@ -0,0 +1,120 b''
1 =========================================
2 Testing single head enforcement: Case A-3
3 =========================================
4
5 A repository is set to only accept a single head per name (typically named
6 branch). However, obsolete changesets can make this enforcement more
7 complicated, because they can be kept visible by other changeset on other
8 branch.
9
10 This case is part of a series of tests checking this behavior.
11
12 Category A: Involving obsolescence
13 TestCase 3: Full superseding of a branch interleaved with another
14
15 .. old-state:
16 ..
17 .. * 2 changesets on branch default
18 .. * 2 changesets on branch Z interleaved with the other
19 ..
20 .. new-state:
21 ..
22 .. * 2 changesets on branch Z at the same location
23 .. * 2 changesets on branch default superseding the other ones
24 ..
25 .. expected-result:
26 ..
27 .. * only one head detected
28 ..
29 .. graph-summary:
30 ..
31 .. D (branch Z)
32 .. |
33 .. C ø⇠◔ C'
34 .. | |
35 .. B ● | (branch Z)
36 .. | |
37 .. A ø⇠◔ A'
38 .. |/
39 ..
40
41 $ . $TESTDIR/testlib/push-checkheads-util.sh
42
43 $ cat >> $HGRCPATH << EOF
44 > [command-templates]
45 > log = "{node|short} [{branch}] ({phase}): {desc}\n"
46 > EOF
47
48 Test setup
49 ----------
50
51 $ mkdir A3
52 $ cd A3
53 $ setuprepos single-head
54 creating basic server and client repo
55 updating to branch default
56 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
57 $ cd client
58 $ hg branch Z
59 marked working directory as branch Z
60 (branches are permanent and global, did you want a bookmark?)
61 $ mkcommit B0
62 $ hg branch default --force
63 marked working directory as branch default
64 $ mkcommit C0
65 created new head
66 $ hg branch Z --force
67 marked working directory as branch Z
68 $ mkcommit D0
69 created new head
70 $ hg push --new-branch
71 pushing to $TESTTMP/A3/server
72 searching for changes
73 adding changesets
74 adding manifests
75 adding file changes
76 added 3 changesets with 3 changes to 3 files
77 $ hg up 0
78 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
79 $ mkcommit A1
80 created new head
81 $ mkcommit C1
82 $ hg debugobsolete `getid "desc(A0)"` `getid "desc(A1)"`
83 1 new obsolescence markers
84 obsoleted 1 changesets
85 3 new orphan changesets
86 $ hg debugobsolete `getid "desc(C0)"` `getid "desc(C1)"`
87 1 new obsolescence markers
88 obsoleted 1 changesets
89 $ hg heads
90 0c76bc104656 [default] (draft): C1
91 78578c4306ce [Z] (draft): D0
92 $ hg log -G --hidden
93 @ 0c76bc104656 [default] (draft): C1
94 |
95 o f6082bc4ffef [default] (draft): A1
96 |
97 | * 78578c4306ce [Z] (draft): D0
98 | |
99 | x afc55ba2ce61 [default] (draft): C0
100 | |
101 | * 93e5c1321ece [Z] (draft): B0
102 | |
103 | x 8aaa48160adc [default] (draft): A0
104 |/
105 o 1e4be0697311 [default] (public): root
106
107
108 Actual testing
109 --------------
110
111 $ hg push -r 'desc("C1")'
112 pushing to $TESTTMP/A3/server
113 searching for changes
114 adding changesets
115 adding manifests
116 adding file changes
117 added 2 changesets with 2 changes to 2 files (+1 heads)
118 2 new obsolescence markers
119 obsoleted 2 changesets
120 2 new orphan changesets
@@ -0,0 +1,117 b''
1 =========================================
2 Testing single head enforcement: Case A-4
3 =========================================
4
5 A repository is set to only accept a single head per name (typically named
6 branch). However, obsolete changesets can make this enforcement more
7 complicated, because they can be kept visible by other changeset on other
8 branch.
9
10 This case is part of a series of tests checking this behavior.
11
12 Category A: Involving obsolescence
13 TestCase 4: Partial rewrite of a branch to deinterleave it
14
15 .. old-state:
16 ..
17 .. * 2 changesets on branch default
18 .. * 2 changesets on branch Z interleaved with the other one
19 ..
20 .. new-state:
21 ..
22 .. * 2 changesets on branch Z at the same location
23 .. * 1 changeset on default untouched (the lower one)
24 .. * 1 changeset on default moved on the other one
25 ..
26 .. expected-result:
27 ..
28 .. * only one head detected
29 ..
30 .. graph-summary:
31 ..
32 .. D (branch Z)
33 .. |
34 .. C ø⇠◔ C'
35 .. | |
36 .. B ● | (branch Z)
37 .. |/
38 .. A ●
39 .. |
40 .. ●
41
42 $ . $TESTDIR/testlib/push-checkheads-util.sh
43
44 $ cat >> $HGRCPATH << EOF
45 > [command-templates]
46 > log = "{node|short} [{branch}] ({phase}): {desc}\n"
47 > EOF
48
49 Test setup
50 ----------
51
52 $ mkdir A4
53 $ cd A4
54 $ setuprepos single-head
55 creating basic server and client repo
56 updating to branch default
57 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 $ cd client
59 $ hg branch Z
60 marked working directory as branch Z
61 (branches are permanent and global, did you want a bookmark?)
62 $ mkcommit B0
63 $ hg branch default --force
64 marked working directory as branch default
65 $ mkcommit C0
66 created new head
67 $ hg branch Z --force
68 marked working directory as branch Z
69 $ mkcommit D0
70 created new head
71 $ hg push --new-branch
72 pushing to $TESTTMP/A4/server
73 searching for changes
74 adding changesets
75 adding manifests
76 adding file changes
77 added 3 changesets with 3 changes to 3 files
78 $ hg up 'desc("A0")'
79 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
80 $ mkcommit C1
81 created new head
82 $ hg debugobsolete `getid "desc(C0)"` `getid "desc(C1)"`
83 1 new obsolescence markers
84 obsoleted 1 changesets
85 1 new orphan changesets
86 $ hg heads
87 cfe9ed94fa4a [default] (draft): C1
88 78578c4306ce [Z] (draft): D0
89 $ hg log -G --hidden
90 @ cfe9ed94fa4a [default] (draft): C1
91 |
92 | * 78578c4306ce [Z] (draft): D0
93 | |
94 | x afc55ba2ce61 [default] (draft): C0
95 | |
96 | o 93e5c1321ece [Z] (draft): B0
97 |/
98 o 8aaa48160adc [default] (draft): A0
99 |
100 o 1e4be0697311 [default] (public): root
101
102
103 Actual testing
104 --------------
105
106 (force push to make sure we get the changeset on the remote)
107
108 $ hg push -r 'desc("C1")' --force
109 pushing to $TESTTMP/A4/server
110 searching for changes
111 adding changesets
112 adding manifests
113 adding file changes
114 added 1 changesets with 1 changes to 1 files (+1 heads)
115 1 new obsolescence markers
116 obsoleted 1 changesets
117 1 new orphan changesets
@@ -0,0 +1,108 b''
1 =========================================
2 Testing single head enforcement: Case A-5
3 =========================================
4
5 A repository is set to only accept a single head per name (typically named
6 branch). However, obsolete changesets can make this enforcement more
7 complicated, because they can be kept visible by other changeset on other
8 branch.
9
10 This case is part of a series of tests checking this behavior.
11
12 Category A: Involving obsolescence
13 TestCase 5: Obsoleting a merge reveals two heads
14
15 .. old-state:
16 ..
17 .. * 3 changesets on branch default (2 on their own branch + 1 merge)
18 .. * 1 changeset on branch Z (children of the merge)
19 ..
20 .. new-state:
21 ..
22 .. * 2 changesets on branch default (merge is obsolete) each a head
23 .. * 1 changeset on branch Z keeping the merge visible
24 ..
25 .. expected-result:
26 ..
27 .. * 2 heads detected (because we skip the merge)
28 ..
29 .. graph-summary:
30 ..
31 .. C (branch Z)
32 .. |
33 .. M
34 .. |\
35 .. A B
36 .. |/
37 ..
38
39 $ . $TESTDIR/testlib/push-checkheads-util.sh
40
41 $ cat >> $HGRCPATH << EOF
42 > [command-templates]
43 > log = "{node|short} [{branch}] ({phase}): {desc}\n"
44 > EOF
45
46 Test setup
47 ----------
48
49 $ mkdir A5
50 $ cd A5
51 $ setuprepos single-head
52 creating basic server and client repo
53 updating to branch default
54 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 $ cd client
56 $ hg up 0
57 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
58 $ mkcommit B0
59 created new head
60 $ hg merge
61 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 (branch merge, don't forget to commit)
63 $ hg ci -m 'M0'
64 $ hg branch Z
65 marked working directory as branch Z
66 (branches are permanent and global, did you want a bookmark?)
67 $ mkcommit C0
68 $ hg push --new-branch
69 pushing to $TESTTMP/A5/server
70 searching for changes
71 adding changesets
72 adding manifests
73 adding file changes
74 added 3 changesets with 2 changes to 2 files
75 $ hg debugobsolete `getid "desc(M0)"` --record-parents
76 1 new obsolescence markers
77 obsoleted 1 changesets
78 1 new orphan changesets
79 $ hg heads
80 61c95483cc12 [Z] (draft): C0
81 74ff5441d343 [default] (draft): B0
82 8aaa48160adc [default] (draft): A0
83 $ hg log -G --hidden
84 @ 61c95483cc12 [Z] (draft): C0
85 |
86 x 14d3d4d41d1a [default] (draft): M0
87 |\
88 | o 74ff5441d343 [default] (draft): B0
89 | |
90 o | 8aaa48160adc [default] (draft): A0
91 |/
92 o 1e4be0697311 [default] (public): root
93
94
95 Actual testing
96 --------------
97
98 (force push to make sure we get the changeset on the remote)
99
100 $ hg push -r 'desc("C0")' --force
101 pushing to $TESTTMP/A5/server
102 searching for changes
103 no changes found
104 transaction abort!
105 rollback completed
106 abort: rejecting multiple heads on branch "default"
107 (2 heads: 8aaa48160adc 74ff5441d343)
108 [255]
@@ -19,6 +19,7 b' from . import ('
19 bookmarks,
19 bookmarks,
20 branchmap,
20 branchmap,
21 error,
21 error,
22 obsolete,
22 phases,
23 phases,
23 pycompat,
24 pycompat,
24 scmutil,
25 scmutil,
@@ -545,12 +546,16 b' def _postprocessobsolete(pushop, futurec'
545 if len(localcandidate) == 1:
546 if len(localcandidate) == 1:
546 return unknownheads | set(candidate_newhs), set()
547 return unknownheads | set(candidate_newhs), set()
547
548
549 obsrevs = obsolete.getrevs(unfi, b'obsolete')
550 futurenonobsolete = frozenset(futurecommon) - obsrevs
551
548 # actually process branch replacement
552 # actually process branch replacement
549 while localcandidate:
553 while localcandidate:
550 nh = localcandidate.pop()
554 nh = localcandidate.pop()
555 r = torev(nh)
551 current_branch = unfi[nh].branch()
556 current_branch = unfi[nh].branch()
552 # run this check early to skip the evaluation of the whole branch
557 # run this check early to skip the evaluation of the whole branch
553 if torev(nh) in futurecommon or ispublic(torev(nh)):
558 if ispublic(r) or r not in obsrevs:
554 newhs.add(nh)
559 newhs.add(nh)
555 continue
560 continue
556
561
@@ -572,7 +577,7 b' def _postprocessobsolete(pushop, futurec'
572 # * if we have no markers to push to obsolete it.
577 # * if we have no markers to push to obsolete it.
573 if (
578 if (
574 any(ispublic(r) for r in branchrevs)
579 any(ispublic(r) for r in branchrevs)
575 or any(torev(n) in futurecommon for n in branchnodes)
580 or any(torev(n) in futurenonobsolete for n in branchnodes)
576 or any(not hasoutmarker(n) for n in branchnodes)
581 or any(not hasoutmarker(n) for n in branchnodes)
577 ):
582 ):
578 newhs.add(nh)
583 newhs.add(nh)
@@ -41,4 +41,10 b' setuprepos() {'
41 mkcommit A0
41 mkcommit A0
42 cd ..
42 cd ..
43 hg clone server client
43 hg clone server client
44
45 if [ "$1" = "single-head" ]; then
46 echo >> "server/.hg/hgrc" "[experimental]"
47 echo >> "server/.hg/hgrc" "# enforce a single name per branch"
48 echo >> "server/.hg/hgrc" "single-head-per-branch = yes"
49 fi
44 }
50 }
General Comments 0
You need to be logged in to leave comments. Login now