##// END OF EJS Templates
rebase: avoid redundant merges (issue1301)
Stefano Tortarolo -
r7278:45495d78 default
parent child Browse files
Show More
@@ -13,12 +13,31 b' For more information:'
13 13 http://www.selenic.com/mercurial/wiki/index.cgi/RebaseProject
14 14 '''
15 15
16 from mercurial import util, repair, merge, cmdutil, dispatch, commands, extensions
16 from mercurial import util, repair, merge, cmdutil, dispatch, commands
17 from mercurial import extensions, ancestor
17 18 from mercurial.commands import templateopts
18 19 from mercurial.node import nullrev
19 20 from mercurial.i18n import _
20 21 import os, errno
21 22
23 def rebasemerge(repo, rev, first=False):
24 'return the correct ancestor'
25 oldancestor = ancestor.ancestor
26
27 def newancestor(a, b, pfunc):
28 ancestor.ancestor = oldancestor
29 anc = ancestor.ancestor(a, b, pfunc)
30 if b == rev:
31 return repo[rev].parents()[0].rev()
32 return ancestor.ancestor(a, b, pfunc)
33
34 if not first:
35 ancestor.ancestor = newancestor
36 else:
37 repo.ui.debug(_("First revision, do not change ancestor\n"))
38 stats = merge.update(repo, rev, True, True, False)
39 return stats
40
22 41 def rebase(ui, repo, **opts):
23 42 """move changeset (and descendants) to a different branch
24 43
@@ -116,10 +135,12 b' def concludenode(repo, rev, p1, p2, stat'
116 135 """Skip commit if collapsing has been required and rev is not the last
117 136 revision, commit otherwise
118 137 """
119 repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
138 repo.ui.debug(_(" set parents\n"))
139 if collapse and not last:
140 repo.dirstate.setparents(repo[p1].node())
141 return None
120 142
121 if collapse and not last:
122 return None
143 repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
123 144
124 145 # Commit, record the old nodeid
125 146 m, a, r = repo.status()[:3]
@@ -147,16 +168,25 b' def concludenode(repo, rev, p1, p2, stat'
147 168
148 169 def rebasenode(repo, rev, target, state, skipped, targetancestors, collapse):
149 170 'Rebase a single revision'
150 repo.ui.debug(_("rebasing %d:%s\n") % (rev, repo[rev].node()))
171 repo.ui.debug(_("rebasing %d:%s\n") % (rev, repo[rev]))
151 172
152 173 p1, p2 = defineparents(repo, rev, target, state, targetancestors)
153 174
175 repo.ui.debug(_(" future parents are %d and %d\n") % (repo[p1].rev(),
176 repo[p2].rev()))
177
154 178 # Merge phase
155 179 if len(repo.parents()) != 2:
156 180 # Update to target and merge it with local
181 if repo['.'].rev() != repo[p1].rev():
182 repo.ui.debug(_(" update to %d:%s\n") % (repo[p1].rev(), repo[p1]))
157 183 merge.update(repo, p1, False, True, False)
184 else:
185 repo.ui.debug(_(" already in target\n"))
158 186 repo.dirstate.write()
159 stats = merge.update(repo, rev, True, False, False)
187 repo.ui.debug(_(" merge against %d:%s\n") % (repo[rev].rev(), repo[rev]))
188 first = repo[rev].rev() == repo[min(state)].rev()
189 stats = rebasemerge(repo, rev, first)
160 190
161 191 if stats[3] > 0:
162 192 raise util.Abort(_('fix unresolved conflicts with hg resolve then '
@@ -41,15 +41,20 b' createrepo () {'
41 41
42 42 createrepo > /dev/null 2>&1
43 43 hg glog --template '{rev}: {desc}\n'
44 echo '% Rebasing'
44 echo '% Rebasing B onto H'
45 45 hg up -C 3
46 46 hg rebase --collapse 2>&1 | sed 's/\(saving bundle to \).*/\1/'
47 47 hg glog --template '{rev}: {desc}\n'
48 echo "Expected A, B, C, D, F, H"
49 hg manifest
48 50
49 51 createrepo > /dev/null 2>&1
50 echo '% Rebasing'
52 echo
53 echo '% Rebasing G onto H'
51 54 hg rebase --base 6 --collapse 2>&1 | sed 's/\(saving bundle to \).*/\1/'
52 55 hg glog --template '{rev}: {desc}\n'
56 echo "Expected A, E, F, H"
57 hg manifest
53 58
54 59 createrepocomplex () {
55 60 cd $BASE
@@ -76,6 +81,7 b' createrepocomplex () {'
76 81 addcommit "H" 7
77 82 }
78 83
84 echo
79 85 createrepocomplex > /dev/null 2>&1
80 86 hg glog --template '{rev}: {desc}\n'
81 87
@@ -84,8 +90,91 b" echo '% Rebase and collapse - more than "
84 90 hg rebase -s 2 --collapse
85 91
86 92 echo
87 echo '% Rebase and collapse'
93 echo '% Rebase and collapse - E onto H'
88 94 hg rebase -s 4 --collapse 2>&1 | sed 's/\(saving bundle to \).*/\1/'
89 95 hg glog --template '{rev}: {desc}\n'
96 echo "Expected A, B, C, E, F, H"
97 hg manifest
90 98
99 createrepocomplex () {
100 cd $BASE
101 rm -rf a
102 hg init a
103 cd a
104 addcommit "A" 0
105 addcommit "B" 1
106
107 hg up 0
108 addcommit "C" 2
109 hg merge
110 commit "D" 3
111
112 hg up 1
113 addcommit "E" 4
114
115 echo "F" > E
116 commit "F" 5
117
118 addcommit "G" 6
119
120 hg merge
121 commit "H" 7
122
123 hg up 0
124 addcommit "I" 8
125 }
126
127 echo
128 createrepocomplex > /dev/null 2>&1
129 hg glog --template '{rev}: {desc}\n'
130
131 echo
132 echo '% Rebase and collapse - E onto I'
133 hg rebase -s 4 --collapse
134
135 echo '% Fix conflict and continue'
136 echo 'Resolved merge' > E
137 hg resolve -m E
138 hg rebase -c 2>&1 | sed 's/\(saving bundle to \).*/\1/'
139
140 hg glog --template '{rev}: {desc}\n'
141
142 echo "Expected A, B, C, E, G, I"
143 hg manifest
144
145 echo 'Cat E:'
146 cat E
147
148 createrepocomplex () {
149 cd $BASE
150 rm -rf a
151 hg init a
152 cd a
153 addcommit "A" 0
154 addcommit "B" 1
155
156 addcommit "C" 2
157 hg up 1
158
159 addcommit "D" 3
160
161 hg merge
162 commit "E" 4
163
164 hg up 0
165 addcommit "F" 5
166 }
167
168 echo
169 createrepocomplex > /dev/null 2>&1
170 hg glog --template '{rev}: {desc}\n'
171
172 echo
173 echo '% Rebase and collapse - B onto F'
174 hg rebase -s 1 --collapse 2>&1 | sed 's/\(saving bundle to \).*/\1/'
175
176 hg glog --template '{rev}: {desc}\n'
177
178 echo "Expected A, B, C, D, F"
179 hg manifest
91 180 exit 0
@@ -14,7 +14,7 b' o | 5: F'
14 14 |/
15 15 o 0: A
16 16
17 % Rebasing
17 % Rebasing B onto H
18 18 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
19 19 saving bundle to
20 20 adding branch
@@ -37,7 +37,15 b' o | 2: F'
37 37 |/
38 38 o 0: A
39 39
40 % Rebasing
40 Expected A, B, C, D, F, H
41 A
42 B
43 C
44 D
45 F
46 H
47
48 % Rebasing G onto H
41 49 saving bundle to
42 50 adding branch
43 51 adding changesets
@@ -60,6 +68,12 b' o 4: F'
60 68 |/
61 69 o 0: A
62 70
71 Expected A, E, F, H
72 A
73 E
74 F
75 H
76
63 77 @ 7: H
64 78 |
65 79 | o 6: G
@@ -80,7 +94,7 b' o 0: A'
80 94 % Rebase and collapse - more than one external (fail)
81 95 abort: unable to collapse, there is more than one external parent
82 96
83 % Rebase and collapse
97 % Rebase and collapse - E onto H
84 98 saving bundle to
85 99 adding branch
86 100 adding changesets
@@ -102,3 +116,104 b' o / 1: B'
102 116 |/
103 117 o 0: A
104 118
119 Expected A, B, C, E, F, H
120 A
121 B
122 C
123 E
124 F
125 H
126
127 @ 8: I
128 |
129 | o 7: H
130 | |\
131 | | o 6: G
132 | | |
133 | | o 5: F
134 | | |
135 | | o 4: E
136 | | |
137 | o | 3: D
138 | |\|
139 | o | 2: C
140 |/ /
141 | o 1: B
142 |/
143 o 0: A
144
145
146 % Rebase and collapse - E onto I
147 merging E
148 warning: conflicts during merge.
149 merging E failed!
150 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
151 % Fix conflict and continue
152 saving bundle to
153 adding branch
154 adding changesets
155 adding manifests
156 adding file changes
157 added 2 changesets with 3 changes to 3 files
158 rebase completed
159 @ 5: Collapsed revision
160 |\ * E
161 | | * F
162 | | * G
163 | | * H
164 | o 4: I
165 | |
166 o | 3: D
167 |\ \
168 | o | 2: C
169 | |/
170 o / 1: B
171 |/
172 o 0: A
173
174 Expected A, B, C, E, G, I
175 A
176 B
177 C
178 E
179 G
180 I
181 Cat E:
182 Resolved merge
183
184 @ 5: F
185 |
186 | o 4: E
187 | |\
188 | | o 3: D
189 | | |
190 | o | 2: C
191 | |/
192 | o 1: B
193 |/
194 o 0: A
195
196
197 % Rebase and collapse - B onto F
198 saving bundle to
199 adding branch
200 adding changesets
201 adding manifests
202 adding file changes
203 added 2 changesets with 4 changes to 4 files
204 rebase completed
205 @ 2: Collapsed revision
206 | * B
207 | * C
208 | * D
209 | * E
210 o 1: F
211 |
212 o 0: A
213
214 Expected A, B, C, D, F
215 A
216 B
217 C
218 D
219 F
@@ -31,6 +31,10 b" sed -e 's/c2/l2/' common > common.new"
31 31 mv common.new common
32 32 hg commit -d '4 0' -u test -m "L2"
33 33
34 echo 'l3' >> extra2
35 hg add extra2
36 hg commit -d '5 0' -u test -m "L3"
37
34 38 hg glog --template '{rev}: {desc}\n'
35 39
36 40 echo
@@ -47,9 +51,28 b' hg rebase --continue'
47 51
48 52 echo
49 53 echo '% Conclude rebase'
50 echo 'solved merge' >common
54 echo 'resolved merge' >common
51 55 hg resolve -m common
52 56 hg rebase --continue 2>&1 | cleanoutput
53 57
58 hg glog --template '{rev}: {desc}\n'
54 59
55 hg glog --template '{rev}: {desc}\n'
60 echo
61 echo '% Check correctness'
62 echo ' - Rev. 0'
63 hg cat -r 0 common
64
65 echo ' - Rev. 1'
66 hg cat -r 1 common
67
68 echo ' - Rev. 2'
69 hg cat -r 2 common
70
71 echo ' - Rev. 3'
72 hg cat -r 3 common
73
74 echo ' - Rev. 4'
75 hg cat -r 4 common
76
77 echo ' - Rev. 5'
78 hg cat -r 5 common
@@ -1,6 +1,8 b''
1 1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 2 created new head
3 @ 4: L2
3 @ 5: L3
4 |
5 o 4: L2
4 6 |
5 7 o 3: L1
6 8 |
@@ -29,9 +31,11 b' adding branch'
29 31 adding changesets
30 32 adding manifests
31 33 adding file changes
32 added 2 changesets with 2 changes to 2 files
34 added 3 changesets with 3 changes to 3 files
33 35 rebase completed
34 @ 4: L2
36 @ 5: L3
37 |
38 o 4: L2
35 39 |
36 40 o 3: L1
37 41 |
@@ -41,3 +45,22 b' o 1: C2'
41 45 |
42 46 o 0: C1
43 47
48
49 % Check correctness
50 - Rev. 0
51 c1
52 - Rev. 1
53 c1
54 c2
55 - Rev. 2
56 c1
57 c2
58 c3
59 - Rev. 3
60 c1
61 c2
62 c3
63 - Rev. 4
64 resolved merge
65 - Rev. 5
66 resolved merge
General Comments 0
You need to be logged in to leave comments. Login now