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