##// END OF EJS Templates
discovery: if a push would create a new head, mention the bookmark name if any
Stephen Lee -
r21580:32601b0b default
parent child Browse files
Show More
@@ -1,362 +1,366 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 knownnode = repo.changelog.hasnode # no nodemap until it is filtered
37 knownnode = repo.changelog.hasnode # no nodemap until it is filtered
38 for h in heads:
38 for h in heads:
39 if not knownnode(h):
39 if not knownnode(h):
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("served").heads()
118 og.missingheads = repo.filtered("served").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 if the branch is new
157 None if 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 knownnode = cl.hasnode # do not use nodemap until it is filtered
175 knownnode = cl.hasnode # do not use nodemap until it is filtered
176 for h in heads:
176 for h in heads:
177 if knownnode(h):
177 if knownnode(h):
178 known.append(h)
178 known.append(h)
179 else:
179 else:
180 unsynced.append(h)
180 unsynced.append(h)
181 headssum[branch] = (known, list(known), unsynced)
181 headssum[branch] = (known, list(known), unsynced)
182 # B. add new branch data
182 # B. add new branch data
183 missingctx = list(repo[n] for n in outgoing.missing)
183 missingctx = list(repo[n] for n in outgoing.missing)
184 touchedbranches = set()
184 touchedbranches = set()
185 for ctx in missingctx:
185 for ctx in missingctx:
186 branch = ctx.branch()
186 branch = ctx.branch()
187 touchedbranches.add(branch)
187 touchedbranches.add(branch)
188 if branch not in headssum:
188 if branch not in headssum:
189 headssum[branch] = (None, [], [])
189 headssum[branch] = (None, [], [])
190
190
191 # C drop data about untouched branches:
191 # C drop data about untouched branches:
192 for branch in remotebranches - touchedbranches:
192 for branch in remotebranches - touchedbranches:
193 del headssum[branch]
193 del headssum[branch]
194
194
195 # D. Update newmap with outgoing changes.
195 # D. Update newmap with outgoing changes.
196 # This will possibly add new heads and remove existing ones.
196 # This will possibly add new heads and remove existing ones.
197 newmap = branchmap.branchcache((branch, heads[1])
197 newmap = branchmap.branchcache((branch, heads[1])
198 for branch, heads in headssum.iteritems()
198 for branch, heads in headssum.iteritems()
199 if heads[0] is not None)
199 if heads[0] is not None)
200 newmap.update(repo, (ctx.rev() for ctx in missingctx))
200 newmap.update(repo, (ctx.rev() for ctx in missingctx))
201 for branch, newheads in newmap.iteritems():
201 for branch, newheads in newmap.iteritems():
202 headssum[branch][1][:] = newheads
202 headssum[branch][1][:] = newheads
203 return headssum
203 return headssum
204
204
205 def _oldheadssummary(repo, remoteheads, outgoing, inc=False):
205 def _oldheadssummary(repo, remoteheads, outgoing, inc=False):
206 """Compute branchmapsummary for repo without branchmap support"""
206 """Compute branchmapsummary for repo without branchmap support"""
207
207
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 knownnode = repo.changelog.hasnode # no nodemap until it is filtered
211 knownnode = repo.changelog.hasnode # no nodemap until it is filtered
212 oldheads = set(h for h in remoteheads if knownnode(h))
212 oldheads = set(h for h in remoteheads if knownnode(h))
213 # all nodes in outgoing.missing are children of either:
213 # all nodes in outgoing.missing are children of either:
214 # - an element of oldheads
214 # - an element of oldheads
215 # - another element of outgoing.missing
215 # - another element of outgoing.missing
216 # - nullrev
216 # - nullrev
217 # This explains why the new head are very simple to compute.
217 # This explains why the new head are very simple to compute.
218 r = repo.set('heads(%ln + %ln)', oldheads, outgoing.missing)
218 r = repo.set('heads(%ln + %ln)', oldheads, outgoing.missing)
219 newheads = list(c.node() for c in r)
219 newheads = list(c.node() for c in r)
220 unsynced = inc and set([None]) or set()
220 unsynced = inc and set([None]) or set()
221 return {None: (oldheads, newheads, unsynced)}
221 return {None: (oldheads, newheads, unsynced)}
222
222
223 def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False,
223 def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False,
224 newbookmarks=[]):
224 newbookmarks=[]):
225 """Check that a push won't add any outgoing head
225 """Check that a push won't add any outgoing head
226
226
227 raise Abort error and display ui message as needed.
227 raise Abort error and display ui message as needed.
228 """
228 """
229 # Check for each named branch if we're creating new remote heads.
229 # Check for each named branch if we're creating new remote heads.
230 # To be a remote head after push, node must be either:
230 # To be a remote head after push, node must be either:
231 # - unknown locally
231 # - unknown locally
232 # - a local outgoing head descended from update
232 # - a local outgoing head descended from update
233 # - a remote head that's known locally and not
233 # - a remote head that's known locally and not
234 # ancestral to an outgoing head
234 # ancestral to an outgoing head
235 if remoteheads == [nullid]:
235 if remoteheads == [nullid]:
236 # remote is empty, nothing to check.
236 # remote is empty, nothing to check.
237 return
237 return
238
238
239 if remote.capable('branchmap'):
239 if remote.capable('branchmap'):
240 headssum = _headssummary(repo, remote, outgoing)
240 headssum = _headssummary(repo, remote, outgoing)
241 else:
241 else:
242 headssum = _oldheadssummary(repo, remoteheads, outgoing, inc)
242 headssum = _oldheadssummary(repo, remoteheads, outgoing, inc)
243 newbranches = [branch for branch, heads in headssum.iteritems()
243 newbranches = [branch for branch, heads in headssum.iteritems()
244 if heads[0] is None]
244 if heads[0] is None]
245 # 1. Check for new branches on the remote.
245 # 1. Check for new branches on the remote.
246 if newbranches and not newbranch: # new branch requires --new-branch
246 if newbranches and not newbranch: # new branch requires --new-branch
247 branchnames = ', '.join(sorted(newbranches))
247 branchnames = ', '.join(sorted(newbranches))
248 raise util.Abort(_("push creates new remote branches: %s!")
248 raise util.Abort(_("push creates new remote branches: %s!")
249 % branchnames,
249 % branchnames,
250 hint=_("use 'hg push --new-branch' to create"
250 hint=_("use 'hg push --new-branch' to create"
251 " new remote branches"))
251 " new remote branches"))
252
252
253 # 2. Compute newly pushed bookmarks. We don't warn about bookmarked heads.
253 # 2. Compute newly pushed bookmarks. We don't warn about bookmarked heads.
254 localbookmarks = repo._bookmarks
254 localbookmarks = repo._bookmarks
255 remotebookmarks = remote.listkeys('bookmarks')
255 remotebookmarks = remote.listkeys('bookmarks')
256 bookmarkedheads = set()
256 bookmarkedheads = set()
257 for bm in localbookmarks:
257 for bm in localbookmarks:
258 rnode = remotebookmarks.get(bm)
258 rnode = remotebookmarks.get(bm)
259 if rnode and rnode in repo:
259 if rnode and rnode in repo:
260 lctx, rctx = repo[bm], repo[rnode]
260 lctx, rctx = repo[bm], repo[rnode]
261 if bookmarks.validdest(repo, rctx, lctx):
261 if bookmarks.validdest(repo, rctx, lctx):
262 bookmarkedheads.add(lctx.node())
262 bookmarkedheads.add(lctx.node())
263 else:
263 else:
264 if bm in newbookmarks:
264 if bm in newbookmarks:
265 bookmarkedheads.add(repo[bm].node())
265 bookmarkedheads.add(repo[bm].node())
266
266
267 # 3. Check for new heads.
267 # 3. Check for new heads.
268 # If there are more heads after the push than before, a suitable
268 # If there are more heads after the push than before, a suitable
269 # error message, depending on unsynced status, is displayed.
269 # error message, depending on unsynced status, is displayed.
270 error = None
270 error = None
271 allmissing = set(outgoing.missing)
271 allmissing = set(outgoing.missing)
272 allfuturecommon = set(c.node() for c in repo.set('%ld', outgoing.common))
272 allfuturecommon = set(c.node() for c in repo.set('%ld', outgoing.common))
273 allfuturecommon.update(allmissing)
273 allfuturecommon.update(allmissing)
274 for branch, heads in sorted(headssum.iteritems()):
274 for branch, heads in sorted(headssum.iteritems()):
275 remoteheads, newheads, unsyncedheads = heads
275 remoteheads, newheads, unsyncedheads = heads
276 candidate_newhs = set(newheads)
276 candidate_newhs = set(newheads)
277 # add unsynced data
277 # add unsynced data
278 if remoteheads is None:
278 if remoteheads is None:
279 oldhs = set()
279 oldhs = set()
280 else:
280 else:
281 oldhs = set(remoteheads)
281 oldhs = set(remoteheads)
282 oldhs.update(unsyncedheads)
282 oldhs.update(unsyncedheads)
283 candidate_newhs.update(unsyncedheads)
283 candidate_newhs.update(unsyncedheads)
284 dhs = None # delta heads, the new heads on branch
284 dhs = None # delta heads, the new heads on branch
285 discardedheads = set()
285 discardedheads = set()
286 if repo.obsstore:
286 if repo.obsstore:
287 # remove future heads which are actually obsoleted by another
287 # remove future heads which are actually obsoleted by another
288 # pushed element:
288 # pushed element:
289 #
289 #
290 # XXX as above, There are several cases this case does not handle
290 # XXX as above, There are several cases this case does not handle
291 # XXX properly
291 # XXX properly
292 #
292 #
293 # (1) if <nh> is public, it won't be affected by obsolete marker
293 # (1) if <nh> is public, it won't be affected by obsolete marker
294 # and a new is created
294 # and a new is created
295 #
295 #
296 # (2) if the new heads have ancestors which are not obsolete and
296 # (2) if the new heads have ancestors which are not obsolete and
297 # not ancestors of any other heads we will have a new head too.
297 # not ancestors of any other heads we will have a new head too.
298 #
298 #
299 # These two cases will be easy to handle for known changeset but
299 # These two cases will be easy to handle for known changeset but
300 # much more tricky for unsynced changes.
300 # much more tricky for unsynced changes.
301 newhs = set()
301 newhs = set()
302 for nh in candidate_newhs:
302 for nh in candidate_newhs:
303 if nh in repo and repo[nh].phase() <= phases.public:
303 if nh in repo and repo[nh].phase() <= phases.public:
304 newhs.add(nh)
304 newhs.add(nh)
305 else:
305 else:
306 for suc in obsolete.allsuccessors(repo.obsstore, [nh]):
306 for suc in obsolete.allsuccessors(repo.obsstore, [nh]):
307 if suc != nh and suc in allfuturecommon:
307 if suc != nh and suc in allfuturecommon:
308 discardedheads.add(nh)
308 discardedheads.add(nh)
309 break
309 break
310 else:
310 else:
311 newhs.add(nh)
311 newhs.add(nh)
312 else:
312 else:
313 newhs = candidate_newhs
313 newhs = candidate_newhs
314 unsynced = sorted(h for h in unsyncedheads if h not in discardedheads)
314 unsynced = sorted(h for h in unsyncedheads if h not in discardedheads)
315 if unsynced:
315 if unsynced:
316 if len(unsynced) <= 4 or repo.ui.verbose:
316 if len(unsynced) <= 4 or repo.ui.verbose:
317 heads = ' '.join(short(h) for h in unsynced)
317 heads = ' '.join(short(h) for h in unsynced)
318 else:
318 else:
319 heads = (' '.join(short(h) for h in unsynced[:4]) +
319 heads = (' '.join(short(h) for h in unsynced[:4]) +
320 ' ' + _("and %s others") % (len(unsynced) - 4))
320 ' ' + _("and %s others") % (len(unsynced) - 4))
321 if branch is None:
321 if branch is None:
322 repo.ui.status(_("remote has heads that are "
322 repo.ui.status(_("remote has heads that are "
323 "not known locally: %s\n") % heads)
323 "not known locally: %s\n") % heads)
324 else:
324 else:
325 repo.ui.status(_("remote has heads on branch '%s' that are "
325 repo.ui.status(_("remote has heads on branch '%s' that are "
326 "not known locally: %s\n") % (branch, heads))
326 "not known locally: %s\n") % (branch, heads))
327 if remoteheads is None:
327 if remoteheads is None:
328 if len(newhs) > 1:
328 if len(newhs) > 1:
329 dhs = list(newhs)
329 dhs = list(newhs)
330 if error is None:
330 if error is None:
331 error = (_("push creates new branch '%s' "
331 error = (_("push creates new branch '%s' "
332 "with multiple heads") % (branch))
332 "with multiple heads") % (branch))
333 hint = _("merge or"
333 hint = _("merge or"
334 " see \"hg help push\" for details about"
334 " see \"hg help push\" for details about"
335 " pushing new heads")
335 " pushing new heads")
336 elif len(newhs) > len(oldhs):
336 elif len(newhs) > len(oldhs):
337 # remove bookmarked or existing remote heads from the new heads list
337 # remove bookmarked or existing remote heads from the new heads list
338 dhs = sorted(newhs - bookmarkedheads - oldhs)
338 dhs = sorted(newhs - bookmarkedheads - oldhs)
339 if dhs:
339 if dhs:
340 if error is None:
340 if error is None:
341 if branch not in ('default', None):
341 if branch not in ('default', None):
342 error = _("push creates new remote head %s "
342 error = _("push creates new remote head %s "
343 "on branch '%s'!") % (short(dhs[0]), branch)
343 "on branch '%s'!") % (short(dhs[0]), branch)
344 elif repo[dhs[0]].bookmarks():
345 error = _("push creates new remote head %s "
346 "with bookmark '%s'!") % (
347 short(dhs[0]), repo[dhs[0]].bookmarks()[0])
344 else:
348 else:
345 error = _("push creates new remote head %s!"
349 error = _("push creates new remote head %s!"
346 ) % short(dhs[0])
350 ) % short(dhs[0])
347 if unsyncedheads:
351 if unsyncedheads:
348 hint = _("pull and merge or"
352 hint = _("pull and merge or"
349 " see \"hg help push\" for details about"
353 " see \"hg help push\" for details about"
350 " pushing new heads")
354 " pushing new heads")
351 else:
355 else:
352 hint = _("merge or"
356 hint = _("merge or"
353 " see \"hg help push\" for details about"
357 " see \"hg help push\" for details about"
354 " pushing new heads")
358 " pushing new heads")
355 if branch is None:
359 if branch is None:
356 repo.ui.note(_("new remote heads:\n"))
360 repo.ui.note(_("new remote heads:\n"))
357 else:
361 else:
358 repo.ui.note(_("new remote heads on branch '%s':\n") % branch)
362 repo.ui.note(_("new remote heads on branch '%s':\n") % branch)
359 for h in dhs:
363 for h in dhs:
360 repo.ui.note((" %s\n") % short(h))
364 repo.ui.note((" %s\n") % short(h))
361 if error:
365 if error:
362 raise util.Abort(error, hint=hint)
366 raise util.Abort(error, hint=hint)
@@ -1,446 +1,446 b''
1 $ "$TESTDIR/hghave" serve || exit 80
1 $ "$TESTDIR/hghave" serve || exit 80
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 > [extensions]
8 > [extensions]
9 > EOF
9 > EOF
10 $ cat > obs.py << EOF
10 $ cat > obs.py << EOF
11 > import mercurial.obsolete
11 > import mercurial.obsolete
12 > mercurial.obsolete._enabled = True
12 > mercurial.obsolete._enabled = True
13 > EOF
13 > EOF
14 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
14 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
15
15
16 initialize
16 initialize
17
17
18 $ hg init a
18 $ hg init a
19 $ cd a
19 $ cd a
20 $ echo 'test' > test
20 $ echo 'test' > test
21 $ hg commit -Am'test'
21 $ hg commit -Am'test'
22 adding test
22 adding test
23
23
24 set bookmarks
24 set bookmarks
25
25
26 $ hg bookmark X
26 $ hg bookmark X
27 $ hg bookmark Y
27 $ hg bookmark Y
28 $ hg bookmark Z
28 $ hg bookmark Z
29
29
30 import bookmark by name
30 import bookmark by name
31
31
32 $ hg init ../b
32 $ hg init ../b
33 $ cd ../b
33 $ cd ../b
34 $ hg book Y
34 $ hg book Y
35 $ hg book
35 $ hg book
36 * Y -1:000000000000
36 * Y -1:000000000000
37 $ hg pull ../a
37 $ hg pull ../a
38 pulling from ../a
38 pulling from ../a
39 requesting all changes
39 requesting all changes
40 adding changesets
40 adding changesets
41 adding manifests
41 adding manifests
42 adding file changes
42 adding file changes
43 added 1 changesets with 1 changes to 1 files
43 added 1 changesets with 1 changes to 1 files
44 adding remote bookmark X
44 adding remote bookmark X
45 updating bookmark Y
45 updating bookmark Y
46 adding remote bookmark Z
46 adding remote bookmark Z
47 (run 'hg update' to get a working copy)
47 (run 'hg update' to get a working copy)
48 $ hg bookmarks
48 $ hg bookmarks
49 X 0:4e3505fd9583
49 X 0:4e3505fd9583
50 * Y 0:4e3505fd9583
50 * Y 0:4e3505fd9583
51 Z 0:4e3505fd9583
51 Z 0:4e3505fd9583
52 $ hg debugpushkey ../a namespaces
52 $ hg debugpushkey ../a namespaces
53 bookmarks
53 bookmarks
54 namespaces
54 namespaces
55 obsolete
55 obsolete
56 phases
56 phases
57 $ hg debugpushkey ../a bookmarks
57 $ hg debugpushkey ../a bookmarks
58 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
58 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
59 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
59 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
60 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
60 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
61 $ hg pull -B X ../a
61 $ hg pull -B X ../a
62 pulling from ../a
62 pulling from ../a
63 no changes found
63 no changes found
64 importing bookmark X
64 importing bookmark X
65 $ hg bookmark
65 $ hg bookmark
66 X 0:4e3505fd9583
66 X 0:4e3505fd9583
67 * Y 0:4e3505fd9583
67 * Y 0:4e3505fd9583
68 Z 0:4e3505fd9583
68 Z 0:4e3505fd9583
69
69
70 export bookmark by name
70 export bookmark by name
71
71
72 $ hg bookmark W
72 $ hg bookmark W
73 $ hg bookmark foo
73 $ hg bookmark foo
74 $ hg bookmark foobar
74 $ hg bookmark foobar
75 $ hg push -B W ../a
75 $ hg push -B W ../a
76 pushing to ../a
76 pushing to ../a
77 searching for changes
77 searching for changes
78 no changes found
78 no changes found
79 exporting bookmark W
79 exporting bookmark W
80 [1]
80 [1]
81 $ hg -R ../a bookmarks
81 $ hg -R ../a bookmarks
82 W -1:000000000000
82 W -1:000000000000
83 X 0:4e3505fd9583
83 X 0:4e3505fd9583
84 Y 0:4e3505fd9583
84 Y 0:4e3505fd9583
85 * Z 0:4e3505fd9583
85 * Z 0:4e3505fd9583
86
86
87 delete a remote bookmark
87 delete a remote bookmark
88
88
89 $ hg book -d W
89 $ hg book -d W
90 $ hg push -B W ../a
90 $ hg push -B W ../a
91 pushing to ../a
91 pushing to ../a
92 searching for changes
92 searching for changes
93 no changes found
93 no changes found
94 deleting remote bookmark W
94 deleting remote bookmark W
95 [1]
95 [1]
96
96
97 push/pull name that doesn't exist
97 push/pull name that doesn't exist
98
98
99 $ hg push -B badname ../a
99 $ hg push -B badname ../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 bookmark badname does not exist on the local or remote repository!
103 bookmark badname does not exist on the local or remote repository!
104 [2]
104 [2]
105 $ hg pull -B anotherbadname ../a
105 $ hg pull -B anotherbadname ../a
106 pulling from ../a
106 pulling from ../a
107 abort: remote bookmark anotherbadname not found!
107 abort: remote bookmark anotherbadname not found!
108 [255]
108 [255]
109
109
110 divergent bookmarks
110 divergent bookmarks
111
111
112 $ cd ../a
112 $ cd ../a
113 $ echo c1 > f1
113 $ echo c1 > f1
114 $ hg ci -Am1
114 $ hg ci -Am1
115 adding f1
115 adding f1
116 $ hg book -f @
116 $ hg book -f @
117 $ hg book -f X
117 $ hg book -f X
118 $ hg book
118 $ hg book
119 @ 1:0d2164f0ce0d
119 @ 1:0d2164f0ce0d
120 * X 1:0d2164f0ce0d
120 * X 1:0d2164f0ce0d
121 Y 0:4e3505fd9583
121 Y 0:4e3505fd9583
122 Z 1:0d2164f0ce0d
122 Z 1:0d2164f0ce0d
123
123
124 $ cd ../b
124 $ cd ../b
125 $ hg up
125 $ hg up
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
127 updating bookmark foobar
127 updating bookmark foobar
128 $ echo c2 > f2
128 $ echo c2 > f2
129 $ hg ci -Am2
129 $ hg ci -Am2
130 adding f2
130 adding f2
131 $ hg book -if @
131 $ hg book -if @
132 $ hg book -if X
132 $ hg book -if X
133 $ hg book
133 $ hg book
134 @ 1:9b140be10808
134 @ 1:9b140be10808
135 X 1:9b140be10808
135 X 1:9b140be10808
136 Y 0:4e3505fd9583
136 Y 0:4e3505fd9583
137 Z 0:4e3505fd9583
137 Z 0:4e3505fd9583
138 foo -1:000000000000
138 foo -1:000000000000
139 * foobar 1:9b140be10808
139 * foobar 1:9b140be10808
140
140
141 $ hg pull --config paths.foo=../a foo
141 $ hg pull --config paths.foo=../a foo
142 pulling from $TESTTMP/a (glob)
142 pulling from $TESTTMP/a (glob)
143 searching for changes
143 searching for changes
144 adding changesets
144 adding changesets
145 adding manifests
145 adding manifests
146 adding file changes
146 adding file changes
147 added 1 changesets with 1 changes to 1 files (+1 heads)
147 added 1 changesets with 1 changes to 1 files (+1 heads)
148 divergent bookmark @ stored as @foo
148 divergent bookmark @ stored as @foo
149 divergent bookmark X stored as X@foo
149 divergent bookmark X stored as X@foo
150 updating bookmark Z
150 updating bookmark Z
151 (run 'hg heads' to see heads, 'hg merge' to merge)
151 (run 'hg heads' to see heads, 'hg merge' to merge)
152 $ hg book
152 $ hg book
153 @ 1:9b140be10808
153 @ 1:9b140be10808
154 @foo 2:0d2164f0ce0d
154 @foo 2:0d2164f0ce0d
155 X 1:9b140be10808
155 X 1:9b140be10808
156 X@foo 2:0d2164f0ce0d
156 X@foo 2:0d2164f0ce0d
157 Y 0:4e3505fd9583
157 Y 0:4e3505fd9583
158 Z 2:0d2164f0ce0d
158 Z 2:0d2164f0ce0d
159 foo -1:000000000000
159 foo -1:000000000000
160 * foobar 1:9b140be10808
160 * foobar 1:9b140be10808
161 $ hg push -f ../a
161 $ hg push -f ../a
162 pushing to ../a
162 pushing to ../a
163 searching for changes
163 searching for changes
164 adding changesets
164 adding changesets
165 adding manifests
165 adding manifests
166 adding file changes
166 adding file changes
167 added 1 changesets with 1 changes to 1 files (+1 heads)
167 added 1 changesets with 1 changes to 1 files (+1 heads)
168 $ hg -R ../a book
168 $ hg -R ../a book
169 @ 1:0d2164f0ce0d
169 @ 1:0d2164f0ce0d
170 * X 1:0d2164f0ce0d
170 * X 1:0d2164f0ce0d
171 Y 0:4e3505fd9583
171 Y 0:4e3505fd9583
172 Z 1:0d2164f0ce0d
172 Z 1:0d2164f0ce0d
173
173
174 revsets should not ignore divergent bookmarks
174 revsets should not ignore divergent bookmarks
175
175
176 $ hg bookmark -fr 1 Z
176 $ hg bookmark -fr 1 Z
177 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
177 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
178 0:4e3505fd9583 Y
178 0:4e3505fd9583 Y
179 1:9b140be10808 @ X Z foobar
179 1:9b140be10808 @ X Z foobar
180 2:0d2164f0ce0d @foo X@foo
180 2:0d2164f0ce0d @foo X@foo
181 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
181 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
182 2:0d2164f0ce0d @foo X@foo
182 2:0d2164f0ce0d @foo X@foo
183 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
183 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
184 2:0d2164f0ce0d @foo X@foo
184 2:0d2164f0ce0d @foo X@foo
185
185
186 update a remote bookmark from a non-head to a head
186 update a remote bookmark from a non-head to a head
187
187
188 $ hg up -q Y
188 $ hg up -q Y
189 $ echo c3 > f2
189 $ echo c3 > f2
190 $ hg ci -Am3
190 $ hg ci -Am3
191 adding f2
191 adding f2
192 created new head
192 created new head
193 $ hg push ../a
193 $ hg push ../a
194 pushing to ../a
194 pushing to ../a
195 searching for changes
195 searching for changes
196 adding changesets
196 adding changesets
197 adding manifests
197 adding manifests
198 adding file changes
198 adding file changes
199 added 1 changesets with 1 changes to 1 files (+1 heads)
199 added 1 changesets with 1 changes to 1 files (+1 heads)
200 updating bookmark Y
200 updating bookmark Y
201 $ hg -R ../a book
201 $ hg -R ../a book
202 @ 1:0d2164f0ce0d
202 @ 1:0d2164f0ce0d
203 * X 1:0d2164f0ce0d
203 * X 1:0d2164f0ce0d
204 Y 3:f6fc62dde3c0
204 Y 3:f6fc62dde3c0
205 Z 1:0d2164f0ce0d
205 Z 1:0d2164f0ce0d
206
206
207 update a bookmark in the middle of a client pulling changes
207 update a bookmark in the middle of a client pulling changes
208
208
209 $ cd ..
209 $ cd ..
210 $ hg clone -q a pull-race
210 $ hg clone -q a pull-race
211 $ hg clone -q pull-race pull-race2
211 $ hg clone -q pull-race pull-race2
212 $ cd pull-race
212 $ cd pull-race
213 $ hg up -q Y
213 $ hg up -q Y
214 $ echo c4 > f2
214 $ echo c4 > f2
215 $ hg ci -Am4
215 $ hg ci -Am4
216 $ echo c5 > f3
216 $ echo c5 > f3
217 $ cat <<EOF > .hg/hgrc
217 $ cat <<EOF > .hg/hgrc
218 > [hooks]
218 > [hooks]
219 > outgoing.makecommit = hg ci -Am5; echo committed in pull-race
219 > outgoing.makecommit = hg ci -Am5; echo committed in pull-race
220 > EOF
220 > EOF
221 $ cd ../pull-race2
221 $ cd ../pull-race2
222 $ hg pull
222 $ hg pull
223 pulling from $TESTTMP/pull-race (glob)
223 pulling from $TESTTMP/pull-race (glob)
224 searching for changes
224 searching for changes
225 adding changesets
225 adding changesets
226 adding f3
226 adding f3
227 committed in pull-race
227 committed in pull-race
228 adding manifests
228 adding manifests
229 adding file changes
229 adding file changes
230 added 1 changesets with 1 changes to 1 files
230 added 1 changesets with 1 changes to 1 files
231 updating bookmark Y
231 updating bookmark Y
232 (run 'hg update' to get a working copy)
232 (run 'hg update' to get a working copy)
233 $ hg book
233 $ hg book
234 * @ 1:0d2164f0ce0d
234 * @ 1:0d2164f0ce0d
235 X 1:0d2164f0ce0d
235 X 1:0d2164f0ce0d
236 Y 4:b0a5eff05604
236 Y 4:b0a5eff05604
237 Z 1:0d2164f0ce0d
237 Z 1:0d2164f0ce0d
238 $ cd ../b
238 $ cd ../b
239
239
240 diverging a remote bookmark fails
240 diverging a remote bookmark fails
241
241
242 $ hg up -q 4e3505fd9583
242 $ hg up -q 4e3505fd9583
243 $ echo c4 > f2
243 $ echo c4 > f2
244 $ hg ci -Am4
244 $ hg ci -Am4
245 adding f2
245 adding f2
246 created new head
246 created new head
247 $ echo c5 > f2
247 $ echo c5 > f2
248 $ hg ci -Am5
248 $ hg ci -Am5
249 $ hg log -G
249 $ hg log -G
250 @ 5:c922c0139ca0 5
250 @ 5:c922c0139ca0 5
251 |
251 |
252 o 4:4efff6d98829 4
252 o 4:4efff6d98829 4
253 |
253 |
254 | o 3:f6fc62dde3c0 3
254 | o 3:f6fc62dde3c0 3
255 |/
255 |/
256 | o 2:0d2164f0ce0d 1
256 | o 2:0d2164f0ce0d 1
257 |/
257 |/
258 | o 1:9b140be10808 2
258 | o 1:9b140be10808 2
259 |/
259 |/
260 o 0:4e3505fd9583 test
260 o 0:4e3505fd9583 test
261
261
262
262
263 $ hg book -f Y
263 $ hg book -f Y
264
264
265 $ cat <<EOF > ../a/.hg/hgrc
265 $ cat <<EOF > ../a/.hg/hgrc
266 > [web]
266 > [web]
267 > push_ssl = false
267 > push_ssl = false
268 > allow_push = *
268 > allow_push = *
269 > EOF
269 > EOF
270
270
271 $ hg -R ../a serve -p $HGPORT2 -d --pid-file=../hg2.pid
271 $ hg -R ../a serve -p $HGPORT2 -d --pid-file=../hg2.pid
272 $ cat ../hg2.pid >> $DAEMON_PIDS
272 $ cat ../hg2.pid >> $DAEMON_PIDS
273
273
274 $ hg push http://localhost:$HGPORT2/
274 $ hg push http://localhost:$HGPORT2/
275 pushing to http://localhost:$HGPORT2/
275 pushing to http://localhost:$HGPORT2/
276 searching for changes
276 searching for changes
277 abort: push creates new remote head c922c0139ca0!
277 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
278 (merge or see "hg help push" for details about pushing new heads)
278 (merge or see "hg help push" for details about pushing new heads)
279 [255]
279 [255]
280 $ hg -R ../a book
280 $ hg -R ../a book
281 @ 1:0d2164f0ce0d
281 @ 1:0d2164f0ce0d
282 * X 1:0d2164f0ce0d
282 * X 1:0d2164f0ce0d
283 Y 3:f6fc62dde3c0
283 Y 3:f6fc62dde3c0
284 Z 1:0d2164f0ce0d
284 Z 1:0d2164f0ce0d
285
285
286
286
287 Unrelated marker does not alter the decision
287 Unrelated marker does not alter the decision
288
288
289 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
289 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
290 $ hg push http://localhost:$HGPORT2/
290 $ hg push http://localhost:$HGPORT2/
291 pushing to http://localhost:$HGPORT2/
291 pushing to http://localhost:$HGPORT2/
292 searching for changes
292 searching for changes
293 abort: push creates new remote head c922c0139ca0!
293 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
294 (merge or see "hg help push" for details about pushing new heads)
294 (merge or see "hg help push" for details about pushing new heads)
295 [255]
295 [255]
296 $ hg -R ../a book
296 $ hg -R ../a book
297 @ 1:0d2164f0ce0d
297 @ 1:0d2164f0ce0d
298 * X 1:0d2164f0ce0d
298 * X 1:0d2164f0ce0d
299 Y 3:f6fc62dde3c0
299 Y 3:f6fc62dde3c0
300 Z 1:0d2164f0ce0d
300 Z 1:0d2164f0ce0d
301
301
302 Update to a successor works
302 Update to a successor works
303
303
304 $ hg id --debug -r 3
304 $ hg id --debug -r 3
305 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
305 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
306 $ hg id --debug -r 4
306 $ hg id --debug -r 4
307 4efff6d98829d9c824c621afd6e3f01865f5439f
307 4efff6d98829d9c824c621afd6e3f01865f5439f
308 $ hg id --debug -r 5
308 $ hg id --debug -r 5
309 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
309 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
310 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
310 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
311 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
311 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
312 $ hg push http://localhost:$HGPORT2/
312 $ hg push http://localhost:$HGPORT2/
313 pushing to http://localhost:$HGPORT2/
313 pushing to http://localhost:$HGPORT2/
314 searching for changes
314 searching for changes
315 remote: adding changesets
315 remote: adding changesets
316 remote: adding manifests
316 remote: adding manifests
317 remote: adding file changes
317 remote: adding file changes
318 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
318 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
319 updating bookmark Y
319 updating bookmark Y
320 $ hg -R ../a book
320 $ hg -R ../a book
321 @ 1:0d2164f0ce0d
321 @ 1:0d2164f0ce0d
322 * X 1:0d2164f0ce0d
322 * X 1:0d2164f0ce0d
323 Y 5:c922c0139ca0
323 Y 5:c922c0139ca0
324 Z 1:0d2164f0ce0d
324 Z 1:0d2164f0ce0d
325
325
326 hgweb
326 hgweb
327
327
328 $ cat <<EOF > .hg/hgrc
328 $ cat <<EOF > .hg/hgrc
329 > [web]
329 > [web]
330 > push_ssl = false
330 > push_ssl = false
331 > allow_push = *
331 > allow_push = *
332 > EOF
332 > EOF
333
333
334 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
334 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
335 $ cat ../hg.pid >> $DAEMON_PIDS
335 $ cat ../hg.pid >> $DAEMON_PIDS
336 $ cd ../a
336 $ cd ../a
337
337
338 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
338 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
339 bookmarks
339 bookmarks
340 namespaces
340 namespaces
341 obsolete
341 obsolete
342 phases
342 phases
343 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
343 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
344 @ 9b140be1080824d768c5a4691a564088eede71f9
344 @ 9b140be1080824d768c5a4691a564088eede71f9
345 X 9b140be1080824d768c5a4691a564088eede71f9
345 X 9b140be1080824d768c5a4691a564088eede71f9
346 Y c922c0139ca03858f655e4a2af4dd02796a63969
346 Y c922c0139ca03858f655e4a2af4dd02796a63969
347 Z 9b140be1080824d768c5a4691a564088eede71f9
347 Z 9b140be1080824d768c5a4691a564088eede71f9
348 foo 0000000000000000000000000000000000000000
348 foo 0000000000000000000000000000000000000000
349 foobar 9b140be1080824d768c5a4691a564088eede71f9
349 foobar 9b140be1080824d768c5a4691a564088eede71f9
350 $ hg out -B http://localhost:$HGPORT/
350 $ hg out -B http://localhost:$HGPORT/
351 comparing with http://localhost:$HGPORT/
351 comparing with http://localhost:$HGPORT/
352 searching for changed bookmarks
352 searching for changed bookmarks
353 no changed bookmarks found
353 no changed bookmarks found
354 [1]
354 [1]
355 $ hg push -B Z http://localhost:$HGPORT/
355 $ hg push -B Z http://localhost:$HGPORT/
356 pushing to http://localhost:$HGPORT/
356 pushing to http://localhost:$HGPORT/
357 searching for changes
357 searching for changes
358 no changes found
358 no changes found
359 exporting bookmark Z
359 exporting bookmark Z
360 [1]
360 [1]
361 $ hg book -d Z
361 $ hg book -d Z
362 $ hg in -B http://localhost:$HGPORT/
362 $ hg in -B http://localhost:$HGPORT/
363 comparing with http://localhost:$HGPORT/
363 comparing with http://localhost:$HGPORT/
364 searching for changed bookmarks
364 searching for changed bookmarks
365 Z 0d2164f0ce0d
365 Z 0d2164f0ce0d
366 foo 000000000000
366 foo 000000000000
367 foobar 9b140be10808
367 foobar 9b140be10808
368 $ hg pull -B Z http://localhost:$HGPORT/
368 $ hg pull -B Z http://localhost:$HGPORT/
369 pulling from http://localhost:$HGPORT/
369 pulling from http://localhost:$HGPORT/
370 no changes found
370 no changes found
371 divergent bookmark @ stored as @1
371 divergent bookmark @ stored as @1
372 divergent bookmark X stored as X@1
372 divergent bookmark X stored as X@1
373 adding remote bookmark Z
373 adding remote bookmark Z
374 adding remote bookmark foo
374 adding remote bookmark foo
375 adding remote bookmark foobar
375 adding remote bookmark foobar
376 importing bookmark Z
376 importing bookmark Z
377 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
377 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
378 requesting all changes
378 requesting all changes
379 adding changesets
379 adding changesets
380 adding manifests
380 adding manifests
381 adding file changes
381 adding file changes
382 added 5 changesets with 5 changes to 3 files (+2 heads)
382 added 5 changesets with 5 changes to 3 files (+2 heads)
383 updating to bookmark @
383 updating to bookmark @
384 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
384 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
385 $ hg -R cloned-bookmarks bookmarks
385 $ hg -R cloned-bookmarks bookmarks
386 * @ 1:9b140be10808
386 * @ 1:9b140be10808
387 X 1:9b140be10808
387 X 1:9b140be10808
388 Y 4:c922c0139ca0
388 Y 4:c922c0139ca0
389 Z 2:0d2164f0ce0d
389 Z 2:0d2164f0ce0d
390 foo -1:000000000000
390 foo -1:000000000000
391 foobar 1:9b140be10808
391 foobar 1:9b140be10808
392
392
393 $ cd ..
393 $ cd ..
394
394
395 Pushing a bookmark should only push the changes required by that
395 Pushing a bookmark should only push the changes required by that
396 bookmark, not all outgoing changes:
396 bookmark, not all outgoing changes:
397 $ hg clone http://localhost:$HGPORT/ addmarks
397 $ hg clone http://localhost:$HGPORT/ addmarks
398 requesting all changes
398 requesting all changes
399 adding changesets
399 adding changesets
400 adding manifests
400 adding manifests
401 adding file changes
401 adding file changes
402 added 5 changesets with 5 changes to 3 files (+2 heads)
402 added 5 changesets with 5 changes to 3 files (+2 heads)
403 updating to bookmark @
403 updating to bookmark @
404 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
404 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
405 $ cd addmarks
405 $ cd addmarks
406 $ echo foo > foo
406 $ echo foo > foo
407 $ hg add foo
407 $ hg add foo
408 $ hg commit -m 'add foo'
408 $ hg commit -m 'add foo'
409 $ echo bar > bar
409 $ echo bar > bar
410 $ hg add bar
410 $ hg add bar
411 $ hg commit -m 'add bar'
411 $ hg commit -m 'add bar'
412 $ hg co "tip^"
412 $ hg co "tip^"
413 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
413 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
414 (leaving bookmark @)
414 (leaving bookmark @)
415 $ hg book add-foo
415 $ hg book add-foo
416 $ hg book -r tip add-bar
416 $ hg book -r tip add-bar
417 Note: this push *must* push only a single changeset, as that's the point
417 Note: this push *must* push only a single changeset, as that's the point
418 of this test.
418 of this test.
419 $ hg push -B add-foo --traceback
419 $ hg push -B add-foo --traceback
420 pushing to http://localhost:$HGPORT/
420 pushing to http://localhost:$HGPORT/
421 searching for changes
421 searching for changes
422 remote: adding changesets
422 remote: adding changesets
423 remote: adding manifests
423 remote: adding manifests
424 remote: adding file changes
424 remote: adding file changes
425 remote: added 1 changesets with 1 changes to 1 files
425 remote: added 1 changesets with 1 changes to 1 files
426 exporting bookmark add-foo
426 exporting bookmark add-foo
427
427
428 pushing a new bookmark on a new head does not require -f if -B is specified
428 pushing a new bookmark on a new head does not require -f if -B is specified
429
429
430 $ hg up -q X
430 $ hg up -q X
431 $ hg book W
431 $ hg book W
432 $ echo c5 > f2
432 $ echo c5 > f2
433 $ hg ci -Am5
433 $ hg ci -Am5
434 created new head
434 created new head
435 $ hg push -B W
435 $ hg push -B W
436 pushing to http://localhost:$HGPORT/
436 pushing to http://localhost:$HGPORT/
437 searching for changes
437 searching for changes
438 remote: adding changesets
438 remote: adding changesets
439 remote: adding manifests
439 remote: adding manifests
440 remote: adding file changes
440 remote: adding file changes
441 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
441 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
442 exporting bookmark W
442 exporting bookmark W
443 $ hg -R ../b id -r W
443 $ hg -R ../b id -r W
444 cc978a373a53 tip W
444 cc978a373a53 tip W
445
445
446 $ cd ..
446 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now