##// END OF EJS Templates
discovery: revise hint message introduced by changeset b00ba31313c3...
FUJIWARA Katsunori -
r19936:8179eb28 default
parent child Browse files
Show More
@@ -1,349 +1,349 b''
1 1 # discovery.py - protocol changeset discovery functions
2 2 #
3 3 # Copyright 2010 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from node import nullid, short
9 9 from i18n import _
10 10 import util, setdiscovery, treediscovery, phases, obsolete, bookmarks
11 11 import branchmap
12 12
13 13 def findcommonincoming(repo, remote, heads=None, force=False):
14 14 """Return a tuple (common, anyincoming, heads) used to identify the common
15 15 subset of nodes between repo and remote.
16 16
17 17 "common" is a list of (at least) the heads of the common subset.
18 18 "anyincoming" is testable as a boolean indicating if any nodes are missing
19 19 locally. If remote does not support getbundle, this actually is a list of
20 20 roots of the nodes that would be incoming, to be supplied to
21 21 changegroupsubset. No code except for pull should be relying on this fact
22 22 any longer.
23 23 "heads" is either the supplied heads, or else the remote's heads.
24 24
25 25 If you pass heads and they are all known locally, the response lists just
26 26 these heads in "common" and in "heads".
27 27
28 28 Please use findcommonoutgoing to compute the set of outgoing nodes to give
29 29 extensions a good hook into outgoing.
30 30 """
31 31
32 32 if not remote.capable('getbundle'):
33 33 return treediscovery.findcommonincoming(repo, remote, heads, force)
34 34
35 35 if heads:
36 36 allknown = True
37 37 nm = repo.changelog.nodemap
38 38 for h in heads:
39 39 if nm.get(h) is None:
40 40 allknown = False
41 41 break
42 42 if allknown:
43 43 return (heads, False, heads)
44 44
45 45 res = setdiscovery.findcommonheads(repo.ui, repo, remote,
46 46 abortwhenunrelated=not force)
47 47 common, anyinc, srvheads = res
48 48 return (list(common), anyinc, heads or list(srvheads))
49 49
50 50 class outgoing(object):
51 51 '''Represents the set of nodes present in a local repo but not in a
52 52 (possibly) remote one.
53 53
54 54 Members:
55 55
56 56 missing is a list of all nodes present in local but not in remote.
57 57 common is a list of all nodes shared between the two repos.
58 58 excluded is the list of missing changeset that shouldn't be sent remotely.
59 59 missingheads is the list of heads of missing.
60 60 commonheads is the list of heads of common.
61 61
62 62 The sets are computed on demand from the heads, unless provided upfront
63 63 by discovery.'''
64 64
65 65 def __init__(self, revlog, commonheads, missingheads):
66 66 self.commonheads = commonheads
67 67 self.missingheads = missingheads
68 68 self._revlog = revlog
69 69 self._common = None
70 70 self._missing = None
71 71 self.excluded = []
72 72
73 73 def _computecommonmissing(self):
74 74 sets = self._revlog.findcommonmissing(self.commonheads,
75 75 self.missingheads)
76 76 self._common, self._missing = sets
77 77
78 78 @util.propertycache
79 79 def common(self):
80 80 if self._common is None:
81 81 self._computecommonmissing()
82 82 return self._common
83 83
84 84 @util.propertycache
85 85 def missing(self):
86 86 if self._missing is None:
87 87 self._computecommonmissing()
88 88 return self._missing
89 89
90 90 def findcommonoutgoing(repo, other, onlyheads=None, force=False,
91 91 commoninc=None, portable=False):
92 92 '''Return an outgoing instance to identify the nodes present in repo but
93 93 not in other.
94 94
95 95 If onlyheads is given, only nodes ancestral to nodes in onlyheads
96 96 (inclusive) are included. If you already know the local repo's heads,
97 97 passing them in onlyheads is faster than letting them be recomputed here.
98 98
99 99 If commoninc is given, it must be the result of a prior call to
100 100 findcommonincoming(repo, other, force) to avoid recomputing it here.
101 101
102 102 If portable is given, compute more conservative common and missingheads,
103 103 to make bundles created from the instance more portable.'''
104 104 # declare an empty outgoing object to be filled later
105 105 og = outgoing(repo.changelog, None, None)
106 106
107 107 # get common set if not provided
108 108 if commoninc is None:
109 109 commoninc = findcommonincoming(repo, other, force=force)
110 110 og.commonheads, _any, _hds = commoninc
111 111
112 112 # compute outgoing
113 113 mayexclude = (repo._phasecache.phaseroots[phases.secret] or repo.obsstore)
114 114 if not mayexclude:
115 115 og.missingheads = onlyheads or repo.heads()
116 116 elif onlyheads is None:
117 117 # use visible heads as it should be cached
118 118 og.missingheads = repo.filtered("served").heads()
119 119 og.excluded = [ctx.node() for ctx in repo.set('secret() or extinct()')]
120 120 else:
121 121 # compute common, missing and exclude secret stuff
122 122 sets = repo.changelog.findcommonmissing(og.commonheads, onlyheads)
123 123 og._common, allmissing = sets
124 124 og._missing = missing = []
125 125 og.excluded = excluded = []
126 126 for node in allmissing:
127 127 ctx = repo[node]
128 128 if ctx.phase() >= phases.secret or ctx.extinct():
129 129 excluded.append(node)
130 130 else:
131 131 missing.append(node)
132 132 if len(missing) == len(allmissing):
133 133 missingheads = onlyheads
134 134 else: # update missing heads
135 135 missingheads = phases.newheads(repo, onlyheads, excluded)
136 136 og.missingheads = missingheads
137 137 if portable:
138 138 # recompute common and missingheads as if -r<rev> had been given for
139 139 # each head of missing, and --base <rev> for each head of the proper
140 140 # ancestors of missing
141 141 og._computecommonmissing()
142 142 cl = repo.changelog
143 143 missingrevs = set(cl.rev(n) for n in og._missing)
144 144 og._common = set(cl.ancestors(missingrevs)) - missingrevs
145 145 commonheads = set(og.commonheads)
146 146 og.missingheads = [h for h in og.missingheads if h not in commonheads]
147 147
148 148 return og
149 149
150 150 def _headssummary(repo, remote, outgoing):
151 151 """compute a summary of branch and heads status before and after push
152 152
153 153 return {'branch': ([remoteheads], [newheads], [unsyncedheads])} mapping
154 154
155 155 - branch: the branch name
156 156 - remoteheads: the list of remote heads known locally
157 157 None is the branch is new
158 158 - newheads: the new remote heads (known locally) with outgoing pushed
159 159 - unsyncedheads: the list of remote heads unknown locally.
160 160 """
161 161 cl = repo.changelog
162 162 headssum = {}
163 163 # A. Create set of branches involved in the push.
164 164 branches = set(repo[n].branch() for n in outgoing.missing)
165 165 remotemap = remote.branchmap()
166 166 newbranches = branches - set(remotemap)
167 167 branches.difference_update(newbranches)
168 168
169 169 # A. register remote heads
170 170 remotebranches = set()
171 171 for branch, heads in remote.branchmap().iteritems():
172 172 remotebranches.add(branch)
173 173 known = []
174 174 unsynced = []
175 175 for h in heads:
176 176 if h in cl.nodemap:
177 177 known.append(h)
178 178 else:
179 179 unsynced.append(h)
180 180 headssum[branch] = (known, list(known), unsynced)
181 181 # B. add new branch data
182 182 missingctx = list(repo[n] for n in outgoing.missing)
183 183 touchedbranches = set()
184 184 for ctx in missingctx:
185 185 branch = ctx.branch()
186 186 touchedbranches.add(branch)
187 187 if branch not in headssum:
188 188 headssum[branch] = (None, [], [])
189 189
190 190 # C drop data about untouched branches:
191 191 for branch in remotebranches - touchedbranches:
192 192 del headssum[branch]
193 193
194 194 # D. Update newmap with outgoing changes.
195 195 # This will possibly add new heads and remove existing ones.
196 196 newmap = branchmap.branchcache((branch, heads[1])
197 197 for branch, heads in headssum.iteritems()
198 198 if heads[0] is not None)
199 199 newmap.update(repo, (ctx.rev() for ctx in missingctx))
200 200 for branch, newheads in newmap.iteritems():
201 201 headssum[branch][1][:] = newheads
202 202 return headssum
203 203
204 204 def _oldheadssummary(repo, remoteheads, outgoing, inc=False):
205 205 """Compute branchmapsummary for repo without branchmap support"""
206 206
207 207 cl = repo.changelog
208 208 # 1-4b. old servers: Check for new topological heads.
209 209 # Construct {old,new}map with branch = None (topological branch).
210 210 # (code based on update)
211 211 oldheads = set(h for h in remoteheads if h in cl.nodemap)
212 212 # all nodes in outgoing.missing are children of either:
213 213 # - an element of oldheads
214 214 # - another element of outgoing.missing
215 215 # - nullrev
216 216 # This explains why the new head are very simple to compute.
217 217 r = repo.set('heads(%ln + %ln)', oldheads, outgoing.missing)
218 218 newheads = list(c.node() for c in r)
219 219 unsynced = inc and set([None]) or set()
220 220 return {None: (oldheads, newheads, unsynced)}
221 221
222 222 def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False):
223 223 """Check that a push won't add any outgoing head
224 224
225 225 raise Abort error and display ui message as needed.
226 226 """
227 227 # Check for each named branch if we're creating new remote heads.
228 228 # To be a remote head after push, node must be either:
229 229 # - unknown locally
230 230 # - a local outgoing head descended from update
231 231 # - a remote head that's known locally and not
232 232 # ancestral to an outgoing head
233 233 if remoteheads == [nullid]:
234 234 # remote is empty, nothing to check.
235 235 return
236 236
237 237 if remote.capable('branchmap'):
238 238 headssum = _headssummary(repo, remote, outgoing)
239 239 else:
240 240 headssum = _oldheadssummary(repo, remoteheads, outgoing, inc)
241 241 newbranches = [branch for branch, heads in headssum.iteritems()
242 242 if heads[0] is None]
243 243 # 1. Check for new branches on the remote.
244 244 if newbranches and not newbranch: # new branch requires --new-branch
245 245 branchnames = ', '.join(sorted(newbranches))
246 246 raise util.Abort(_("push creates new remote branches: %s!")
247 247 % branchnames,
248 248 hint=_("use 'hg push --new-branch' to create"
249 249 " new remote branches"))
250 250
251 251 # 2 compute newly pushed bookmarks. We
252 252 # we don't warned about bookmarked heads.
253 253 localbookmarks = repo._bookmarks
254 254 remotebookmarks = remote.listkeys('bookmarks')
255 255 bookmarkedheads = set()
256 256 for bm in localbookmarks:
257 257 rnode = remotebookmarks.get(bm)
258 258 if rnode and rnode in repo:
259 259 lctx, rctx = repo[bm], repo[rnode]
260 260 if bookmarks.validdest(repo, rctx, lctx):
261 261 bookmarkedheads.add(lctx.node())
262 262
263 263 # 3. Check for new heads.
264 264 # If there are more heads after the push than before, a suitable
265 265 # error message, depending on unsynced status, is displayed.
266 266 error = None
267 267 unsynced = False
268 268 allmissing = set(outgoing.missing)
269 269 allfuturecommon = set(c.node() for c in repo.set('%ld', outgoing.common))
270 270 allfuturecommon.update(allmissing)
271 271 for branch, heads in sorted(headssum.iteritems()):
272 272 candidate_newhs = set(heads[1])
273 273 # add unsynced data
274 274 if heads[0] is None:
275 275 oldhs = set()
276 276 else:
277 277 oldhs = set(heads[0])
278 278 oldhs.update(heads[2])
279 279 candidate_newhs.update(heads[2])
280 280 dhs = None
281 281 discardedheads = set()
282 282 if repo.obsstore:
283 283 # remove future heads which are actually obsolete by another
284 284 # pushed element:
285 285 #
286 286 # XXX as above, There are several cases this case does not handle
287 287 # XXX properly
288 288 #
289 289 # (1) if <nh> is public, it won't be affected by obsolete marker
290 290 # and a new is created
291 291 #
292 292 # (2) if the new heads have ancestors which are not obsolete and
293 293 # not ancestors of any other heads we will have a new head too.
294 294 #
295 295 # This two case will be easy to handle for know changeset but much
296 296 # more tricky for unsynced changes.
297 297 newhs = set()
298 298 for nh in candidate_newhs:
299 299 if nh in repo and repo[nh].phase() <= phases.public:
300 300 newhs.add(nh)
301 301 else:
302 302 for suc in obsolete.allsuccessors(repo.obsstore, [nh]):
303 303 if suc != nh and suc in allfuturecommon:
304 304 discardedheads.add(nh)
305 305 break
306 306 else:
307 307 newhs.add(nh)
308 308 else:
309 309 newhs = candidate_newhs
310 310 if [h for h in heads[2] if h not in discardedheads]:
311 311 unsynced = True
312 312 if heads[0] is None:
313 313 if 1 < len(newhs):
314 314 dhs = list(newhs)
315 315 if error is None:
316 316 error = (_("push creates multiple headed new branch '%s'")
317 317 % (branch))
318 318 hint = _("merge or"
319 " see \"hg help push\" for detail about"
319 " see \"hg help push\" for details about"
320 320 " pushing new heads")
321 321 elif len(newhs) > len(oldhs):
322 322 # strip updates to existing remote heads from the new heads list
323 323 dhs = sorted(newhs - bookmarkedheads - oldhs)
324 324 if dhs:
325 325 if error is None:
326 326 if branch not in ('default', None):
327 327 error = _("push creates new remote head %s "
328 328 "on branch '%s'!") % (short(dhs[0]), branch)
329 329 else:
330 330 error = _("push creates new remote head %s!"
331 331 ) % short(dhs[0])
332 332 if heads[2]: # unsynced
333 333 hint = _("pull and merge or"
334 334 " see \"hg help push\" for details about"
335 335 " pushing new heads")
336 336 else:
337 337 hint = _("merge or"
338 338 " see \"hg help push\" for details about"
339 339 " pushing new heads")
340 340 if branch is not None:
341 341 repo.ui.note(_("new remote heads on branch '%s'\n") % branch)
342 342 for h in dhs:
343 343 repo.ui.note(_("new remote head %s\n") % short(h))
344 344 if error:
345 345 raise util.Abort(error, hint=hint)
346 346
347 347 # 6. Check for unsynced changes on involved branches.
348 348 if unsynced:
349 349 repo.ui.warn(_("note: unsynced remote changes!\n"))
@@ -1,755 +1,755 b''
1 1 $ echo "[extensions]" >> $HGRCPATH
2 2 $ echo "graphlog=" >> $HGRCPATH
3 3
4 4 $ hg init a
5 5 $ cd a
6 6 $ echo foo > t1
7 7 $ hg add t1
8 8 $ hg commit -m "1"
9 9
10 10 $ cd ..
11 11 $ hg clone a b
12 12 updating to branch default
13 13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 14
15 15 $ cd a
16 16 $ echo foo > t2
17 17 $ hg add t2
18 18 $ hg commit -m "2"
19 19
20 20 $ cd ../b
21 21 $ echo foo > t3
22 22 $ hg add t3
23 23 $ hg commit -m "3"
24 24
25 25 $ hg push ../a
26 26 pushing to ../a
27 27 searching for changes
28 28 abort: push creates new remote head 1e108cc5548c!
29 29 (pull and merge or see "hg help push" for details about pushing new heads)
30 30 [255]
31 31
32 32 $ hg push --debug ../a
33 33 pushing to ../a
34 34 query 1; heads
35 35 searching for changes
36 36 taking quick initial sample
37 37 searching: 2 queries
38 38 query 2; still undecided: 1, sample size is: 1
39 39 2 total queries
40 40 listing keys for "bookmarks"
41 41 new remote heads on branch 'default'
42 42 new remote head 1e108cc5548c
43 43 abort: push creates new remote head 1e108cc5548c!
44 44 (pull and merge or see "hg help push" for details about pushing new heads)
45 45 [255]
46 46
47 47 $ hg pull ../a
48 48 pulling from ../a
49 49 searching for changes
50 50 adding changesets
51 51 adding manifests
52 52 adding file changes
53 53 added 1 changesets with 1 changes to 1 files (+1 heads)
54 54 (run 'hg heads' to see heads, 'hg merge' to merge)
55 55
56 56 $ hg push ../a
57 57 pushing to ../a
58 58 searching for changes
59 59 abort: push creates new remote head 1e108cc5548c!
60 60 (merge or see "hg help push" for details about pushing new heads)
61 61 [255]
62 62
63 63 $ hg merge
64 64 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
65 65 (branch merge, don't forget to commit)
66 66
67 67 $ hg commit -m "4"
68 68 $ hg push ../a
69 69 pushing to ../a
70 70 searching for changes
71 71 adding changesets
72 72 adding manifests
73 73 adding file changes
74 74 added 2 changesets with 1 changes to 1 files
75 75
76 76 $ cd ..
77 77
78 78 $ hg init c
79 79 $ cd c
80 80 $ for i in 0 1 2; do
81 81 > echo $i >> foo
82 82 > hg ci -Am $i
83 83 > done
84 84 adding foo
85 85 $ cd ..
86 86
87 87 $ hg clone c d
88 88 updating to branch default
89 89 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 90
91 91 $ cd d
92 92 $ for i in 0 1; do
93 93 > hg co -C $i
94 94 > echo d-$i >> foo
95 95 > hg ci -m d-$i
96 96 > done
97 97 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
98 98 created new head
99 99 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 100 created new head
101 101
102 102 $ HGMERGE=true hg merge 3
103 103 merging foo
104 104 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
105 105 (branch merge, don't forget to commit)
106 106
107 107 $ hg ci -m c-d
108 108
109 109 $ hg push ../c
110 110 pushing to ../c
111 111 searching for changes
112 112 abort: push creates new remote head 6346d66eb9f5!
113 113 (merge or see "hg help push" for details about pushing new heads)
114 114 [255]
115 115
116 116 $ hg push -r 2 ../c
117 117 pushing to ../c
118 118 searching for changes
119 119 no changes found
120 120 [1]
121 121
122 122 $ hg push -r 3 ../c
123 123 pushing to ../c
124 124 searching for changes
125 125 abort: push creates new remote head a5dda829a167!
126 126 (merge or see "hg help push" for details about pushing new heads)
127 127 [255]
128 128
129 129 $ hg push -v -r 3 -r 4 ../c
130 130 pushing to ../c
131 131 searching for changes
132 132 new remote heads on branch 'default'
133 133 new remote head a5dda829a167
134 134 new remote head ee8fbc7a0295
135 135 abort: push creates new remote head a5dda829a167!
136 136 (merge or see "hg help push" for details about pushing new heads)
137 137 [255]
138 138
139 139 $ hg push -v -f -r 3 -r 4 ../c
140 140 pushing to ../c
141 141 searching for changes
142 142 2 changesets found
143 143 adding changesets
144 144 adding manifests
145 145 adding file changes
146 146 added 2 changesets with 2 changes to 1 files (+2 heads)
147 147
148 148 $ hg push -r 5 ../c
149 149 pushing to ../c
150 150 searching for changes
151 151 adding changesets
152 152 adding manifests
153 153 adding file changes
154 154 added 1 changesets with 1 changes to 1 files (-1 heads)
155 155
156 156 $ hg in ../c
157 157 comparing with ../c
158 158 searching for changes
159 159 no changes found
160 160 [1]
161 161
162 162
163 163 Issue450: push -r warns about remote head creation even if no heads
164 164 will be created
165 165
166 166 $ hg init ../e
167 167 $ hg push -r 0 ../e
168 168 pushing to ../e
169 169 searching for changes
170 170 adding changesets
171 171 adding manifests
172 172 adding file changes
173 173 added 1 changesets with 1 changes to 1 files
174 174
175 175 $ hg push -r 1 ../e
176 176 pushing to ../e
177 177 searching for changes
178 178 adding changesets
179 179 adding manifests
180 180 adding file changes
181 181 added 1 changesets with 1 changes to 1 files
182 182
183 183 $ cd ..
184 184
185 185
186 186 Issue736: named branches are not considered for detection of
187 187 unmerged heads in "hg push"
188 188
189 189 $ hg init f
190 190 $ cd f
191 191 $ hg -q branch a
192 192 $ echo 0 > foo
193 193 $ hg -q ci -Am 0
194 194 $ echo 1 > foo
195 195 $ hg -q ci -m 1
196 196 $ hg -q up 0
197 197 $ echo 2 > foo
198 198 $ hg -q ci -m 2
199 199 $ hg -q up 0
200 200 $ hg -q branch b
201 201 $ echo 3 > foo
202 202 $ hg -q ci -m 3
203 203 $ cd ..
204 204
205 205 $ hg -q clone f g
206 206 $ cd g
207 207
208 208 Push on existing branch and new branch:
209 209
210 210 $ hg -q up 1
211 211 $ echo 4 > foo
212 212 $ hg -q ci -m 4
213 213 $ hg -q up 0
214 214 $ echo 5 > foo
215 215 $ hg -q branch c
216 216 $ hg -q ci -m 5
217 217
218 218 $ hg push ../f
219 219 pushing to ../f
220 220 searching for changes
221 221 abort: push creates new remote branches: c!
222 222 (use 'hg push --new-branch' to create new remote branches)
223 223 [255]
224 224
225 225 $ hg push -r 4 -r 5 ../f
226 226 pushing to ../f
227 227 searching for changes
228 228 abort: push creates new remote branches: c!
229 229 (use 'hg push --new-branch' to create new remote branches)
230 230 [255]
231 231
232 232
233 233 Multiple new branches:
234 234
235 235 $ hg -q branch d
236 236 $ echo 6 > foo
237 237 $ hg -q ci -m 6
238 238
239 239 $ hg push ../f
240 240 pushing to ../f
241 241 searching for changes
242 242 abort: push creates new remote branches: c, d!
243 243 (use 'hg push --new-branch' to create new remote branches)
244 244 [255]
245 245
246 246 $ hg push -r 4 -r 6 ../f
247 247 pushing to ../f
248 248 searching for changes
249 249 abort: push creates new remote branches: c, d!
250 250 (use 'hg push --new-branch' to create new remote branches)
251 251 [255]
252 252
253 253 $ cd ../g
254 254
255 255
256 256 Fail on multiple head push:
257 257
258 258 $ hg -q up 1
259 259 $ echo 7 > foo
260 260 $ hg -q ci -m 7
261 261
262 262 $ hg push -r 4 -r 7 ../f
263 263 pushing to ../f
264 264 searching for changes
265 265 abort: push creates new remote head 0b715ef6ff8f on branch 'a'!
266 266 (merge or see "hg help push" for details about pushing new heads)
267 267 [255]
268 268
269 269 Push replacement head on existing branches:
270 270
271 271 $ hg -q up 3
272 272 $ echo 8 > foo
273 273 $ hg -q ci -m 8
274 274
275 275 $ hg push -r 7 -r 8 ../f
276 276 pushing to ../f
277 277 searching for changes
278 278 adding changesets
279 279 adding manifests
280 280 adding file changes
281 281 added 2 changesets with 2 changes to 1 files
282 282
283 283
284 284 Merge of branch a to other branch b followed by unrelated push
285 285 on branch a:
286 286
287 287 $ hg -q up 7
288 288 $ HGMERGE=true hg -q merge 8
289 289 $ hg -q ci -m 9
290 290 $ hg -q up 8
291 291 $ echo 10 > foo
292 292 $ hg -q ci -m 10
293 293
294 294 $ hg push -r 9 ../f
295 295 pushing to ../f
296 296 searching for changes
297 297 adding changesets
298 298 adding manifests
299 299 adding file changes
300 300 added 1 changesets with 1 changes to 1 files (-1 heads)
301 301
302 302 $ hg push -r 10 ../f
303 303 pushing to ../f
304 304 searching for changes
305 305 adding changesets
306 306 adding manifests
307 307 adding file changes
308 308 added 1 changesets with 1 changes to 1 files (+1 heads)
309 309
310 310
311 311 Cheating the counting algorithm:
312 312
313 313 $ hg -q up 9
314 314 $ HGMERGE=true hg -q merge 2
315 315 $ hg -q ci -m 11
316 316 $ hg -q up 1
317 317 $ echo 12 > foo
318 318 $ hg -q ci -m 12
319 319
320 320 $ hg push -r 11 -r 12 ../f
321 321 pushing to ../f
322 322 searching for changes
323 323 adding changesets
324 324 adding manifests
325 325 adding file changes
326 326 added 2 changesets with 2 changes to 1 files
327 327
328 328
329 329 Failed push of new named branch:
330 330
331 331 $ echo 12 > foo
332 332 $ hg -q ci -m 12a
333 333 [1]
334 334 $ hg -q up 11
335 335 $ echo 13 > foo
336 336 $ hg -q branch e
337 337 $ hg -q ci -m 13d
338 338
339 339 $ hg push -r 12 -r 13 ../f
340 340 pushing to ../f
341 341 searching for changes
342 342 abort: push creates new remote branches: e!
343 343 (use 'hg push --new-branch' to create new remote branches)
344 344 [255]
345 345
346 346
347 347 Using --new-branch to push new named branch:
348 348
349 349 $ hg push --new-branch -r 12 -r 13 ../f
350 350 pushing to ../f
351 351 searching for changes
352 352 adding changesets
353 353 adding manifests
354 354 adding file changes
355 355 added 1 changesets with 1 changes to 1 files
356 356
357 357 Pushing muliple headed new branch:
358 358
359 359 $ echo 14 > foo
360 360 $ hg -q branch f
361 361 $ hg -q ci -m 14
362 362 $ echo 15 > foo
363 363 $ hg -q ci -m 15
364 364 $ hg -q up 14
365 365 $ echo 16 > foo
366 366 $ hg -q ci -m 16
367 367 $ hg push --branch f --new-branch ../f
368 368 pushing to ../f
369 369 searching for changes
370 370 abort: push creates multiple headed new branch 'f'
371 (merge or see "hg help push" for detail about pushing new heads)
371 (merge or see "hg help push" for details about pushing new heads)
372 372 [255]
373 373 $ hg push --branch f --new-branch --force ../f
374 374 pushing to ../f
375 375 searching for changes
376 376 adding changesets
377 377 adding manifests
378 378 adding file changes
379 379 added 3 changesets with 3 changes to 1 files (+1 heads)
380 380
381 381 Checking prepush logic does not allow silently pushing
382 382 multiple new heads:
383 383
384 384 $ cd ..
385 385 $ hg init h
386 386 $ echo init > h/init
387 387 $ hg -R h ci -Am init
388 388 adding init
389 389 $ echo a > h/a
390 390 $ hg -R h ci -Am a
391 391 adding a
392 392 $ hg clone h i
393 393 updating to branch default
394 394 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
395 395 $ hg -R h up 0
396 396 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
397 397 $ echo b > h/b
398 398 $ hg -R h ci -Am b
399 399 adding b
400 400 created new head
401 401 $ hg -R i up 0
402 402 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
403 403 $ echo c > i/c
404 404 $ hg -R i ci -Am c
405 405 adding c
406 406 created new head
407 407
408 408 $ hg -R i push h
409 409 pushing to h
410 410 searching for changes
411 411 abort: push creates new remote head 97bd0c84d346!
412 412 (pull and merge or see "hg help push" for details about pushing new heads)
413 413 [255]
414 414
415 415
416 416 Check prepush logic with merged branches:
417 417
418 418 $ hg init j
419 419 $ hg -R j branch a
420 420 marked working directory as branch a
421 421 (branches are permanent and global, did you want a bookmark?)
422 422 $ echo init > j/foo
423 423 $ hg -R j ci -Am init
424 424 adding foo
425 425 $ hg clone j k
426 426 updating to branch a
427 427 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
428 428 $ echo a1 > j/foo
429 429 $ hg -R j ci -m a1
430 430 $ hg -R k branch b
431 431 marked working directory as branch b
432 432 (branches are permanent and global, did you want a bookmark?)
433 433 $ echo b > k/foo
434 434 $ hg -R k ci -m b
435 435 $ hg -R k up 0
436 436 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
437 437
438 438 $ hg -R k merge b
439 439 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
440 440 (branch merge, don't forget to commit)
441 441
442 442 $ hg -R k ci -m merge
443 443
444 444 $ hg -R k push -r a j
445 445 pushing to j
446 446 searching for changes
447 447 abort: push creates new remote branches: b!
448 448 (use 'hg push --new-branch' to create new remote branches)
449 449 [255]
450 450
451 451
452 452 Prepush -r should not allow you to sneak in new heads:
453 453
454 454 $ hg init l
455 455 $ cd l
456 456 $ echo a >> foo
457 457 $ hg -q add foo
458 458 $ hg -q branch a
459 459 $ hg -q ci -ma
460 460 $ hg -q up null
461 461 $ echo a >> foo
462 462 $ hg -q add foo
463 463 $ hg -q branch b
464 464 $ hg -q ci -mb
465 465 $ cd ..
466 466 $ hg -q clone l m -u a
467 467 $ cd m
468 468 $ hg -q merge b
469 469 $ hg -q ci -mmb
470 470 $ hg -q up 0
471 471 $ echo a >> foo
472 472 $ hg -q ci -ma2
473 473 $ hg -q up 2
474 474 $ echo a >> foo
475 475 $ hg -q branch -f b
476 476 $ hg -q ci -mb2
477 477 $ hg -q merge 3
478 478 $ hg -q ci -mma
479 479
480 480 $ hg push ../l -b b
481 481 pushing to ../l
482 482 searching for changes
483 483 abort: push creates new remote head 451211cc22b0 on branch 'a'!
484 484 (merge or see "hg help push" for details about pushing new heads)
485 485 [255]
486 486
487 487 $ cd ..
488 488
489 489
490 490 Check prepush with new branch head on former topo non-head:
491 491
492 492 $ hg init n
493 493 $ cd n
494 494 $ hg branch A
495 495 marked working directory as branch A
496 496 (branches are permanent and global, did you want a bookmark?)
497 497 $ echo a >a
498 498 $ hg ci -Ama
499 499 adding a
500 500 $ hg branch B
501 501 marked working directory as branch B
502 502 (branches are permanent and global, did you want a bookmark?)
503 503 $ echo b >b
504 504 $ hg ci -Amb
505 505 adding b
506 506
507 507 b is now branch head of B, and a topological head
508 508 a is now branch head of A, but not a topological head
509 509
510 510 $ hg clone . inner
511 511 updating to branch B
512 512 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
513 513 $ cd inner
514 514 $ hg up B
515 515 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
516 516 $ echo b1 >b1
517 517 $ hg ci -Amb1
518 518 adding b1
519 519
520 520 in the clone b1 is now the head of B
521 521
522 522 $ cd ..
523 523 $ hg up 0
524 524 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
525 525 $ echo a2 >a2
526 526 $ hg ci -Ama2
527 527 adding a2
528 528
529 529 a2 is now the new branch head of A, and a new topological head
530 530 it replaces a former inner branch head, so it should at most warn about
531 531 A, not B
532 532
533 533 glog of local:
534 534
535 535 $ hg glog --template "{rev}: {branches} {desc}\n"
536 536 @ 2: A a2
537 537 |
538 538 | o 1: B b
539 539 |/
540 540 o 0: A a
541 541
542 542 glog of remote:
543 543
544 544 $ hg glog -R inner --template "{rev}: {branches} {desc}\n"
545 545 @ 2: B b1
546 546 |
547 547 o 1: B b
548 548 |
549 549 o 0: A a
550 550
551 551 outgoing:
552 552
553 553 $ hg out inner --template "{rev}: {branches} {desc}\n"
554 554 comparing with inner
555 555 searching for changes
556 556 2: A a2
557 557
558 558 $ hg push inner
559 559 pushing to inner
560 560 searching for changes
561 561 adding changesets
562 562 adding manifests
563 563 adding file changes
564 564 added 1 changesets with 1 changes to 1 files (+1 heads)
565 565
566 566 $ cd ..
567 567
568 568
569 569 Check prepush with new branch head on former topo head:
570 570
571 571 $ hg init o
572 572 $ cd o
573 573 $ hg branch A
574 574 marked working directory as branch A
575 575 (branches are permanent and global, did you want a bookmark?)
576 576 $ echo a >a
577 577 $ hg ci -Ama
578 578 adding a
579 579 $ hg branch B
580 580 marked working directory as branch B
581 581 (branches are permanent and global, did you want a bookmark?)
582 582 $ echo b >b
583 583 $ hg ci -Amb
584 584 adding b
585 585
586 586 b is now branch head of B, and a topological head
587 587
588 588 $ hg up 0
589 589 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
590 590 $ echo a1 >a1
591 591 $ hg ci -Ama1
592 592 adding a1
593 593
594 594 a1 is now branch head of A, and a topological head
595 595
596 596 $ hg clone . inner
597 597 updating to branch A
598 598 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
599 599 $ cd inner
600 600 $ hg up B
601 601 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
602 602 $ echo b1 >b1
603 603 $ hg ci -Amb1
604 604 adding b1
605 605
606 606 in the clone b1 is now the head of B
607 607
608 608 $ cd ..
609 609 $ echo a2 >a2
610 610 $ hg ci -Ama2
611 611 adding a2
612 612
613 613 a2 is now the new branch head of A, and a topological head
614 614 it replaces a former topological and branch head, so this should not warn
615 615
616 616 glog of local:
617 617
618 618 $ hg glog --template "{rev}: {branches} {desc}\n"
619 619 @ 3: A a2
620 620 |
621 621 o 2: A a1
622 622 |
623 623 | o 1: B b
624 624 |/
625 625 o 0: A a
626 626
627 627 glog of remote:
628 628
629 629 $ hg glog -R inner --template "{rev}: {branches} {desc}\n"
630 630 @ 3: B b1
631 631 |
632 632 | o 2: A a1
633 633 | |
634 634 o | 1: B b
635 635 |/
636 636 o 0: A a
637 637
638 638 outgoing:
639 639
640 640 $ hg out inner --template "{rev}: {branches} {desc}\n"
641 641 comparing with inner
642 642 searching for changes
643 643 3: A a2
644 644
645 645 $ hg push inner
646 646 pushing to inner
647 647 searching for changes
648 648 adding changesets
649 649 adding manifests
650 650 adding file changes
651 651 added 1 changesets with 1 changes to 1 files
652 652
653 653 $ cd ..
654 654
655 655
656 656 Check prepush with new branch head and new child of former branch head
657 657 but child is on different branch:
658 658
659 659 $ hg init p
660 660 $ cd p
661 661 $ hg branch A
662 662 marked working directory as branch A
663 663 (branches are permanent and global, did you want a bookmark?)
664 664 $ echo a0 >a
665 665 $ hg ci -Ama0
666 666 adding a
667 667 $ echo a1 >a
668 668 $ hg ci -ma1
669 669 $ hg up null
670 670 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
671 671 $ hg branch B
672 672 marked working directory as branch B
673 673 (branches are permanent and global, did you want a bookmark?)
674 674 $ echo b0 >b
675 675 $ hg ci -Amb0
676 676 adding b
677 677 $ echo b1 >b
678 678 $ hg ci -mb1
679 679
680 680 $ hg clone . inner
681 681 updating to branch B
682 682 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
683 683
684 684 $ hg up A
685 685 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
686 686 $ hg branch -f B
687 687 marked working directory as branch B
688 688 (branches are permanent and global, did you want a bookmark?)
689 689 $ echo a3 >a
690 690 $ hg ci -ma3
691 691 created new head
692 692 $ hg up 3
693 693 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
694 694 $ hg branch -f A
695 695 marked working directory as branch A
696 696 (branches are permanent and global, did you want a bookmark?)
697 697 $ echo b3 >b
698 698 $ hg ci -mb3
699 699 created new head
700 700
701 701 glog of local:
702 702
703 703 $ hg glog --template "{rev}: {branches} {desc}\n"
704 704 @ 5: A b3
705 705 |
706 706 | o 4: B a3
707 707 | |
708 708 o | 3: B b1
709 709 | |
710 710 o | 2: B b0
711 711 /
712 712 o 1: A a1
713 713 |
714 714 o 0: A a0
715 715
716 716 glog of remote:
717 717
718 718 $ hg glog -R inner --template "{rev}: {branches} {desc}\n"
719 719 @ 3: B b1
720 720 |
721 721 o 2: B b0
722 722
723 723 o 1: A a1
724 724 |
725 725 o 0: A a0
726 726
727 727 outgoing:
728 728
729 729 $ hg out inner --template "{rev}: {branches} {desc}\n"
730 730 comparing with inner
731 731 searching for changes
732 732 4: B a3
733 733 5: A b3
734 734
735 735 $ hg push inner
736 736 pushing to inner
737 737 searching for changes
738 738 abort: push creates new remote head 7d0f4fb6cf04 on branch 'A'!
739 739 (merge or see "hg help push" for details about pushing new heads)
740 740 [255]
741 741
742 742 $ hg push inner -r4 -r5
743 743 pushing to inner
744 744 searching for changes
745 745 abort: push creates new remote head 7d0f4fb6cf04 on branch 'A'!
746 746 (merge or see "hg help push" for details about pushing new heads)
747 747 [255]
748 748
749 749 $ hg in inner
750 750 comparing with inner
751 751 searching for changes
752 752 no changes found
753 753 [1]
754 754
755 755 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now