##// END OF EJS Templates
bookmarks: don't allow pushing new head for existing mark with -B (issue4400)
Matt Mackall -
r26819:ba7eeeac stable
parent child Browse files
Show More
@@ -1,397 +1,397
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 __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 from .i18n import _
10 from .i18n import _
11 from .node import (
11 from .node import (
12 nullid,
12 nullid,
13 short,
13 short,
14 )
14 )
15
15
16 from . import (
16 from . import (
17 bookmarks,
17 bookmarks,
18 branchmap,
18 branchmap,
19 error,
19 error,
20 obsolete,
20 obsolete,
21 phases,
21 phases,
22 setdiscovery,
22 setdiscovery,
23 treediscovery,
23 treediscovery,
24 util,
24 util,
25 )
25 )
26
26
27 def findcommonincoming(repo, remote, heads=None, force=False):
27 def findcommonincoming(repo, remote, heads=None, force=False):
28 """Return a tuple (common, anyincoming, heads) used to identify the common
28 """Return a tuple (common, anyincoming, heads) used to identify the common
29 subset of nodes between repo and remote.
29 subset of nodes between repo and remote.
30
30
31 "common" is a list of (at least) the heads of the common subset.
31 "common" is a list of (at least) the heads of the common subset.
32 "anyincoming" is testable as a boolean indicating if any nodes are missing
32 "anyincoming" is testable as a boolean indicating if any nodes are missing
33 locally. If remote does not support getbundle, this actually is a list of
33 locally. If remote does not support getbundle, this actually is a list of
34 roots of the nodes that would be incoming, to be supplied to
34 roots of the nodes that would be incoming, to be supplied to
35 changegroupsubset. No code except for pull should be relying on this fact
35 changegroupsubset. No code except for pull should be relying on this fact
36 any longer.
36 any longer.
37 "heads" is either the supplied heads, or else the remote's heads.
37 "heads" is either the supplied heads, or else the remote's heads.
38
38
39 If you pass heads and they are all known locally, the response lists just
39 If you pass heads and they are all known locally, the response lists just
40 these heads in "common" and in "heads".
40 these heads in "common" and in "heads".
41
41
42 Please use findcommonoutgoing to compute the set of outgoing nodes to give
42 Please use findcommonoutgoing to compute the set of outgoing nodes to give
43 extensions a good hook into outgoing.
43 extensions a good hook into outgoing.
44 """
44 """
45
45
46 if not remote.capable('getbundle'):
46 if not remote.capable('getbundle'):
47 return treediscovery.findcommonincoming(repo, remote, heads, force)
47 return treediscovery.findcommonincoming(repo, remote, heads, force)
48
48
49 if heads:
49 if heads:
50 allknown = True
50 allknown = True
51 knownnode = repo.changelog.hasnode # no nodemap until it is filtered
51 knownnode = repo.changelog.hasnode # no nodemap until it is filtered
52 for h in heads:
52 for h in heads:
53 if not knownnode(h):
53 if not knownnode(h):
54 allknown = False
54 allknown = False
55 break
55 break
56 if allknown:
56 if allknown:
57 return (heads, False, heads)
57 return (heads, False, heads)
58
58
59 res = setdiscovery.findcommonheads(repo.ui, repo, remote,
59 res = setdiscovery.findcommonheads(repo.ui, repo, remote,
60 abortwhenunrelated=not force)
60 abortwhenunrelated=not force)
61 common, anyinc, srvheads = res
61 common, anyinc, srvheads = res
62 return (list(common), anyinc, heads or list(srvheads))
62 return (list(common), anyinc, heads or list(srvheads))
63
63
64 class outgoing(object):
64 class outgoing(object):
65 '''Represents the set of nodes present in a local repo but not in a
65 '''Represents the set of nodes present in a local repo but not in a
66 (possibly) remote one.
66 (possibly) remote one.
67
67
68 Members:
68 Members:
69
69
70 missing is a list of all nodes present in local but not in remote.
70 missing is a list of all nodes present in local but not in remote.
71 common is a list of all nodes shared between the two repos.
71 common is a list of all nodes shared between the two repos.
72 excluded is the list of missing changeset that shouldn't be sent remotely.
72 excluded is the list of missing changeset that shouldn't be sent remotely.
73 missingheads is the list of heads of missing.
73 missingheads is the list of heads of missing.
74 commonheads is the list of heads of common.
74 commonheads is the list of heads of common.
75
75
76 The sets are computed on demand from the heads, unless provided upfront
76 The sets are computed on demand from the heads, unless provided upfront
77 by discovery.'''
77 by discovery.'''
78
78
79 def __init__(self, revlog, commonheads, missingheads):
79 def __init__(self, revlog, commonheads, missingheads):
80 self.commonheads = commonheads
80 self.commonheads = commonheads
81 self.missingheads = missingheads
81 self.missingheads = missingheads
82 self._revlog = revlog
82 self._revlog = revlog
83 self._common = None
83 self._common = None
84 self._missing = None
84 self._missing = None
85 self.excluded = []
85 self.excluded = []
86
86
87 def _computecommonmissing(self):
87 def _computecommonmissing(self):
88 sets = self._revlog.findcommonmissing(self.commonheads,
88 sets = self._revlog.findcommonmissing(self.commonheads,
89 self.missingheads)
89 self.missingheads)
90 self._common, self._missing = sets
90 self._common, self._missing = sets
91
91
92 @util.propertycache
92 @util.propertycache
93 def common(self):
93 def common(self):
94 if self._common is None:
94 if self._common is None:
95 self._computecommonmissing()
95 self._computecommonmissing()
96 return self._common
96 return self._common
97
97
98 @util.propertycache
98 @util.propertycache
99 def missing(self):
99 def missing(self):
100 if self._missing is None:
100 if self._missing is None:
101 self._computecommonmissing()
101 self._computecommonmissing()
102 return self._missing
102 return self._missing
103
103
104 def findcommonoutgoing(repo, other, onlyheads=None, force=False,
104 def findcommonoutgoing(repo, other, onlyheads=None, force=False,
105 commoninc=None, portable=False):
105 commoninc=None, portable=False):
106 '''Return an outgoing instance to identify the nodes present in repo but
106 '''Return an outgoing instance to identify the nodes present in repo but
107 not in other.
107 not in other.
108
108
109 If onlyheads is given, only nodes ancestral to nodes in onlyheads
109 If onlyheads is given, only nodes ancestral to nodes in onlyheads
110 (inclusive) are included. If you already know the local repo's heads,
110 (inclusive) are included. If you already know the local repo's heads,
111 passing them in onlyheads is faster than letting them be recomputed here.
111 passing them in onlyheads is faster than letting them be recomputed here.
112
112
113 If commoninc is given, it must be the result of a prior call to
113 If commoninc is given, it must be the result of a prior call to
114 findcommonincoming(repo, other, force) to avoid recomputing it here.
114 findcommonincoming(repo, other, force) to avoid recomputing it here.
115
115
116 If portable is given, compute more conservative common and missingheads,
116 If portable is given, compute more conservative common and missingheads,
117 to make bundles created from the instance more portable.'''
117 to make bundles created from the instance more portable.'''
118 # declare an empty outgoing object to be filled later
118 # declare an empty outgoing object to be filled later
119 og = outgoing(repo.changelog, None, None)
119 og = outgoing(repo.changelog, None, None)
120
120
121 # get common set if not provided
121 # get common set if not provided
122 if commoninc is None:
122 if commoninc is None:
123 commoninc = findcommonincoming(repo, other, force=force)
123 commoninc = findcommonincoming(repo, other, force=force)
124 og.commonheads, _any, _hds = commoninc
124 og.commonheads, _any, _hds = commoninc
125
125
126 # compute outgoing
126 # compute outgoing
127 mayexclude = (repo._phasecache.phaseroots[phases.secret] or repo.obsstore)
127 mayexclude = (repo._phasecache.phaseroots[phases.secret] or repo.obsstore)
128 if not mayexclude:
128 if not mayexclude:
129 og.missingheads = onlyheads or repo.heads()
129 og.missingheads = onlyheads or repo.heads()
130 elif onlyheads is None:
130 elif onlyheads is None:
131 # use visible heads as it should be cached
131 # use visible heads as it should be cached
132 og.missingheads = repo.filtered("served").heads()
132 og.missingheads = repo.filtered("served").heads()
133 og.excluded = [ctx.node() for ctx in repo.set('secret() or extinct()')]
133 og.excluded = [ctx.node() for ctx in repo.set('secret() or extinct()')]
134 else:
134 else:
135 # compute common, missing and exclude secret stuff
135 # compute common, missing and exclude secret stuff
136 sets = repo.changelog.findcommonmissing(og.commonheads, onlyheads)
136 sets = repo.changelog.findcommonmissing(og.commonheads, onlyheads)
137 og._common, allmissing = sets
137 og._common, allmissing = sets
138 og._missing = missing = []
138 og._missing = missing = []
139 og.excluded = excluded = []
139 og.excluded = excluded = []
140 for node in allmissing:
140 for node in allmissing:
141 ctx = repo[node]
141 ctx = repo[node]
142 if ctx.phase() >= phases.secret or ctx.extinct():
142 if ctx.phase() >= phases.secret or ctx.extinct():
143 excluded.append(node)
143 excluded.append(node)
144 else:
144 else:
145 missing.append(node)
145 missing.append(node)
146 if len(missing) == len(allmissing):
146 if len(missing) == len(allmissing):
147 missingheads = onlyheads
147 missingheads = onlyheads
148 else: # update missing heads
148 else: # update missing heads
149 missingheads = phases.newheads(repo, onlyheads, excluded)
149 missingheads = phases.newheads(repo, onlyheads, excluded)
150 og.missingheads = missingheads
150 og.missingheads = missingheads
151 if portable:
151 if portable:
152 # recompute common and missingheads as if -r<rev> had been given for
152 # recompute common and missingheads as if -r<rev> had been given for
153 # each head of missing, and --base <rev> for each head of the proper
153 # each head of missing, and --base <rev> for each head of the proper
154 # ancestors of missing
154 # ancestors of missing
155 og._computecommonmissing()
155 og._computecommonmissing()
156 cl = repo.changelog
156 cl = repo.changelog
157 missingrevs = set(cl.rev(n) for n in og._missing)
157 missingrevs = set(cl.rev(n) for n in og._missing)
158 og._common = set(cl.ancestors(missingrevs)) - missingrevs
158 og._common = set(cl.ancestors(missingrevs)) - missingrevs
159 commonheads = set(og.commonheads)
159 commonheads = set(og.commonheads)
160 og.missingheads = [h for h in og.missingheads if h not in commonheads]
160 og.missingheads = [h for h in og.missingheads if h not in commonheads]
161
161
162 return og
162 return og
163
163
164 def _headssummary(repo, remote, outgoing):
164 def _headssummary(repo, remote, outgoing):
165 """compute a summary of branch and heads status before and after push
165 """compute a summary of branch and heads status before and after push
166
166
167 return {'branch': ([remoteheads], [newheads], [unsyncedheads])} mapping
167 return {'branch': ([remoteheads], [newheads], [unsyncedheads])} mapping
168
168
169 - branch: the branch name
169 - branch: the branch name
170 - remoteheads: the list of remote heads known locally
170 - remoteheads: the list of remote heads known locally
171 None if the branch is new
171 None if the branch is new
172 - newheads: the new remote heads (known locally) with outgoing pushed
172 - newheads: the new remote heads (known locally) with outgoing pushed
173 - unsyncedheads: the list of remote heads unknown locally.
173 - unsyncedheads: the list of remote heads unknown locally.
174 """
174 """
175 cl = repo.changelog
175 cl = repo.changelog
176 headssum = {}
176 headssum = {}
177 # A. Create set of branches involved in the push.
177 # A. Create set of branches involved in the push.
178 branches = set(repo[n].branch() for n in outgoing.missing)
178 branches = set(repo[n].branch() for n in outgoing.missing)
179 remotemap = remote.branchmap()
179 remotemap = remote.branchmap()
180 newbranches = branches - set(remotemap)
180 newbranches = branches - set(remotemap)
181 branches.difference_update(newbranches)
181 branches.difference_update(newbranches)
182
182
183 # A. register remote heads
183 # A. register remote heads
184 remotebranches = set()
184 remotebranches = set()
185 for branch, heads in remote.branchmap().iteritems():
185 for branch, heads in remote.branchmap().iteritems():
186 remotebranches.add(branch)
186 remotebranches.add(branch)
187 known = []
187 known = []
188 unsynced = []
188 unsynced = []
189 knownnode = cl.hasnode # do not use nodemap until it is filtered
189 knownnode = cl.hasnode # do not use nodemap until it is filtered
190 for h in heads:
190 for h in heads:
191 if knownnode(h):
191 if knownnode(h):
192 known.append(h)
192 known.append(h)
193 else:
193 else:
194 unsynced.append(h)
194 unsynced.append(h)
195 headssum[branch] = (known, list(known), unsynced)
195 headssum[branch] = (known, list(known), unsynced)
196 # B. add new branch data
196 # B. add new branch data
197 missingctx = list(repo[n] for n in outgoing.missing)
197 missingctx = list(repo[n] for n in outgoing.missing)
198 touchedbranches = set()
198 touchedbranches = set()
199 for ctx in missingctx:
199 for ctx in missingctx:
200 branch = ctx.branch()
200 branch = ctx.branch()
201 touchedbranches.add(branch)
201 touchedbranches.add(branch)
202 if branch not in headssum:
202 if branch not in headssum:
203 headssum[branch] = (None, [], [])
203 headssum[branch] = (None, [], [])
204
204
205 # C drop data about untouched branches:
205 # C drop data about untouched branches:
206 for branch in remotebranches - touchedbranches:
206 for branch in remotebranches - touchedbranches:
207 del headssum[branch]
207 del headssum[branch]
208
208
209 # D. Update newmap with outgoing changes.
209 # D. Update newmap with outgoing changes.
210 # This will possibly add new heads and remove existing ones.
210 # This will possibly add new heads and remove existing ones.
211 newmap = branchmap.branchcache((branch, heads[1])
211 newmap = branchmap.branchcache((branch, heads[1])
212 for branch, heads in headssum.iteritems()
212 for branch, heads in headssum.iteritems()
213 if heads[0] is not None)
213 if heads[0] is not None)
214 newmap.update(repo, (ctx.rev() for ctx in missingctx))
214 newmap.update(repo, (ctx.rev() for ctx in missingctx))
215 for branch, newheads in newmap.iteritems():
215 for branch, newheads in newmap.iteritems():
216 headssum[branch][1][:] = newheads
216 headssum[branch][1][:] = newheads
217 return headssum
217 return headssum
218
218
219 def _oldheadssummary(repo, remoteheads, outgoing, inc=False):
219 def _oldheadssummary(repo, remoteheads, outgoing, inc=False):
220 """Compute branchmapsummary for repo without branchmap support"""
220 """Compute branchmapsummary for repo without branchmap support"""
221
221
222 # 1-4b. old servers: Check for new topological heads.
222 # 1-4b. old servers: Check for new topological heads.
223 # Construct {old,new}map with branch = None (topological branch).
223 # Construct {old,new}map with branch = None (topological branch).
224 # (code based on update)
224 # (code based on update)
225 knownnode = repo.changelog.hasnode # no nodemap until it is filtered
225 knownnode = repo.changelog.hasnode # no nodemap until it is filtered
226 oldheads = set(h for h in remoteheads if knownnode(h))
226 oldheads = set(h for h in remoteheads if knownnode(h))
227 # all nodes in outgoing.missing are children of either:
227 # all nodes in outgoing.missing are children of either:
228 # - an element of oldheads
228 # - an element of oldheads
229 # - another element of outgoing.missing
229 # - another element of outgoing.missing
230 # - nullrev
230 # - nullrev
231 # This explains why the new head are very simple to compute.
231 # This explains why the new head are very simple to compute.
232 r = repo.set('heads(%ln + %ln)', oldheads, outgoing.missing)
232 r = repo.set('heads(%ln + %ln)', oldheads, outgoing.missing)
233 newheads = list(c.node() for c in r)
233 newheads = list(c.node() for c in r)
234 # set some unsynced head to issue the "unsynced changes" warning
234 # set some unsynced head to issue the "unsynced changes" warning
235 if inc:
235 if inc:
236 unsynced = set([None])
236 unsynced = set([None])
237 else:
237 else:
238 unsynced = set()
238 unsynced = set()
239 return {None: (oldheads, newheads, unsynced)}
239 return {None: (oldheads, newheads, unsynced)}
240
240
241 def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False,
241 def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False,
242 newbookmarks=[]):
242 newbookmarks=[]):
243 """Check that a push won't add any outgoing head
243 """Check that a push won't add any outgoing head
244
244
245 raise Abort error and display ui message as needed.
245 raise Abort error and display ui message as needed.
246 """
246 """
247 # Check for each named branch if we're creating new remote heads.
247 # Check for each named branch if we're creating new remote heads.
248 # To be a remote head after push, node must be either:
248 # To be a remote head after push, node must be either:
249 # - unknown locally
249 # - unknown locally
250 # - a local outgoing head descended from update
250 # - a local outgoing head descended from update
251 # - a remote head that's known locally and not
251 # - a remote head that's known locally and not
252 # ancestral to an outgoing head
252 # ancestral to an outgoing head
253 if remoteheads == [nullid]:
253 if remoteheads == [nullid]:
254 # remote is empty, nothing to check.
254 # remote is empty, nothing to check.
255 return
255 return
256
256
257 if remote.capable('branchmap'):
257 if remote.capable('branchmap'):
258 headssum = _headssummary(repo, remote, outgoing)
258 headssum = _headssummary(repo, remote, outgoing)
259 else:
259 else:
260 headssum = _oldheadssummary(repo, remoteheads, outgoing, inc)
260 headssum = _oldheadssummary(repo, remoteheads, outgoing, inc)
261 newbranches = [branch for branch, heads in headssum.iteritems()
261 newbranches = [branch for branch, heads in headssum.iteritems()
262 if heads[0] is None]
262 if heads[0] is None]
263 # 1. Check for new branches on the remote.
263 # 1. Check for new branches on the remote.
264 if newbranches and not newbranch: # new branch requires --new-branch
264 if newbranches and not newbranch: # new branch requires --new-branch
265 branchnames = ', '.join(sorted(newbranches))
265 branchnames = ', '.join(sorted(newbranches))
266 raise error.Abort(_("push creates new remote branches: %s!")
266 raise error.Abort(_("push creates new remote branches: %s!")
267 % branchnames,
267 % branchnames,
268 hint=_("use 'hg push --new-branch' to create"
268 hint=_("use 'hg push --new-branch' to create"
269 " new remote branches"))
269 " new remote branches"))
270
270
271 # 2. Compute newly pushed bookmarks. We don't warn about bookmarked heads.
271 # 2. Compute newly pushed bookmarks. We don't warn about bookmarked heads.
272 localbookmarks = repo._bookmarks
272 localbookmarks = repo._bookmarks
273 remotebookmarks = remote.listkeys('bookmarks')
273 remotebookmarks = remote.listkeys('bookmarks')
274 bookmarkedheads = set()
274 bookmarkedheads = set()
275 for bm in localbookmarks:
275 for bm in localbookmarks:
276 rnode = remotebookmarks.get(bm)
276 rnode = remotebookmarks.get(bm)
277 if rnode and rnode in repo:
277 if rnode and rnode in repo:
278 lctx, rctx = repo[bm], repo[rnode]
278 lctx, rctx = repo[bm], repo[rnode]
279 if bookmarks.validdest(repo, rctx, lctx):
279 if bookmarks.validdest(repo, rctx, lctx):
280 bookmarkedheads.add(lctx.node())
280 bookmarkedheads.add(lctx.node())
281 else:
281 else:
282 if bm in newbookmarks:
282 if bm in newbookmarks and bm not in remotebookmarks:
283 bookmarkedheads.add(repo[bm].node())
283 bookmarkedheads.add(repo[bm].node())
284
284
285 # 3. Check for new heads.
285 # 3. Check for new heads.
286 # If there are more heads after the push than before, a suitable
286 # If there are more heads after the push than before, a suitable
287 # error message, depending on unsynced status, is displayed.
287 # error message, depending on unsynced status, is displayed.
288 errormsg = None
288 errormsg = None
289 # If there is no obsstore, allfuturecommon won't be used, so no
289 # If there is no obsstore, allfuturecommon won't be used, so no
290 # need to compute it.
290 # need to compute it.
291 if repo.obsstore:
291 if repo.obsstore:
292 allmissing = set(outgoing.missing)
292 allmissing = set(outgoing.missing)
293 cctx = repo.set('%ld', outgoing.common)
293 cctx = repo.set('%ld', outgoing.common)
294 allfuturecommon = set(c.node() for c in cctx)
294 allfuturecommon = set(c.node() for c in cctx)
295 allfuturecommon.update(allmissing)
295 allfuturecommon.update(allmissing)
296 for branch, heads in sorted(headssum.iteritems()):
296 for branch, heads in sorted(headssum.iteritems()):
297 remoteheads, newheads, unsyncedheads = heads
297 remoteheads, newheads, unsyncedheads = heads
298 candidate_newhs = set(newheads)
298 candidate_newhs = set(newheads)
299 # add unsynced data
299 # add unsynced data
300 if remoteheads is None:
300 if remoteheads is None:
301 oldhs = set()
301 oldhs = set()
302 else:
302 else:
303 oldhs = set(remoteheads)
303 oldhs = set(remoteheads)
304 oldhs.update(unsyncedheads)
304 oldhs.update(unsyncedheads)
305 candidate_newhs.update(unsyncedheads)
305 candidate_newhs.update(unsyncedheads)
306 dhs = None # delta heads, the new heads on branch
306 dhs = None # delta heads, the new heads on branch
307 discardedheads = set()
307 discardedheads = set()
308 if not repo.obsstore:
308 if not repo.obsstore:
309 newhs = candidate_newhs
309 newhs = candidate_newhs
310 else:
310 else:
311 # remove future heads which are actually obsoleted by another
311 # remove future heads which are actually obsoleted by another
312 # pushed element:
312 # pushed element:
313 #
313 #
314 # XXX as above, There are several cases this code does not handle
314 # XXX as above, There are several cases this code does not handle
315 # XXX properly
315 # XXX properly
316 #
316 #
317 # (1) if <nh> is public, it won't be affected by obsolete marker
317 # (1) if <nh> is public, it won't be affected by obsolete marker
318 # and a new is created
318 # and a new is created
319 #
319 #
320 # (2) if the new heads have ancestors which are not obsolete and
320 # (2) if the new heads have ancestors which are not obsolete and
321 # not ancestors of any other heads we will have a new head too.
321 # not ancestors of any other heads we will have a new head too.
322 #
322 #
323 # These two cases will be easy to handle for known changeset but
323 # These two cases will be easy to handle for known changeset but
324 # much more tricky for unsynced changes.
324 # much more tricky for unsynced changes.
325 #
325 #
326 # In addition, this code is confused by prune as it only looks for
326 # In addition, this code is confused by prune as it only looks for
327 # successors of the heads (none if pruned) leading to issue4354
327 # successors of the heads (none if pruned) leading to issue4354
328 newhs = set()
328 newhs = set()
329 for nh in candidate_newhs:
329 for nh in candidate_newhs:
330 if nh in repo and repo[nh].phase() <= phases.public:
330 if nh in repo and repo[nh].phase() <= phases.public:
331 newhs.add(nh)
331 newhs.add(nh)
332 else:
332 else:
333 for suc in obsolete.allsuccessors(repo.obsstore, [nh]):
333 for suc in obsolete.allsuccessors(repo.obsstore, [nh]):
334 if suc != nh and suc in allfuturecommon:
334 if suc != nh and suc in allfuturecommon:
335 discardedheads.add(nh)
335 discardedheads.add(nh)
336 break
336 break
337 else:
337 else:
338 newhs.add(nh)
338 newhs.add(nh)
339 unsynced = sorted(h for h in unsyncedheads if h not in discardedheads)
339 unsynced = sorted(h for h in unsyncedheads if h not in discardedheads)
340 if unsynced:
340 if unsynced:
341 if None in unsynced:
341 if None in unsynced:
342 # old remote, no heads data
342 # old remote, no heads data
343 heads = None
343 heads = None
344 elif len(unsynced) <= 4 or repo.ui.verbose:
344 elif len(unsynced) <= 4 or repo.ui.verbose:
345 heads = ' '.join(short(h) for h in unsynced)
345 heads = ' '.join(short(h) for h in unsynced)
346 else:
346 else:
347 heads = (' '.join(short(h) for h in unsynced[:4]) +
347 heads = (' '.join(short(h) for h in unsynced[:4]) +
348 ' ' + _("and %s others") % (len(unsynced) - 4))
348 ' ' + _("and %s others") % (len(unsynced) - 4))
349 if heads is None:
349 if heads is None:
350 repo.ui.status(_("remote has heads that are "
350 repo.ui.status(_("remote has heads that are "
351 "not known locally\n"))
351 "not known locally\n"))
352 elif branch is None:
352 elif branch is None:
353 repo.ui.status(_("remote has heads that are "
353 repo.ui.status(_("remote has heads that are "
354 "not known locally: %s\n") % heads)
354 "not known locally: %s\n") % heads)
355 else:
355 else:
356 repo.ui.status(_("remote has heads on branch '%s' that are "
356 repo.ui.status(_("remote has heads on branch '%s' that are "
357 "not known locally: %s\n") % (branch, heads))
357 "not known locally: %s\n") % (branch, heads))
358 if remoteheads is None:
358 if remoteheads is None:
359 if len(newhs) > 1:
359 if len(newhs) > 1:
360 dhs = list(newhs)
360 dhs = list(newhs)
361 if errormsg is None:
361 if errormsg is None:
362 errormsg = (_("push creates new branch '%s' "
362 errormsg = (_("push creates new branch '%s' "
363 "with multiple heads") % (branch))
363 "with multiple heads") % (branch))
364 hint = _("merge or"
364 hint = _("merge or"
365 " see \"hg help push\" for details about"
365 " see \"hg help push\" for details about"
366 " pushing new heads")
366 " pushing new heads")
367 elif len(newhs) > len(oldhs):
367 elif len(newhs) > len(oldhs):
368 # remove bookmarked or existing remote heads from the new heads list
368 # remove bookmarked or existing remote heads from the new heads list
369 dhs = sorted(newhs - bookmarkedheads - oldhs)
369 dhs = sorted(newhs - bookmarkedheads - oldhs)
370 if dhs:
370 if dhs:
371 if errormsg is None:
371 if errormsg is None:
372 if branch not in ('default', None):
372 if branch not in ('default', None):
373 errormsg = _("push creates new remote head %s "
373 errormsg = _("push creates new remote head %s "
374 "on branch '%s'!") % (short(dhs[0]), branch)
374 "on branch '%s'!") % (short(dhs[0]), branch)
375 elif repo[dhs[0]].bookmarks():
375 elif repo[dhs[0]].bookmarks():
376 errormsg = _("push creates new remote head %s "
376 errormsg = _("push creates new remote head %s "
377 "with bookmark '%s'!") % (
377 "with bookmark '%s'!") % (
378 short(dhs[0]), repo[dhs[0]].bookmarks()[0])
378 short(dhs[0]), repo[dhs[0]].bookmarks()[0])
379 else:
379 else:
380 errormsg = _("push creates new remote head %s!"
380 errormsg = _("push creates new remote head %s!"
381 ) % short(dhs[0])
381 ) % short(dhs[0])
382 if unsyncedheads:
382 if unsyncedheads:
383 hint = _("pull and merge or"
383 hint = _("pull and merge or"
384 " see \"hg help push\" for details about"
384 " see \"hg help push\" for details about"
385 " pushing new heads")
385 " pushing new heads")
386 else:
386 else:
387 hint = _("merge or"
387 hint = _("merge or"
388 " see \"hg help push\" for details about"
388 " see \"hg help push\" for details about"
389 " pushing new heads")
389 " pushing new heads")
390 if branch is None:
390 if branch is None:
391 repo.ui.note(_("new remote heads:\n"))
391 repo.ui.note(_("new remote heads:\n"))
392 else:
392 else:
393 repo.ui.note(_("new remote heads on branch '%s':\n") % branch)
393 repo.ui.note(_("new remote heads on branch '%s':\n") % branch)
394 for h in dhs:
394 for h in dhs:
395 repo.ui.note((" %s\n") % short(h))
395 repo.ui.note((" %s\n") % short(h))
396 if errormsg:
396 if errormsg:
397 raise error.Abort(errormsg, hint=hint)
397 raise error.Abort(errormsg, hint=hint)
@@ -1,807 +1,827
1 #require serve
1 #require serve
2
2
3 $ cat << EOF >> $HGRCPATH
3 $ cat << EOF >> $HGRCPATH
4 > [ui]
4 > [ui]
5 > logtemplate={rev}:{node|short} {desc|firstline}
5 > logtemplate={rev}:{node|short} {desc|firstline}
6 > [phases]
6 > [phases]
7 > publish=False
7 > publish=False
8 > [experimental]
8 > [experimental]
9 > evolution=createmarkers,exchange
9 > evolution=createmarkers,exchange
10 > # drop me once bundle2 is the default,
10 > # drop me once bundle2 is the default,
11 > # added to get test change early.
11 > # added to get test change early.
12 > bundle2-exp = True
12 > bundle2-exp = True
13 > EOF
13 > EOF
14
14
15 initialize
15 initialize
16
16
17 $ hg init a
17 $ hg init a
18 $ cd a
18 $ cd a
19 $ echo 'test' > test
19 $ echo 'test' > test
20 $ hg commit -Am'test'
20 $ hg commit -Am'test'
21 adding test
21 adding test
22
22
23 set bookmarks
23 set bookmarks
24
24
25 $ hg bookmark X
25 $ hg bookmark X
26 $ hg bookmark Y
26 $ hg bookmark Y
27 $ hg bookmark Z
27 $ hg bookmark Z
28
28
29 import bookmark by name
29 import bookmark by name
30
30
31 $ hg init ../b
31 $ hg init ../b
32 $ cd ../b
32 $ cd ../b
33 $ hg book Y
33 $ hg book Y
34 $ hg book
34 $ hg book
35 * Y -1:000000000000
35 * Y -1:000000000000
36 $ hg pull ../a
36 $ hg pull ../a
37 pulling from ../a
37 pulling from ../a
38 requesting all changes
38 requesting all changes
39 adding changesets
39 adding changesets
40 adding manifests
40 adding manifests
41 adding file changes
41 adding file changes
42 added 1 changesets with 1 changes to 1 files
42 added 1 changesets with 1 changes to 1 files
43 adding remote bookmark X
43 adding remote bookmark X
44 updating bookmark Y
44 updating bookmark Y
45 adding remote bookmark Z
45 adding remote bookmark Z
46 (run 'hg update' to get a working copy)
46 (run 'hg update' to get a working copy)
47 $ hg bookmarks
47 $ hg bookmarks
48 X 0:4e3505fd9583
48 X 0:4e3505fd9583
49 * Y 0:4e3505fd9583
49 * Y 0:4e3505fd9583
50 Z 0:4e3505fd9583
50 Z 0:4e3505fd9583
51 $ hg debugpushkey ../a namespaces
51 $ hg debugpushkey ../a namespaces
52 bookmarks
52 bookmarks
53 namespaces
53 namespaces
54 obsolete
54 obsolete
55 phases
55 phases
56 $ hg debugpushkey ../a bookmarks
56 $ hg debugpushkey ../a bookmarks
57 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
57 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
58 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
58 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
59 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
59 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
60
60
61 delete the bookmark to re-pull it
61 delete the bookmark to re-pull it
62
62
63 $ hg book -d X
63 $ hg book -d X
64 $ hg pull -B X ../a
64 $ hg pull -B X ../a
65 pulling from ../a
65 pulling from ../a
66 no changes found
66 no changes found
67 adding remote bookmark X
67 adding remote bookmark X
68
68
69 finally no-op pull
69 finally no-op pull
70
70
71 $ hg pull -B X ../a
71 $ hg pull -B X ../a
72 pulling from ../a
72 pulling from ../a
73 no changes found
73 no changes found
74 $ hg bookmark
74 $ hg bookmark
75 X 0:4e3505fd9583
75 X 0:4e3505fd9583
76 * Y 0:4e3505fd9583
76 * Y 0:4e3505fd9583
77 Z 0:4e3505fd9583
77 Z 0:4e3505fd9583
78
78
79 export bookmark by name
79 export bookmark by name
80
80
81 $ hg bookmark W
81 $ hg bookmark W
82 $ hg bookmark foo
82 $ hg bookmark foo
83 $ hg bookmark foobar
83 $ hg bookmark foobar
84 $ hg push -B W ../a
84 $ hg push -B W ../a
85 pushing to ../a
85 pushing to ../a
86 searching for changes
86 searching for changes
87 no changes found
87 no changes found
88 exporting bookmark W
88 exporting bookmark W
89 [1]
89 [1]
90 $ hg -R ../a bookmarks
90 $ hg -R ../a bookmarks
91 W -1:000000000000
91 W -1:000000000000
92 X 0:4e3505fd9583
92 X 0:4e3505fd9583
93 Y 0:4e3505fd9583
93 Y 0:4e3505fd9583
94 * Z 0:4e3505fd9583
94 * Z 0:4e3505fd9583
95
95
96 delete a remote bookmark
96 delete a remote bookmark
97
97
98 $ hg book -d W
98 $ hg book -d W
99 $ hg push -B W ../a
99 $ hg push -B W ../a
100 pushing to ../a
100 pushing to ../a
101 searching for changes
101 searching for changes
102 no changes found
102 no changes found
103 deleting remote bookmark W
103 deleting remote bookmark W
104 [1]
104 [1]
105
105
106 push/pull name that doesn't exist
106 push/pull name that doesn't exist
107
107
108 $ hg push -B badname ../a
108 $ hg push -B badname ../a
109 pushing to ../a
109 pushing to ../a
110 searching for changes
110 searching for changes
111 bookmark badname does not exist on the local or remote repository!
111 bookmark badname does not exist on the local or remote repository!
112 no changes found
112 no changes found
113 [2]
113 [2]
114 $ hg pull -B anotherbadname ../a
114 $ hg pull -B anotherbadname ../a
115 pulling from ../a
115 pulling from ../a
116 abort: remote bookmark anotherbadname not found!
116 abort: remote bookmark anotherbadname not found!
117 [255]
117 [255]
118
118
119 divergent bookmarks
119 divergent bookmarks
120
120
121 $ cd ../a
121 $ cd ../a
122 $ echo c1 > f1
122 $ echo c1 > f1
123 $ hg ci -Am1
123 $ hg ci -Am1
124 adding f1
124 adding f1
125 $ hg book -f @
125 $ hg book -f @
126 $ hg book -f X
126 $ hg book -f X
127 $ hg book
127 $ hg book
128 @ 1:0d2164f0ce0d
128 @ 1:0d2164f0ce0d
129 * X 1:0d2164f0ce0d
129 * X 1:0d2164f0ce0d
130 Y 0:4e3505fd9583
130 Y 0:4e3505fd9583
131 Z 1:0d2164f0ce0d
131 Z 1:0d2164f0ce0d
132
132
133 $ cd ../b
133 $ cd ../b
134 $ hg up
134 $ hg up
135 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
135 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
136 updating bookmark foobar
136 updating bookmark foobar
137 $ echo c2 > f2
137 $ echo c2 > f2
138 $ hg ci -Am2
138 $ hg ci -Am2
139 adding f2
139 adding f2
140 $ hg book -if @
140 $ hg book -if @
141 $ hg book -if X
141 $ hg book -if X
142 $ hg book
142 $ hg book
143 @ 1:9b140be10808
143 @ 1:9b140be10808
144 X 1:9b140be10808
144 X 1:9b140be10808
145 Y 0:4e3505fd9583
145 Y 0:4e3505fd9583
146 Z 0:4e3505fd9583
146 Z 0:4e3505fd9583
147 foo -1:000000000000
147 foo -1:000000000000
148 * foobar 1:9b140be10808
148 * foobar 1:9b140be10808
149
149
150 $ hg pull --config paths.foo=../a foo
150 $ hg pull --config paths.foo=../a foo
151 pulling from $TESTTMP/a (glob)
151 pulling from $TESTTMP/a (glob)
152 searching for changes
152 searching for changes
153 adding changesets
153 adding changesets
154 adding manifests
154 adding manifests
155 adding file changes
155 adding file changes
156 added 1 changesets with 1 changes to 1 files (+1 heads)
156 added 1 changesets with 1 changes to 1 files (+1 heads)
157 divergent bookmark @ stored as @foo
157 divergent bookmark @ stored as @foo
158 divergent bookmark X stored as X@foo
158 divergent bookmark X stored as X@foo
159 updating bookmark Z
159 updating bookmark Z
160 (run 'hg heads' to see heads, 'hg merge' to merge)
160 (run 'hg heads' to see heads, 'hg merge' to merge)
161 $ hg book
161 $ hg book
162 @ 1:9b140be10808
162 @ 1:9b140be10808
163 @foo 2:0d2164f0ce0d
163 @foo 2:0d2164f0ce0d
164 X 1:9b140be10808
164 X 1:9b140be10808
165 X@foo 2:0d2164f0ce0d
165 X@foo 2:0d2164f0ce0d
166 Y 0:4e3505fd9583
166 Y 0:4e3505fd9583
167 Z 2:0d2164f0ce0d
167 Z 2:0d2164f0ce0d
168 foo -1:000000000000
168 foo -1:000000000000
169 * foobar 1:9b140be10808
169 * foobar 1:9b140be10808
170
170
171 (test that too many divergence of bookmark)
171 (test that too many divergence of bookmark)
172
172
173 $ python $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -r 000000000000 "X@${i}"; done
173 $ python $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -r 000000000000 "X@${i}"; done
174 $ hg pull ../a
174 $ hg pull ../a
175 pulling from ../a
175 pulling from ../a
176 searching for changes
176 searching for changes
177 no changes found
177 no changes found
178 warning: failed to assign numbered name to divergent bookmark X
178 warning: failed to assign numbered name to divergent bookmark X
179 divergent bookmark @ stored as @1
179 divergent bookmark @ stored as @1
180 $ hg bookmarks | grep '^ X' | grep -v ':000000000000'
180 $ hg bookmarks | grep '^ X' | grep -v ':000000000000'
181 X 1:9b140be10808
181 X 1:9b140be10808
182 X@foo 2:0d2164f0ce0d
182 X@foo 2:0d2164f0ce0d
183
183
184 (test that remotely diverged bookmarks are reused if they aren't changed)
184 (test that remotely diverged bookmarks are reused if they aren't changed)
185
185
186 $ hg bookmarks | grep '^ @'
186 $ hg bookmarks | grep '^ @'
187 @ 1:9b140be10808
187 @ 1:9b140be10808
188 @1 2:0d2164f0ce0d
188 @1 2:0d2164f0ce0d
189 @foo 2:0d2164f0ce0d
189 @foo 2:0d2164f0ce0d
190 $ hg pull ../a
190 $ hg pull ../a
191 pulling from ../a
191 pulling from ../a
192 searching for changes
192 searching for changes
193 no changes found
193 no changes found
194 warning: failed to assign numbered name to divergent bookmark X
194 warning: failed to assign numbered name to divergent bookmark X
195 divergent bookmark @ stored as @1
195 divergent bookmark @ stored as @1
196 $ hg bookmarks | grep '^ @'
196 $ hg bookmarks | grep '^ @'
197 @ 1:9b140be10808
197 @ 1:9b140be10808
198 @1 2:0d2164f0ce0d
198 @1 2:0d2164f0ce0d
199 @foo 2:0d2164f0ce0d
199 @foo 2:0d2164f0ce0d
200
200
201 $ python $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -d "X@${i}"; done
201 $ python $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -d "X@${i}"; done
202 $ hg bookmarks -d "@1"
202 $ hg bookmarks -d "@1"
203
203
204 $ hg push -f ../a
204 $ hg push -f ../a
205 pushing to ../a
205 pushing to ../a
206 searching for changes
206 searching for changes
207 adding changesets
207 adding changesets
208 adding manifests
208 adding manifests
209 adding file changes
209 adding file changes
210 added 1 changesets with 1 changes to 1 files (+1 heads)
210 added 1 changesets with 1 changes to 1 files (+1 heads)
211 $ hg -R ../a book
211 $ hg -R ../a book
212 @ 1:0d2164f0ce0d
212 @ 1:0d2164f0ce0d
213 * X 1:0d2164f0ce0d
213 * X 1:0d2164f0ce0d
214 Y 0:4e3505fd9583
214 Y 0:4e3505fd9583
215 Z 1:0d2164f0ce0d
215 Z 1:0d2164f0ce0d
216
216
217 explicit pull should overwrite the local version (issue4439)
217 explicit pull should overwrite the local version (issue4439)
218
218
219 $ hg pull --config paths.foo=../a foo -B X
219 $ hg pull --config paths.foo=../a foo -B X
220 pulling from $TESTTMP/a (glob)
220 pulling from $TESTTMP/a (glob)
221 no changes found
221 no changes found
222 divergent bookmark @ stored as @foo
222 divergent bookmark @ stored as @foo
223 importing bookmark X
223 importing bookmark X
224
224
225 reinstall state for further testing:
225 reinstall state for further testing:
226
226
227 $ hg book -fr 9b140be10808 X
227 $ hg book -fr 9b140be10808 X
228
228
229 revsets should not ignore divergent bookmarks
229 revsets should not ignore divergent bookmarks
230
230
231 $ hg bookmark -fr 1 Z
231 $ hg bookmark -fr 1 Z
232 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
232 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
233 0:4e3505fd9583 Y
233 0:4e3505fd9583 Y
234 1:9b140be10808 @ X Z foobar
234 1:9b140be10808 @ X Z foobar
235 2:0d2164f0ce0d @foo X@foo
235 2:0d2164f0ce0d @foo X@foo
236 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
236 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
237 2:0d2164f0ce0d @foo X@foo
237 2:0d2164f0ce0d @foo X@foo
238 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
238 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
239 2:0d2164f0ce0d @foo X@foo
239 2:0d2164f0ce0d @foo X@foo
240
240
241 update a remote bookmark from a non-head to a head
241 update a remote bookmark from a non-head to a head
242
242
243 $ hg up -q Y
243 $ hg up -q Y
244 $ echo c3 > f2
244 $ echo c3 > f2
245 $ hg ci -Am3
245 $ hg ci -Am3
246 adding f2
246 adding f2
247 created new head
247 created new head
248 $ hg push ../a
248 $ hg push ../a
249 pushing to ../a
249 pushing to ../a
250 searching for changes
250 searching for changes
251 adding changesets
251 adding changesets
252 adding manifests
252 adding manifests
253 adding file changes
253 adding file changes
254 added 1 changesets with 1 changes to 1 files (+1 heads)
254 added 1 changesets with 1 changes to 1 files (+1 heads)
255 updating bookmark Y
255 updating bookmark Y
256 $ hg -R ../a book
256 $ hg -R ../a book
257 @ 1:0d2164f0ce0d
257 @ 1:0d2164f0ce0d
258 * X 1:0d2164f0ce0d
258 * X 1:0d2164f0ce0d
259 Y 3:f6fc62dde3c0
259 Y 3:f6fc62dde3c0
260 Z 1:0d2164f0ce0d
260 Z 1:0d2164f0ce0d
261
261
262 update a bookmark in the middle of a client pulling changes
262 update a bookmark in the middle of a client pulling changes
263
263
264 $ cd ..
264 $ cd ..
265 $ hg clone -q a pull-race
265 $ hg clone -q a pull-race
266
266
267 We want to use http because it is stateless and therefore more susceptible to
267 We want to use http because it is stateless and therefore more susceptible to
268 race conditions
268 race conditions
269
269
270 $ hg -R pull-race serve -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
270 $ hg -R pull-race serve -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
271 $ cat pull-race.pid >> $DAEMON_PIDS
271 $ cat pull-race.pid >> $DAEMON_PIDS
272
272
273 $ hg clone -q http://localhost:$HGPORT/ pull-race2
273 $ hg clone -q http://localhost:$HGPORT/ pull-race2
274 $ cd pull-race
274 $ cd pull-race
275 $ hg up -q Y
275 $ hg up -q Y
276 $ echo c4 > f2
276 $ echo c4 > f2
277 $ hg ci -Am4
277 $ hg ci -Am4
278 $ echo c5 > f3
278 $ echo c5 > f3
279 $ cat <<EOF > .hg/hgrc
279 $ cat <<EOF > .hg/hgrc
280 > [hooks]
280 > [hooks]
281 > outgoing.makecommit = hg ci -Am5; echo committed in pull-race
281 > outgoing.makecommit = hg ci -Am5; echo committed in pull-race
282 > EOF
282 > EOF
283
283
284 (new config needs a server restart)
284 (new config needs a server restart)
285
285
286 $ cd ..
286 $ cd ..
287 $ killdaemons.py
287 $ killdaemons.py
288 $ hg -R pull-race serve -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
288 $ hg -R pull-race serve -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
289 $ cat pull-race.pid >> $DAEMON_PIDS
289 $ cat pull-race.pid >> $DAEMON_PIDS
290 $ cd pull-race2
290 $ cd pull-race2
291 $ hg -R $TESTTMP/pull-race book
291 $ hg -R $TESTTMP/pull-race book
292 @ 1:0d2164f0ce0d
292 @ 1:0d2164f0ce0d
293 X 1:0d2164f0ce0d
293 X 1:0d2164f0ce0d
294 * Y 4:b0a5eff05604
294 * Y 4:b0a5eff05604
295 Z 1:0d2164f0ce0d
295 Z 1:0d2164f0ce0d
296 $ hg pull
296 $ hg pull
297 pulling from http://localhost:$HGPORT/
297 pulling from http://localhost:$HGPORT/
298 searching for changes
298 searching for changes
299 adding changesets
299 adding changesets
300 adding manifests
300 adding manifests
301 adding file changes
301 adding file changes
302 added 1 changesets with 1 changes to 1 files
302 added 1 changesets with 1 changes to 1 files
303 updating bookmark Y
303 updating bookmark Y
304 (run 'hg update' to get a working copy)
304 (run 'hg update' to get a working copy)
305 $ hg book
305 $ hg book
306 * @ 1:0d2164f0ce0d
306 * @ 1:0d2164f0ce0d
307 X 1:0d2164f0ce0d
307 X 1:0d2164f0ce0d
308 Y 4:b0a5eff05604
308 Y 4:b0a5eff05604
309 Z 1:0d2164f0ce0d
309 Z 1:0d2164f0ce0d
310
310
311 Update a bookmark right after the initial lookup -B (issue4689)
311 Update a bookmark right after the initial lookup -B (issue4689)
312
312
313 $ echo c6 > ../pull-race/f3 # to be committed during the race
313 $ echo c6 > ../pull-race/f3 # to be committed during the race
314 $ cat <<EOF > ../pull-race/.hg/hgrc
314 $ cat <<EOF > ../pull-race/.hg/hgrc
315 > [hooks]
315 > [hooks]
316 > # If anything to commit, commit it right after the first key listing used
316 > # If anything to commit, commit it right after the first key listing used
317 > # during lookup. This makes the commit appear before the actual getbundle
317 > # during lookup. This makes the commit appear before the actual getbundle
318 > # call.
318 > # call.
319 > listkeys.makecommit= ((hg st | grep -q M) && (hg commit -m race; echo commited in pull-race)) || exit 0
319 > listkeys.makecommit= ((hg st | grep -q M) && (hg commit -m race; echo commited in pull-race)) || exit 0
320 > EOF
320 > EOF
321
321
322 (new config need server restart)
322 (new config need server restart)
323
323
324 $ killdaemons.py
324 $ killdaemons.py
325 $ hg -R ../pull-race serve -p $HGPORT -d --pid-file=../pull-race.pid -E main-error.log
325 $ hg -R ../pull-race serve -p $HGPORT -d --pid-file=../pull-race.pid -E main-error.log
326 $ cat ../pull-race.pid >> $DAEMON_PIDS
326 $ cat ../pull-race.pid >> $DAEMON_PIDS
327
327
328 $ hg -R $TESTTMP/pull-race book
328 $ hg -R $TESTTMP/pull-race book
329 @ 1:0d2164f0ce0d
329 @ 1:0d2164f0ce0d
330 X 1:0d2164f0ce0d
330 X 1:0d2164f0ce0d
331 * Y 5:35d1ef0a8d1b
331 * Y 5:35d1ef0a8d1b
332 Z 1:0d2164f0ce0d
332 Z 1:0d2164f0ce0d
333 $ hg pull -B Y
333 $ hg pull -B Y
334 pulling from http://localhost:$HGPORT/
334 pulling from http://localhost:$HGPORT/
335 searching for changes
335 searching for changes
336 adding changesets
336 adding changesets
337 adding manifests
337 adding manifests
338 adding file changes
338 adding file changes
339 added 1 changesets with 1 changes to 1 files
339 added 1 changesets with 1 changes to 1 files
340 updating bookmark Y
340 updating bookmark Y
341 (run 'hg update' to get a working copy)
341 (run 'hg update' to get a working copy)
342 $ hg book
342 $ hg book
343 * @ 1:0d2164f0ce0d
343 * @ 1:0d2164f0ce0d
344 X 1:0d2164f0ce0d
344 X 1:0d2164f0ce0d
345 Y 5:35d1ef0a8d1b
345 Y 5:35d1ef0a8d1b
346 Z 1:0d2164f0ce0d
346 Z 1:0d2164f0ce0d
347
347
348 (done with this section of the test)
348 (done with this section of the test)
349
349
350 $ killdaemons.py
350 $ killdaemons.py
351 $ cd ../b
351 $ cd ../b
352
352
353 diverging a remote bookmark fails
353 diverging a remote bookmark fails
354
354
355 $ hg up -q 4e3505fd9583
355 $ hg up -q 4e3505fd9583
356 $ echo c4 > f2
356 $ echo c4 > f2
357 $ hg ci -Am4
357 $ hg ci -Am4
358 adding f2
358 adding f2
359 created new head
359 created new head
360 $ echo c5 > f2
360 $ echo c5 > f2
361 $ hg ci -Am5
361 $ hg ci -Am5
362 $ hg log -G
362 $ hg log -G
363 @ 5:c922c0139ca0 5
363 @ 5:c922c0139ca0 5
364 |
364 |
365 o 4:4efff6d98829 4
365 o 4:4efff6d98829 4
366 |
366 |
367 | o 3:f6fc62dde3c0 3
367 | o 3:f6fc62dde3c0 3
368 |/
368 |/
369 | o 2:0d2164f0ce0d 1
369 | o 2:0d2164f0ce0d 1
370 |/
370 |/
371 | o 1:9b140be10808 2
371 | o 1:9b140be10808 2
372 |/
372 |/
373 o 0:4e3505fd9583 test
373 o 0:4e3505fd9583 test
374
374
375
375
376 $ hg book -f Y
376 $ hg book -f Y
377
377
378 $ cat <<EOF > ../a/.hg/hgrc
378 $ cat <<EOF > ../a/.hg/hgrc
379 > [web]
379 > [web]
380 > push_ssl = false
380 > push_ssl = false
381 > allow_push = *
381 > allow_push = *
382 > EOF
382 > EOF
383
383
384 $ hg -R ../a serve -p $HGPORT2 -d --pid-file=../hg2.pid
384 $ hg -R ../a serve -p $HGPORT2 -d --pid-file=../hg2.pid
385 $ cat ../hg2.pid >> $DAEMON_PIDS
385 $ cat ../hg2.pid >> $DAEMON_PIDS
386
386
387 $ hg push http://localhost:$HGPORT2/
387 $ hg push http://localhost:$HGPORT2/
388 pushing to http://localhost:$HGPORT2/
388 pushing to http://localhost:$HGPORT2/
389 searching for changes
389 searching for changes
390 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
390 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
391 (merge or see "hg help push" for details about pushing new heads)
391 (merge or see "hg help push" for details about pushing new heads)
392 [255]
392 [255]
393 $ hg -R ../a book
393 $ hg -R ../a book
394 @ 1:0d2164f0ce0d
394 @ 1:0d2164f0ce0d
395 * X 1:0d2164f0ce0d
395 * X 1:0d2164f0ce0d
396 Y 3:f6fc62dde3c0
396 Y 3:f6fc62dde3c0
397 Z 1:0d2164f0ce0d
397 Z 1:0d2164f0ce0d
398
398
399
399
400 Unrelated marker does not alter the decision
400 Unrelated marker does not alter the decision
401
401
402 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
402 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
403 $ hg push http://localhost:$HGPORT2/
403 $ hg push http://localhost:$HGPORT2/
404 pushing to http://localhost:$HGPORT2/
404 pushing to http://localhost:$HGPORT2/
405 searching for changes
405 searching for changes
406 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
406 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
407 (merge or see "hg help push" for details about pushing new heads)
407 (merge or see "hg help push" for details about pushing new heads)
408 [255]
408 [255]
409 $ hg -R ../a book
409 $ hg -R ../a book
410 @ 1:0d2164f0ce0d
410 @ 1:0d2164f0ce0d
411 * X 1:0d2164f0ce0d
411 * X 1:0d2164f0ce0d
412 Y 3:f6fc62dde3c0
412 Y 3:f6fc62dde3c0
413 Z 1:0d2164f0ce0d
413 Z 1:0d2164f0ce0d
414
414
415 Update to a successor works
415 Update to a successor works
416
416
417 $ hg id --debug -r 3
417 $ hg id --debug -r 3
418 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
418 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
419 $ hg id --debug -r 4
419 $ hg id --debug -r 4
420 4efff6d98829d9c824c621afd6e3f01865f5439f
420 4efff6d98829d9c824c621afd6e3f01865f5439f
421 $ hg id --debug -r 5
421 $ hg id --debug -r 5
422 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
422 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
423 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
423 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
424 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
424 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
425 $ hg push http://localhost:$HGPORT2/
425 $ hg push http://localhost:$HGPORT2/
426 pushing to http://localhost:$HGPORT2/
426 pushing to http://localhost:$HGPORT2/
427 searching for changes
427 searching for changes
428 remote: adding changesets
428 remote: adding changesets
429 remote: adding manifests
429 remote: adding manifests
430 remote: adding file changes
430 remote: adding file changes
431 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
431 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
432 remote: 2 new obsolescence markers
432 remote: 2 new obsolescence markers
433 updating bookmark Y
433 updating bookmark Y
434 $ hg -R ../a book
434 $ hg -R ../a book
435 @ 1:0d2164f0ce0d
435 @ 1:0d2164f0ce0d
436 * X 1:0d2164f0ce0d
436 * X 1:0d2164f0ce0d
437 Y 5:c922c0139ca0
437 Y 5:c922c0139ca0
438 Z 1:0d2164f0ce0d
438 Z 1:0d2164f0ce0d
439
439
440 hgweb
440 hgweb
441
441
442 $ cat <<EOF > .hg/hgrc
442 $ cat <<EOF > .hg/hgrc
443 > [web]
443 > [web]
444 > push_ssl = false
444 > push_ssl = false
445 > allow_push = *
445 > allow_push = *
446 > EOF
446 > EOF
447
447
448 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
448 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
449 $ cat ../hg.pid >> $DAEMON_PIDS
449 $ cat ../hg.pid >> $DAEMON_PIDS
450 $ cd ../a
450 $ cd ../a
451
451
452 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
452 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
453 bookmarks
453 bookmarks
454 namespaces
454 namespaces
455 obsolete
455 obsolete
456 phases
456 phases
457 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
457 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
458 @ 9b140be1080824d768c5a4691a564088eede71f9
458 @ 9b140be1080824d768c5a4691a564088eede71f9
459 X 9b140be1080824d768c5a4691a564088eede71f9
459 X 9b140be1080824d768c5a4691a564088eede71f9
460 Y c922c0139ca03858f655e4a2af4dd02796a63969
460 Y c922c0139ca03858f655e4a2af4dd02796a63969
461 Z 9b140be1080824d768c5a4691a564088eede71f9
461 Z 9b140be1080824d768c5a4691a564088eede71f9
462 foo 0000000000000000000000000000000000000000
462 foo 0000000000000000000000000000000000000000
463 foobar 9b140be1080824d768c5a4691a564088eede71f9
463 foobar 9b140be1080824d768c5a4691a564088eede71f9
464 $ hg out -B http://localhost:$HGPORT/
464 $ hg out -B http://localhost:$HGPORT/
465 comparing with http://localhost:$HGPORT/
465 comparing with http://localhost:$HGPORT/
466 searching for changed bookmarks
466 searching for changed bookmarks
467 @ 0d2164f0ce0d
467 @ 0d2164f0ce0d
468 X 0d2164f0ce0d
468 X 0d2164f0ce0d
469 Z 0d2164f0ce0d
469 Z 0d2164f0ce0d
470 foo
470 foo
471 foobar
471 foobar
472 $ hg push -B Z http://localhost:$HGPORT/
472 $ hg push -B Z http://localhost:$HGPORT/
473 pushing to http://localhost:$HGPORT/
473 pushing to http://localhost:$HGPORT/
474 searching for changes
474 searching for changes
475 no changes found
475 no changes found
476 updating bookmark Z
476 updating bookmark Z
477 [1]
477 [1]
478 $ hg book -d Z
478 $ hg book -d Z
479 $ hg in -B http://localhost:$HGPORT/
479 $ hg in -B http://localhost:$HGPORT/
480 comparing with http://localhost:$HGPORT/
480 comparing with http://localhost:$HGPORT/
481 searching for changed bookmarks
481 searching for changed bookmarks
482 @ 9b140be10808
482 @ 9b140be10808
483 X 9b140be10808
483 X 9b140be10808
484 Z 0d2164f0ce0d
484 Z 0d2164f0ce0d
485 foo 000000000000
485 foo 000000000000
486 foobar 9b140be10808
486 foobar 9b140be10808
487 $ hg pull -B Z http://localhost:$HGPORT/
487 $ hg pull -B Z http://localhost:$HGPORT/
488 pulling from http://localhost:$HGPORT/
488 pulling from http://localhost:$HGPORT/
489 no changes found
489 no changes found
490 divergent bookmark @ stored as @1
490 divergent bookmark @ stored as @1
491 divergent bookmark X stored as X@1
491 divergent bookmark X stored as X@1
492 adding remote bookmark Z
492 adding remote bookmark Z
493 adding remote bookmark foo
493 adding remote bookmark foo
494 adding remote bookmark foobar
494 adding remote bookmark foobar
495 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
495 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
496 requesting all changes
496 requesting all changes
497 adding changesets
497 adding changesets
498 adding manifests
498 adding manifests
499 adding file changes
499 adding file changes
500 added 5 changesets with 5 changes to 3 files (+2 heads)
500 added 5 changesets with 5 changes to 3 files (+2 heads)
501 2 new obsolescence markers
501 2 new obsolescence markers
502 updating to bookmark @
502 updating to bookmark @
503 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
503 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
504 $ hg -R cloned-bookmarks bookmarks
504 $ hg -R cloned-bookmarks bookmarks
505 * @ 1:9b140be10808
505 * @ 1:9b140be10808
506 X 1:9b140be10808
506 X 1:9b140be10808
507 Y 4:c922c0139ca0
507 Y 4:c922c0139ca0
508 Z 2:0d2164f0ce0d
508 Z 2:0d2164f0ce0d
509 foo -1:000000000000
509 foo -1:000000000000
510 foobar 1:9b140be10808
510 foobar 1:9b140be10808
511
511
512 $ cd ..
512 $ cd ..
513
513
514 Test to show result of bookmarks comparision
514 Test to show result of bookmarks comparision
515
515
516 $ mkdir bmcomparison
516 $ mkdir bmcomparison
517 $ cd bmcomparison
517 $ cd bmcomparison
518
518
519 $ hg init source
519 $ hg init source
520 $ hg -R source debugbuilddag '+2*2*3*4'
520 $ hg -R source debugbuilddag '+2*2*3*4'
521 $ hg -R source log -G --template '{rev}:{node|short}'
521 $ hg -R source log -G --template '{rev}:{node|short}'
522 o 4:e7bd5218ca15
522 o 4:e7bd5218ca15
523 |
523 |
524 | o 3:6100d3090acf
524 | o 3:6100d3090acf
525 |/
525 |/
526 | o 2:fa942426a6fd
526 | o 2:fa942426a6fd
527 |/
527 |/
528 | o 1:66f7d451a68b
528 | o 1:66f7d451a68b
529 |/
529 |/
530 o 0:1ea73414a91b
530 o 0:1ea73414a91b
531
531
532 $ hg -R source bookmarks -r 0 SAME
532 $ hg -R source bookmarks -r 0 SAME
533 $ hg -R source bookmarks -r 0 ADV_ON_REPO1
533 $ hg -R source bookmarks -r 0 ADV_ON_REPO1
534 $ hg -R source bookmarks -r 0 ADV_ON_REPO2
534 $ hg -R source bookmarks -r 0 ADV_ON_REPO2
535 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO1
535 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO1
536 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO2
536 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO2
537 $ hg -R source bookmarks -r 1 DIVERGED
537 $ hg -R source bookmarks -r 1 DIVERGED
538
538
539 $ hg clone -U source repo1
539 $ hg clone -U source repo1
540
540
541 (test that incoming/outgoing exit with 1, if there is no bookmark to
541 (test that incoming/outgoing exit with 1, if there is no bookmark to
542 be exchanged)
542 be exchanged)
543
543
544 $ hg -R repo1 incoming -B
544 $ hg -R repo1 incoming -B
545 comparing with $TESTTMP/bmcomparison/source
545 comparing with $TESTTMP/bmcomparison/source
546 searching for changed bookmarks
546 searching for changed bookmarks
547 no changed bookmarks found
547 no changed bookmarks found
548 [1]
548 [1]
549 $ hg -R repo1 outgoing -B
549 $ hg -R repo1 outgoing -B
550 comparing with $TESTTMP/bmcomparison/source
550 comparing with $TESTTMP/bmcomparison/source
551 searching for changed bookmarks
551 searching for changed bookmarks
552 no changed bookmarks found
552 no changed bookmarks found
553 [1]
553 [1]
554
554
555 $ hg -R repo1 bookmarks -f -r 1 ADD_ON_REPO1
555 $ hg -R repo1 bookmarks -f -r 1 ADD_ON_REPO1
556 $ hg -R repo1 bookmarks -f -r 2 ADV_ON_REPO1
556 $ hg -R repo1 bookmarks -f -r 2 ADV_ON_REPO1
557 $ hg -R repo1 bookmarks -f -r 3 DIFF_ADV_ON_REPO1
557 $ hg -R repo1 bookmarks -f -r 3 DIFF_ADV_ON_REPO1
558 $ hg -R repo1 bookmarks -f -r 3 DIFF_DIVERGED
558 $ hg -R repo1 bookmarks -f -r 3 DIFF_DIVERGED
559 $ hg -R repo1 -q --config extensions.mq= strip 4
559 $ hg -R repo1 -q --config extensions.mq= strip 4
560 $ hg -R repo1 log -G --template '{node|short} ({bookmarks})'
560 $ hg -R repo1 log -G --template '{node|short} ({bookmarks})'
561 o 6100d3090acf (DIFF_ADV_ON_REPO1 DIFF_DIVERGED)
561 o 6100d3090acf (DIFF_ADV_ON_REPO1 DIFF_DIVERGED)
562 |
562 |
563 | o fa942426a6fd (ADV_ON_REPO1)
563 | o fa942426a6fd (ADV_ON_REPO1)
564 |/
564 |/
565 | o 66f7d451a68b (ADD_ON_REPO1 DIVERGED)
565 | o 66f7d451a68b (ADD_ON_REPO1 DIVERGED)
566 |/
566 |/
567 o 1ea73414a91b (ADV_ON_REPO2 DIFF_ADV_ON_REPO2 SAME)
567 o 1ea73414a91b (ADV_ON_REPO2 DIFF_ADV_ON_REPO2 SAME)
568
568
569
569
570 $ hg clone -U source repo2
570 $ hg clone -U source repo2
571 $ hg -R repo2 bookmarks -f -r 1 ADD_ON_REPO2
571 $ hg -R repo2 bookmarks -f -r 1 ADD_ON_REPO2
572 $ hg -R repo2 bookmarks -f -r 1 ADV_ON_REPO2
572 $ hg -R repo2 bookmarks -f -r 1 ADV_ON_REPO2
573 $ hg -R repo2 bookmarks -f -r 2 DIVERGED
573 $ hg -R repo2 bookmarks -f -r 2 DIVERGED
574 $ hg -R repo2 bookmarks -f -r 4 DIFF_ADV_ON_REPO2
574 $ hg -R repo2 bookmarks -f -r 4 DIFF_ADV_ON_REPO2
575 $ hg -R repo2 bookmarks -f -r 4 DIFF_DIVERGED
575 $ hg -R repo2 bookmarks -f -r 4 DIFF_DIVERGED
576 $ hg -R repo2 -q --config extensions.mq= strip 3
576 $ hg -R repo2 -q --config extensions.mq= strip 3
577 $ hg -R repo2 log -G --template '{node|short} ({bookmarks})'
577 $ hg -R repo2 log -G --template '{node|short} ({bookmarks})'
578 o e7bd5218ca15 (DIFF_ADV_ON_REPO2 DIFF_DIVERGED)
578 o e7bd5218ca15 (DIFF_ADV_ON_REPO2 DIFF_DIVERGED)
579 |
579 |
580 | o fa942426a6fd (DIVERGED)
580 | o fa942426a6fd (DIVERGED)
581 |/
581 |/
582 | o 66f7d451a68b (ADD_ON_REPO2 ADV_ON_REPO2)
582 | o 66f7d451a68b (ADD_ON_REPO2 ADV_ON_REPO2)
583 |/
583 |/
584 o 1ea73414a91b (ADV_ON_REPO1 DIFF_ADV_ON_REPO1 SAME)
584 o 1ea73414a91b (ADV_ON_REPO1 DIFF_ADV_ON_REPO1 SAME)
585
585
586
586
587 (test that difference of bookmarks between repositories are fully shown)
587 (test that difference of bookmarks between repositories are fully shown)
588
588
589 $ hg -R repo1 incoming -B repo2 -v
589 $ hg -R repo1 incoming -B repo2 -v
590 comparing with repo2
590 comparing with repo2
591 searching for changed bookmarks
591 searching for changed bookmarks
592 ADD_ON_REPO2 66f7d451a68b added
592 ADD_ON_REPO2 66f7d451a68b added
593 ADV_ON_REPO2 66f7d451a68b advanced
593 ADV_ON_REPO2 66f7d451a68b advanced
594 DIFF_ADV_ON_REPO2 e7bd5218ca15 changed
594 DIFF_ADV_ON_REPO2 e7bd5218ca15 changed
595 DIFF_DIVERGED e7bd5218ca15 changed
595 DIFF_DIVERGED e7bd5218ca15 changed
596 DIVERGED fa942426a6fd diverged
596 DIVERGED fa942426a6fd diverged
597 $ hg -R repo1 outgoing -B repo2 -v
597 $ hg -R repo1 outgoing -B repo2 -v
598 comparing with repo2
598 comparing with repo2
599 searching for changed bookmarks
599 searching for changed bookmarks
600 ADD_ON_REPO1 66f7d451a68b added
600 ADD_ON_REPO1 66f7d451a68b added
601 ADD_ON_REPO2 deleted
601 ADD_ON_REPO2 deleted
602 ADV_ON_REPO1 fa942426a6fd advanced
602 ADV_ON_REPO1 fa942426a6fd advanced
603 DIFF_ADV_ON_REPO1 6100d3090acf advanced
603 DIFF_ADV_ON_REPO1 6100d3090acf advanced
604 DIFF_ADV_ON_REPO2 1ea73414a91b changed
604 DIFF_ADV_ON_REPO2 1ea73414a91b changed
605 DIFF_DIVERGED 6100d3090acf changed
605 DIFF_DIVERGED 6100d3090acf changed
606 DIVERGED 66f7d451a68b diverged
606 DIVERGED 66f7d451a68b diverged
607
607
608 $ hg -R repo2 incoming -B repo1 -v
608 $ hg -R repo2 incoming -B repo1 -v
609 comparing with repo1
609 comparing with repo1
610 searching for changed bookmarks
610 searching for changed bookmarks
611 ADD_ON_REPO1 66f7d451a68b added
611 ADD_ON_REPO1 66f7d451a68b added
612 ADV_ON_REPO1 fa942426a6fd advanced
612 ADV_ON_REPO1 fa942426a6fd advanced
613 DIFF_ADV_ON_REPO1 6100d3090acf changed
613 DIFF_ADV_ON_REPO1 6100d3090acf changed
614 DIFF_DIVERGED 6100d3090acf changed
614 DIFF_DIVERGED 6100d3090acf changed
615 DIVERGED 66f7d451a68b diverged
615 DIVERGED 66f7d451a68b diverged
616 $ hg -R repo2 outgoing -B repo1 -v
616 $ hg -R repo2 outgoing -B repo1 -v
617 comparing with repo1
617 comparing with repo1
618 searching for changed bookmarks
618 searching for changed bookmarks
619 ADD_ON_REPO1 deleted
619 ADD_ON_REPO1 deleted
620 ADD_ON_REPO2 66f7d451a68b added
620 ADD_ON_REPO2 66f7d451a68b added
621 ADV_ON_REPO2 66f7d451a68b advanced
621 ADV_ON_REPO2 66f7d451a68b advanced
622 DIFF_ADV_ON_REPO1 1ea73414a91b changed
622 DIFF_ADV_ON_REPO1 1ea73414a91b changed
623 DIFF_ADV_ON_REPO2 e7bd5218ca15 advanced
623 DIFF_ADV_ON_REPO2 e7bd5218ca15 advanced
624 DIFF_DIVERGED e7bd5218ca15 changed
624 DIFF_DIVERGED e7bd5218ca15 changed
625 DIVERGED fa942426a6fd diverged
625 DIVERGED fa942426a6fd diverged
626
626
627 $ cd ..
627 $ cd ..
628
628
629 Pushing a bookmark should only push the changes required by that
629 Pushing a bookmark should only push the changes required by that
630 bookmark, not all outgoing changes:
630 bookmark, not all outgoing changes:
631 $ hg clone http://localhost:$HGPORT/ addmarks
631 $ hg clone http://localhost:$HGPORT/ addmarks
632 requesting all changes
632 requesting all changes
633 adding changesets
633 adding changesets
634 adding manifests
634 adding manifests
635 adding file changes
635 adding file changes
636 added 5 changesets with 5 changes to 3 files (+2 heads)
636 added 5 changesets with 5 changes to 3 files (+2 heads)
637 2 new obsolescence markers
637 2 new obsolescence markers
638 updating to bookmark @
638 updating to bookmark @
639 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
639 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
640 $ cd addmarks
640 $ cd addmarks
641 $ echo foo > foo
641 $ echo foo > foo
642 $ hg add foo
642 $ hg add foo
643 $ hg commit -m 'add foo'
643 $ hg commit -m 'add foo'
644 $ echo bar > bar
644 $ echo bar > bar
645 $ hg add bar
645 $ hg add bar
646 $ hg commit -m 'add bar'
646 $ hg commit -m 'add bar'
647 $ hg co "tip^"
647 $ hg co "tip^"
648 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
648 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
649 (leaving bookmark @)
649 (leaving bookmark @)
650 $ hg book add-foo
650 $ hg book add-foo
651 $ hg book -r tip add-bar
651 $ hg book -r tip add-bar
652 Note: this push *must* push only a single changeset, as that's the point
652 Note: this push *must* push only a single changeset, as that's the point
653 of this test.
653 of this test.
654 $ hg push -B add-foo --traceback
654 $ hg push -B add-foo --traceback
655 pushing to http://localhost:$HGPORT/
655 pushing to http://localhost:$HGPORT/
656 searching for changes
656 searching for changes
657 remote: adding changesets
657 remote: adding changesets
658 remote: adding manifests
658 remote: adding manifests
659 remote: adding file changes
659 remote: adding file changes
660 remote: added 1 changesets with 1 changes to 1 files
660 remote: added 1 changesets with 1 changes to 1 files
661 exporting bookmark add-foo
661 exporting bookmark add-foo
662
662
663 pushing a new bookmark on a new head does not require -f if -B is specified
663 pushing a new bookmark on a new head does not require -f if -B is specified
664
664
665 $ hg up -q X
665 $ hg up -q X
666 $ hg book W
666 $ hg book W
667 $ echo c5 > f2
667 $ echo c5 > f2
668 $ hg ci -Am5
668 $ hg ci -Am5
669 created new head
669 created new head
670 $ hg push -B W
670 $ hg push -B W
671 pushing to http://localhost:$HGPORT/
671 pushing to http://localhost:$HGPORT/
672 searching for changes
672 searching for changes
673 remote: adding changesets
673 remote: adding changesets
674 remote: adding manifests
674 remote: adding manifests
675 remote: adding file changes
675 remote: adding file changes
676 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
676 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
677 exporting bookmark W
677 exporting bookmark W
678 $ hg -R ../b id -r W
678 $ hg -R ../b id -r W
679 cc978a373a53 tip W
679 cc978a373a53 tip W
680
680
681 pushing an existing but divergent bookmark with -B still requires -f
682
683 $ hg clone -q . r
684 $ hg up -q X
685 $ echo 1 > f2
686 $ hg ci -qAml
687
688 $ cd r
689 $ hg up -q X
690 $ echo 2 > f2
691 $ hg ci -qAmr
692 $ hg push -B X
693 pushing to $TESTTMP/addmarks (glob)
694 searching for changes
695 remote has heads on branch 'default' that are not known locally: a2a606d9ff1b
696 abort: push creates new remote head 54694f811df9 with bookmark 'X'!
697 (pull and merge or see "hg help push" for details about pushing new heads)
698 [255]
699 $ cd ..
700
681 Check summary output for incoming/outgoing bookmarks
701 Check summary output for incoming/outgoing bookmarks
682
702
683 $ hg bookmarks -d X
703 $ hg bookmarks -d X
684 $ hg bookmarks -d Y
704 $ hg bookmarks -d Y
685 $ hg summary --remote | grep '^remote:'
705 $ hg summary --remote | grep '^remote:'
686 remote: *, 2 incoming bookmarks, 1 outgoing bookmarks (glob)
706 remote: *, 2 incoming bookmarks, 1 outgoing bookmarks (glob)
687
707
688 $ cd ..
708 $ cd ..
689
709
690 pushing an unchanged bookmark should result in no changes
710 pushing an unchanged bookmark should result in no changes
691
711
692 $ hg init unchanged-a
712 $ hg init unchanged-a
693 $ hg init unchanged-b
713 $ hg init unchanged-b
694 $ cd unchanged-a
714 $ cd unchanged-a
695 $ echo initial > foo
715 $ echo initial > foo
696 $ hg commit -A -m initial
716 $ hg commit -A -m initial
697 adding foo
717 adding foo
698 $ hg bookmark @
718 $ hg bookmark @
699 $ hg push -B @ ../unchanged-b
719 $ hg push -B @ ../unchanged-b
700 pushing to ../unchanged-b
720 pushing to ../unchanged-b
701 searching for changes
721 searching for changes
702 adding changesets
722 adding changesets
703 adding manifests
723 adding manifests
704 adding file changes
724 adding file changes
705 added 1 changesets with 1 changes to 1 files
725 added 1 changesets with 1 changes to 1 files
706 exporting bookmark @
726 exporting bookmark @
707
727
708 $ hg push -B @ ../unchanged-b
728 $ hg push -B @ ../unchanged-b
709 pushing to ../unchanged-b
729 pushing to ../unchanged-b
710 searching for changes
730 searching for changes
711 no changes found
731 no changes found
712 [1]
732 [1]
713
733
714
734
715 Check hook preventing push (issue4455)
735 Check hook preventing push (issue4455)
716 ======================================
736 ======================================
717
737
718 $ hg bookmarks
738 $ hg bookmarks
719 * @ 0:55482a6fb4b1
739 * @ 0:55482a6fb4b1
720 $ hg log -G
740 $ hg log -G
721 @ 0:55482a6fb4b1 initial
741 @ 0:55482a6fb4b1 initial
722
742
723 $ hg init ../issue4455-dest
743 $ hg init ../issue4455-dest
724 $ hg push ../issue4455-dest # changesets only
744 $ hg push ../issue4455-dest # changesets only
725 pushing to ../issue4455-dest
745 pushing to ../issue4455-dest
726 searching for changes
746 searching for changes
727 adding changesets
747 adding changesets
728 adding manifests
748 adding manifests
729 adding file changes
749 adding file changes
730 added 1 changesets with 1 changes to 1 files
750 added 1 changesets with 1 changes to 1 files
731 $ cat >> .hg/hgrc << EOF
751 $ cat >> .hg/hgrc << EOF
732 > [paths]
752 > [paths]
733 > local=../issue4455-dest/
753 > local=../issue4455-dest/
734 > ssh=ssh://user@dummy/issue4455-dest
754 > ssh=ssh://user@dummy/issue4455-dest
735 > http=http://localhost:$HGPORT/
755 > http=http://localhost:$HGPORT/
736 > [ui]
756 > [ui]
737 > ssh=python "$TESTDIR/dummyssh"
757 > ssh=python "$TESTDIR/dummyssh"
738 > EOF
758 > EOF
739 $ cat >> ../issue4455-dest/.hg/hgrc << EOF
759 $ cat >> ../issue4455-dest/.hg/hgrc << EOF
740 > [hooks]
760 > [hooks]
741 > prepushkey=false
761 > prepushkey=false
742 > [web]
762 > [web]
743 > push_ssl = false
763 > push_ssl = false
744 > allow_push = *
764 > allow_push = *
745 > EOF
765 > EOF
746 $ killdaemons.py
766 $ killdaemons.py
747 $ hg -R ../issue4455-dest serve -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
767 $ hg -R ../issue4455-dest serve -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
748 $ cat ../issue4455.pid >> $DAEMON_PIDS
768 $ cat ../issue4455.pid >> $DAEMON_PIDS
749
769
750 Local push
770 Local push
751 ----------
771 ----------
752
772
753 $ hg push -B @ local
773 $ hg push -B @ local
754 pushing to $TESTTMP/issue4455-dest (glob)
774 pushing to $TESTTMP/issue4455-dest (glob)
755 searching for changes
775 searching for changes
756 no changes found
776 no changes found
757 pushkey-abort: prepushkey hook exited with status 1
777 pushkey-abort: prepushkey hook exited with status 1
758 abort: exporting bookmark @ failed!
778 abort: exporting bookmark @ failed!
759 [255]
779 [255]
760 $ hg -R ../issue4455-dest/ bookmarks
780 $ hg -R ../issue4455-dest/ bookmarks
761 no bookmarks set
781 no bookmarks set
762
782
763 Using ssh
783 Using ssh
764 ---------
784 ---------
765
785
766 $ hg push -B @ ssh --config experimental.bundle2-exp=True
786 $ hg push -B @ ssh --config experimental.bundle2-exp=True
767 pushing to ssh://user@dummy/issue4455-dest
787 pushing to ssh://user@dummy/issue4455-dest
768 searching for changes
788 searching for changes
769 no changes found
789 no changes found
770 remote: pushkey-abort: prepushkey hook exited with status 1
790 remote: pushkey-abort: prepushkey hook exited with status 1
771 abort: exporting bookmark @ failed!
791 abort: exporting bookmark @ failed!
772 [255]
792 [255]
773 $ hg -R ../issue4455-dest/ bookmarks
793 $ hg -R ../issue4455-dest/ bookmarks
774 no bookmarks set
794 no bookmarks set
775
795
776 $ hg push -B @ ssh --config experimental.bundle2-exp=False
796 $ hg push -B @ ssh --config experimental.bundle2-exp=False
777 pushing to ssh://user@dummy/issue4455-dest
797 pushing to ssh://user@dummy/issue4455-dest
778 searching for changes
798 searching for changes
779 no changes found
799 no changes found
780 remote: pushkey-abort: prepushkey hook exited with status 1
800 remote: pushkey-abort: prepushkey hook exited with status 1
781 exporting bookmark @ failed!
801 exporting bookmark @ failed!
782 [1]
802 [1]
783 $ hg -R ../issue4455-dest/ bookmarks
803 $ hg -R ../issue4455-dest/ bookmarks
784 no bookmarks set
804 no bookmarks set
785
805
786 Using http
806 Using http
787 ----------
807 ----------
788
808
789 $ hg push -B @ http --config experimental.bundle2-exp=True
809 $ hg push -B @ http --config experimental.bundle2-exp=True
790 pushing to http://localhost:$HGPORT/
810 pushing to http://localhost:$HGPORT/
791 searching for changes
811 searching for changes
792 no changes found
812 no changes found
793 remote: pushkey-abort: prepushkey hook exited with status 1
813 remote: pushkey-abort: prepushkey hook exited with status 1
794 abort: exporting bookmark @ failed!
814 abort: exporting bookmark @ failed!
795 [255]
815 [255]
796 $ hg -R ../issue4455-dest/ bookmarks
816 $ hg -R ../issue4455-dest/ bookmarks
797 no bookmarks set
817 no bookmarks set
798
818
799 $ hg push -B @ http --config experimental.bundle2-exp=False
819 $ hg push -B @ http --config experimental.bundle2-exp=False
800 pushing to http://localhost:$HGPORT/
820 pushing to http://localhost:$HGPORT/
801 searching for changes
821 searching for changes
802 no changes found
822 no changes found
803 remote: pushkey-abort: prepushkey hook exited with status 1
823 remote: pushkey-abort: prepushkey hook exited with status 1
804 exporting bookmark @ failed!
824 exporting bookmark @ failed!
805 [1]
825 [1]
806 $ hg -R ../issue4455-dest/ bookmarks
826 $ hg -R ../issue4455-dest/ bookmarks
807 no bookmarks set
827 no bookmarks set
General Comments 0
You need to be logged in to leave comments. Login now