##// END OF EJS Templates
templatekw: introduce obsfate keyword...
Boris Feld -
r34848:e27f1f04 default
parent child Browse files
Show More
@@ -1,785 +1,826
1 # obsutil.py - utility functions for obsolescence
1 # obsutil.py - utility functions for obsolescence
2 #
2 #
3 # Copyright 2017 Boris Feld <boris.feld@octobus.net>
3 # Copyright 2017 Boris Feld <boris.feld@octobus.net>
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 import re
10 import re
11
11
12 from . import (
12 from . import (
13 phases,
13 phases,
14 util
14 util
15 )
15 )
16
16
17 class marker(object):
17 class marker(object):
18 """Wrap obsolete marker raw data"""
18 """Wrap obsolete marker raw data"""
19
19
20 def __init__(self, repo, data):
20 def __init__(self, repo, data):
21 # the repo argument will be used to create changectx in later version
21 # the repo argument will be used to create changectx in later version
22 self._repo = repo
22 self._repo = repo
23 self._data = data
23 self._data = data
24 self._decodedmeta = None
24 self._decodedmeta = None
25
25
26 def __hash__(self):
26 def __hash__(self):
27 return hash(self._data)
27 return hash(self._data)
28
28
29 def __eq__(self, other):
29 def __eq__(self, other):
30 if type(other) != type(self):
30 if type(other) != type(self):
31 return False
31 return False
32 return self._data == other._data
32 return self._data == other._data
33
33
34 def precnode(self):
34 def precnode(self):
35 msg = ("'marker.precnode' is deprecated, "
35 msg = ("'marker.precnode' is deprecated, "
36 "use 'marker.prednode'")
36 "use 'marker.prednode'")
37 util.nouideprecwarn(msg, '4.4')
37 util.nouideprecwarn(msg, '4.4')
38 return self.prednode()
38 return self.prednode()
39
39
40 def prednode(self):
40 def prednode(self):
41 """Predecessor changeset node identifier"""
41 """Predecessor changeset node identifier"""
42 return self._data[0]
42 return self._data[0]
43
43
44 def succnodes(self):
44 def succnodes(self):
45 """List of successor changesets node identifiers"""
45 """List of successor changesets node identifiers"""
46 return self._data[1]
46 return self._data[1]
47
47
48 def parentnodes(self):
48 def parentnodes(self):
49 """Parents of the predecessors (None if not recorded)"""
49 """Parents of the predecessors (None if not recorded)"""
50 return self._data[5]
50 return self._data[5]
51
51
52 def metadata(self):
52 def metadata(self):
53 """Decoded metadata dictionary"""
53 """Decoded metadata dictionary"""
54 return dict(self._data[3])
54 return dict(self._data[3])
55
55
56 def date(self):
56 def date(self):
57 """Creation date as (unixtime, offset)"""
57 """Creation date as (unixtime, offset)"""
58 return self._data[4]
58 return self._data[4]
59
59
60 def flags(self):
60 def flags(self):
61 """The flags field of the marker"""
61 """The flags field of the marker"""
62 return self._data[2]
62 return self._data[2]
63
63
64 def getmarkers(repo, nodes=None, exclusive=False):
64 def getmarkers(repo, nodes=None, exclusive=False):
65 """returns markers known in a repository
65 """returns markers known in a repository
66
66
67 If <nodes> is specified, only markers "relevant" to those nodes are are
67 If <nodes> is specified, only markers "relevant" to those nodes are are
68 returned"""
68 returned"""
69 if nodes is None:
69 if nodes is None:
70 rawmarkers = repo.obsstore
70 rawmarkers = repo.obsstore
71 elif exclusive:
71 elif exclusive:
72 rawmarkers = exclusivemarkers(repo, nodes)
72 rawmarkers = exclusivemarkers(repo, nodes)
73 else:
73 else:
74 rawmarkers = repo.obsstore.relevantmarkers(nodes)
74 rawmarkers = repo.obsstore.relevantmarkers(nodes)
75
75
76 for markerdata in rawmarkers:
76 for markerdata in rawmarkers:
77 yield marker(repo, markerdata)
77 yield marker(repo, markerdata)
78
78
79 def closestpredecessors(repo, nodeid):
79 def closestpredecessors(repo, nodeid):
80 """yield the list of next predecessors pointing on visible changectx nodes
80 """yield the list of next predecessors pointing on visible changectx nodes
81
81
82 This function respect the repoview filtering, filtered revision will be
82 This function respect the repoview filtering, filtered revision will be
83 considered missing.
83 considered missing.
84 """
84 """
85
85
86 precursors = repo.obsstore.predecessors
86 precursors = repo.obsstore.predecessors
87 stack = [nodeid]
87 stack = [nodeid]
88 seen = set(stack)
88 seen = set(stack)
89
89
90 while stack:
90 while stack:
91 current = stack.pop()
91 current = stack.pop()
92 currentpreccs = precursors.get(current, ())
92 currentpreccs = precursors.get(current, ())
93
93
94 for prec in currentpreccs:
94 for prec in currentpreccs:
95 precnodeid = prec[0]
95 precnodeid = prec[0]
96
96
97 # Basic cycle protection
97 # Basic cycle protection
98 if precnodeid in seen:
98 if precnodeid in seen:
99 continue
99 continue
100 seen.add(precnodeid)
100 seen.add(precnodeid)
101
101
102 if precnodeid in repo:
102 if precnodeid in repo:
103 yield precnodeid
103 yield precnodeid
104 else:
104 else:
105 stack.append(precnodeid)
105 stack.append(precnodeid)
106
106
107 def allprecursors(*args, **kwargs):
107 def allprecursors(*args, **kwargs):
108 """ (DEPRECATED)
108 """ (DEPRECATED)
109 """
109 """
110 msg = ("'obsutil.allprecursors' is deprecated, "
110 msg = ("'obsutil.allprecursors' is deprecated, "
111 "use 'obsutil.allpredecessors'")
111 "use 'obsutil.allpredecessors'")
112 util.nouideprecwarn(msg, '4.4')
112 util.nouideprecwarn(msg, '4.4')
113
113
114 return allpredecessors(*args, **kwargs)
114 return allpredecessors(*args, **kwargs)
115
115
116 def allpredecessors(obsstore, nodes, ignoreflags=0):
116 def allpredecessors(obsstore, nodes, ignoreflags=0):
117 """Yield node for every precursors of <nodes>.
117 """Yield node for every precursors of <nodes>.
118
118
119 Some precursors may be unknown locally.
119 Some precursors may be unknown locally.
120
120
121 This is a linear yield unsuited to detecting folded changesets. It includes
121 This is a linear yield unsuited to detecting folded changesets. It includes
122 initial nodes too."""
122 initial nodes too."""
123
123
124 remaining = set(nodes)
124 remaining = set(nodes)
125 seen = set(remaining)
125 seen = set(remaining)
126 while remaining:
126 while remaining:
127 current = remaining.pop()
127 current = remaining.pop()
128 yield current
128 yield current
129 for mark in obsstore.predecessors.get(current, ()):
129 for mark in obsstore.predecessors.get(current, ()):
130 # ignore marker flagged with specified flag
130 # ignore marker flagged with specified flag
131 if mark[2] & ignoreflags:
131 if mark[2] & ignoreflags:
132 continue
132 continue
133 suc = mark[0]
133 suc = mark[0]
134 if suc not in seen:
134 if suc not in seen:
135 seen.add(suc)
135 seen.add(suc)
136 remaining.add(suc)
136 remaining.add(suc)
137
137
138 def allsuccessors(obsstore, nodes, ignoreflags=0):
138 def allsuccessors(obsstore, nodes, ignoreflags=0):
139 """Yield node for every successor of <nodes>.
139 """Yield node for every successor of <nodes>.
140
140
141 Some successors may be unknown locally.
141 Some successors may be unknown locally.
142
142
143 This is a linear yield unsuited to detecting split changesets. It includes
143 This is a linear yield unsuited to detecting split changesets. It includes
144 initial nodes too."""
144 initial nodes too."""
145 remaining = set(nodes)
145 remaining = set(nodes)
146 seen = set(remaining)
146 seen = set(remaining)
147 while remaining:
147 while remaining:
148 current = remaining.pop()
148 current = remaining.pop()
149 yield current
149 yield current
150 for mark in obsstore.successors.get(current, ()):
150 for mark in obsstore.successors.get(current, ()):
151 # ignore marker flagged with specified flag
151 # ignore marker flagged with specified flag
152 if mark[2] & ignoreflags:
152 if mark[2] & ignoreflags:
153 continue
153 continue
154 for suc in mark[1]:
154 for suc in mark[1]:
155 if suc not in seen:
155 if suc not in seen:
156 seen.add(suc)
156 seen.add(suc)
157 remaining.add(suc)
157 remaining.add(suc)
158
158
159 def _filterprunes(markers):
159 def _filterprunes(markers):
160 """return a set with no prune markers"""
160 """return a set with no prune markers"""
161 return set(m for m in markers if m[1])
161 return set(m for m in markers if m[1])
162
162
163 def exclusivemarkers(repo, nodes):
163 def exclusivemarkers(repo, nodes):
164 """set of markers relevant to "nodes" but no other locally-known nodes
164 """set of markers relevant to "nodes" but no other locally-known nodes
165
165
166 This function compute the set of markers "exclusive" to a locally-known
166 This function compute the set of markers "exclusive" to a locally-known
167 node. This means we walk the markers starting from <nodes> until we reach a
167 node. This means we walk the markers starting from <nodes> until we reach a
168 locally-known precursors outside of <nodes>. Element of <nodes> with
168 locally-known precursors outside of <nodes>. Element of <nodes> with
169 locally-known successors outside of <nodes> are ignored (since their
169 locally-known successors outside of <nodes> are ignored (since their
170 precursors markers are also relevant to these successors).
170 precursors markers are also relevant to these successors).
171
171
172 For example:
172 For example:
173
173
174 # (A0 rewritten as A1)
174 # (A0 rewritten as A1)
175 #
175 #
176 # A0 <-1- A1 # Marker "1" is exclusive to A1
176 # A0 <-1- A1 # Marker "1" is exclusive to A1
177
177
178 or
178 or
179
179
180 # (A0 rewritten as AX; AX rewritten as A1; AX is unkown locally)
180 # (A0 rewritten as AX; AX rewritten as A1; AX is unkown locally)
181 #
181 #
182 # <-1- A0 <-2- AX <-3- A1 # Marker "2,3" are exclusive to A1
182 # <-1- A0 <-2- AX <-3- A1 # Marker "2,3" are exclusive to A1
183
183
184 or
184 or
185
185
186 # (A0 has unknown precursors, A0 rewritten as A1 and A2 (divergence))
186 # (A0 has unknown precursors, A0 rewritten as A1 and A2 (divergence))
187 #
187 #
188 # <-2- A1 # Marker "2" is exclusive to A0,A1
188 # <-2- A1 # Marker "2" is exclusive to A0,A1
189 # /
189 # /
190 # <-1- A0
190 # <-1- A0
191 # \
191 # \
192 # <-3- A2 # Marker "3" is exclusive to A0,A2
192 # <-3- A2 # Marker "3" is exclusive to A0,A2
193 #
193 #
194 # in addition:
194 # in addition:
195 #
195 #
196 # Markers "2,3" are exclusive to A1,A2
196 # Markers "2,3" are exclusive to A1,A2
197 # Markers "1,2,3" are exclusive to A0,A1,A2
197 # Markers "1,2,3" are exclusive to A0,A1,A2
198
198
199 See test/test-obsolete-bundle-strip.t for more examples.
199 See test/test-obsolete-bundle-strip.t for more examples.
200
200
201 An example usage is strip. When stripping a changeset, we also want to
201 An example usage is strip. When stripping a changeset, we also want to
202 strip the markers exclusive to this changeset. Otherwise we would have
202 strip the markers exclusive to this changeset. Otherwise we would have
203 "dangling"" obsolescence markers from its precursors: Obsolescence markers
203 "dangling"" obsolescence markers from its precursors: Obsolescence markers
204 marking a node as obsolete without any successors available locally.
204 marking a node as obsolete without any successors available locally.
205
205
206 As for relevant markers, the prune markers for children will be followed.
206 As for relevant markers, the prune markers for children will be followed.
207 Of course, they will only be followed if the pruned children is
207 Of course, they will only be followed if the pruned children is
208 locally-known. Since the prune markers are relevant to the pruned node.
208 locally-known. Since the prune markers are relevant to the pruned node.
209 However, while prune markers are considered relevant to the parent of the
209 However, while prune markers are considered relevant to the parent of the
210 pruned changesets, prune markers for locally-known changeset (with no
210 pruned changesets, prune markers for locally-known changeset (with no
211 successors) are considered exclusive to the pruned nodes. This allows
211 successors) are considered exclusive to the pruned nodes. This allows
212 to strip the prune markers (with the rest of the exclusive chain) alongside
212 to strip the prune markers (with the rest of the exclusive chain) alongside
213 the pruned changesets.
213 the pruned changesets.
214 """
214 """
215 # running on a filtered repository would be dangerous as markers could be
215 # running on a filtered repository would be dangerous as markers could be
216 # reported as exclusive when they are relevant for other filtered nodes.
216 # reported as exclusive when they are relevant for other filtered nodes.
217 unfi = repo.unfiltered()
217 unfi = repo.unfiltered()
218
218
219 # shortcut to various useful item
219 # shortcut to various useful item
220 nm = unfi.changelog.nodemap
220 nm = unfi.changelog.nodemap
221 precursorsmarkers = unfi.obsstore.predecessors
221 precursorsmarkers = unfi.obsstore.predecessors
222 successormarkers = unfi.obsstore.successors
222 successormarkers = unfi.obsstore.successors
223 childrenmarkers = unfi.obsstore.children
223 childrenmarkers = unfi.obsstore.children
224
224
225 # exclusive markers (return of the function)
225 # exclusive markers (return of the function)
226 exclmarkers = set()
226 exclmarkers = set()
227 # we need fast membership testing
227 # we need fast membership testing
228 nodes = set(nodes)
228 nodes = set(nodes)
229 # looking for head in the obshistory
229 # looking for head in the obshistory
230 #
230 #
231 # XXX we are ignoring all issues in regard with cycle for now.
231 # XXX we are ignoring all issues in regard with cycle for now.
232 stack = [n for n in nodes if not _filterprunes(successormarkers.get(n, ()))]
232 stack = [n for n in nodes if not _filterprunes(successormarkers.get(n, ()))]
233 stack.sort()
233 stack.sort()
234 # nodes already stacked
234 # nodes already stacked
235 seennodes = set(stack)
235 seennodes = set(stack)
236 while stack:
236 while stack:
237 current = stack.pop()
237 current = stack.pop()
238 # fetch precursors markers
238 # fetch precursors markers
239 markers = list(precursorsmarkers.get(current, ()))
239 markers = list(precursorsmarkers.get(current, ()))
240 # extend the list with prune markers
240 # extend the list with prune markers
241 for mark in successormarkers.get(current, ()):
241 for mark in successormarkers.get(current, ()):
242 if not mark[1]:
242 if not mark[1]:
243 markers.append(mark)
243 markers.append(mark)
244 # and markers from children (looking for prune)
244 # and markers from children (looking for prune)
245 for mark in childrenmarkers.get(current, ()):
245 for mark in childrenmarkers.get(current, ()):
246 if not mark[1]:
246 if not mark[1]:
247 markers.append(mark)
247 markers.append(mark)
248 # traverse the markers
248 # traverse the markers
249 for mark in markers:
249 for mark in markers:
250 if mark in exclmarkers:
250 if mark in exclmarkers:
251 # markers already selected
251 # markers already selected
252 continue
252 continue
253
253
254 # If the markers is about the current node, select it
254 # If the markers is about the current node, select it
255 #
255 #
256 # (this delay the addition of markers from children)
256 # (this delay the addition of markers from children)
257 if mark[1] or mark[0] == current:
257 if mark[1] or mark[0] == current:
258 exclmarkers.add(mark)
258 exclmarkers.add(mark)
259
259
260 # should we keep traversing through the precursors?
260 # should we keep traversing through the precursors?
261 prec = mark[0]
261 prec = mark[0]
262
262
263 # nodes in the stack or already processed
263 # nodes in the stack or already processed
264 if prec in seennodes:
264 if prec in seennodes:
265 continue
265 continue
266
266
267 # is this a locally known node ?
267 # is this a locally known node ?
268 known = prec in nm
268 known = prec in nm
269 # if locally-known and not in the <nodes> set the traversal
269 # if locally-known and not in the <nodes> set the traversal
270 # stop here.
270 # stop here.
271 if known and prec not in nodes:
271 if known and prec not in nodes:
272 continue
272 continue
273
273
274 # do not keep going if there are unselected markers pointing to this
274 # do not keep going if there are unselected markers pointing to this
275 # nodes. If we end up traversing these unselected markers later the
275 # nodes. If we end up traversing these unselected markers later the
276 # node will be taken care of at that point.
276 # node will be taken care of at that point.
277 precmarkers = _filterprunes(successormarkers.get(prec))
277 precmarkers = _filterprunes(successormarkers.get(prec))
278 if precmarkers.issubset(exclmarkers):
278 if precmarkers.issubset(exclmarkers):
279 seennodes.add(prec)
279 seennodes.add(prec)
280 stack.append(prec)
280 stack.append(prec)
281
281
282 return exclmarkers
282 return exclmarkers
283
283
284 def foreground(repo, nodes):
284 def foreground(repo, nodes):
285 """return all nodes in the "foreground" of other node
285 """return all nodes in the "foreground" of other node
286
286
287 The foreground of a revision is anything reachable using parent -> children
287 The foreground of a revision is anything reachable using parent -> children
288 or precursor -> successor relation. It is very similar to "descendant" but
288 or precursor -> successor relation. It is very similar to "descendant" but
289 augmented with obsolescence information.
289 augmented with obsolescence information.
290
290
291 Beware that possible obsolescence cycle may result if complex situation.
291 Beware that possible obsolescence cycle may result if complex situation.
292 """
292 """
293 repo = repo.unfiltered()
293 repo = repo.unfiltered()
294 foreground = set(repo.set('%ln::', nodes))
294 foreground = set(repo.set('%ln::', nodes))
295 if repo.obsstore:
295 if repo.obsstore:
296 # We only need this complicated logic if there is obsolescence
296 # We only need this complicated logic if there is obsolescence
297 # XXX will probably deserve an optimised revset.
297 # XXX will probably deserve an optimised revset.
298 nm = repo.changelog.nodemap
298 nm = repo.changelog.nodemap
299 plen = -1
299 plen = -1
300 # compute the whole set of successors or descendants
300 # compute the whole set of successors or descendants
301 while len(foreground) != plen:
301 while len(foreground) != plen:
302 plen = len(foreground)
302 plen = len(foreground)
303 succs = set(c.node() for c in foreground)
303 succs = set(c.node() for c in foreground)
304 mutable = [c.node() for c in foreground if c.mutable()]
304 mutable = [c.node() for c in foreground if c.mutable()]
305 succs.update(allsuccessors(repo.obsstore, mutable))
305 succs.update(allsuccessors(repo.obsstore, mutable))
306 known = (n for n in succs if n in nm)
306 known = (n for n in succs if n in nm)
307 foreground = set(repo.set('%ln::', known))
307 foreground = set(repo.set('%ln::', known))
308 return set(c.node() for c in foreground)
308 return set(c.node() for c in foreground)
309
309
310 # effectflag field
310 # effectflag field
311 #
311 #
312 # Effect-flag is a 1-byte bit field used to store what changed between a
312 # Effect-flag is a 1-byte bit field used to store what changed between a
313 # changeset and its successor(s).
313 # changeset and its successor(s).
314 #
314 #
315 # The effect flag is stored in obs-markers metadata while we iterate on the
315 # The effect flag is stored in obs-markers metadata while we iterate on the
316 # information design. That's why we have the EFFECTFLAGFIELD. If we come up
316 # information design. That's why we have the EFFECTFLAGFIELD. If we come up
317 # with an incompatible design for effect flag, we can store a new design under
317 # with an incompatible design for effect flag, we can store a new design under
318 # another field name so we don't break readers. We plan to extend the existing
318 # another field name so we don't break readers. We plan to extend the existing
319 # obsmarkers bit-field when the effect flag design will be stabilized.
319 # obsmarkers bit-field when the effect flag design will be stabilized.
320 #
320 #
321 # The effect-flag is placed behind an experimental flag
321 # The effect-flag is placed behind an experimental flag
322 # `effect-flags` set to off by default.
322 # `effect-flags` set to off by default.
323 #
323 #
324
324
325 EFFECTFLAGFIELD = "ef1"
325 EFFECTFLAGFIELD = "ef1"
326
326
327 DESCCHANGED = 1 << 0 # action changed the description
327 DESCCHANGED = 1 << 0 # action changed the description
328 METACHANGED = 1 << 1 # action change the meta
328 METACHANGED = 1 << 1 # action change the meta
329 DIFFCHANGED = 1 << 3 # action change diff introduced by the changeset
329 DIFFCHANGED = 1 << 3 # action change diff introduced by the changeset
330 PARENTCHANGED = 1 << 2 # action change the parent
330 PARENTCHANGED = 1 << 2 # action change the parent
331 USERCHANGED = 1 << 4 # the user changed
331 USERCHANGED = 1 << 4 # the user changed
332 DATECHANGED = 1 << 5 # the date changed
332 DATECHANGED = 1 << 5 # the date changed
333 BRANCHCHANGED = 1 << 6 # the branch changed
333 BRANCHCHANGED = 1 << 6 # the branch changed
334
334
335 METABLACKLIST = [
335 METABLACKLIST = [
336 re.compile('^branch$'),
336 re.compile('^branch$'),
337 re.compile('^.*-source$'),
337 re.compile('^.*-source$'),
338 re.compile('^.*_source$'),
338 re.compile('^.*_source$'),
339 re.compile('^source$'),
339 re.compile('^source$'),
340 ]
340 ]
341
341
342 def metanotblacklisted(metaitem):
342 def metanotblacklisted(metaitem):
343 """ Check that the key of a meta item (extrakey, extravalue) does not
343 """ Check that the key of a meta item (extrakey, extravalue) does not
344 match at least one of the blacklist pattern
344 match at least one of the blacklist pattern
345 """
345 """
346 metakey = metaitem[0]
346 metakey = metaitem[0]
347
347
348 return not any(pattern.match(metakey) for pattern in METABLACKLIST)
348 return not any(pattern.match(metakey) for pattern in METABLACKLIST)
349
349
350 def _prepare_hunk(hunk):
350 def _prepare_hunk(hunk):
351 """Drop all information but the username and patch"""
351 """Drop all information but the username and patch"""
352 cleanhunk = []
352 cleanhunk = []
353 for line in hunk.splitlines():
353 for line in hunk.splitlines():
354 if line.startswith(b'# User') or not line.startswith(b'#'):
354 if line.startswith(b'# User') or not line.startswith(b'#'):
355 if line.startswith(b'@@'):
355 if line.startswith(b'@@'):
356 line = b'@@\n'
356 line = b'@@\n'
357 cleanhunk.append(line)
357 cleanhunk.append(line)
358 return cleanhunk
358 return cleanhunk
359
359
360 def _getdifflines(iterdiff):
360 def _getdifflines(iterdiff):
361 """return a cleaned up lines"""
361 """return a cleaned up lines"""
362 lines = next(iterdiff, None)
362 lines = next(iterdiff, None)
363
363
364 if lines is None:
364 if lines is None:
365 return lines
365 return lines
366
366
367 return _prepare_hunk(lines)
367 return _prepare_hunk(lines)
368
368
369 def _cmpdiff(leftctx, rightctx):
369 def _cmpdiff(leftctx, rightctx):
370 """return True if both ctx introduce the "same diff"
370 """return True if both ctx introduce the "same diff"
371
371
372 This is a first and basic implementation, with many shortcoming.
372 This is a first and basic implementation, with many shortcoming.
373 """
373 """
374
374
375 # Leftctx or right ctx might be filtered, so we need to use the contexts
375 # Leftctx or right ctx might be filtered, so we need to use the contexts
376 # with an unfiltered repository to safely compute the diff
376 # with an unfiltered repository to safely compute the diff
377 leftunfi = leftctx._repo.unfiltered()[leftctx.rev()]
377 leftunfi = leftctx._repo.unfiltered()[leftctx.rev()]
378 leftdiff = leftunfi.diff(git=1)
378 leftdiff = leftunfi.diff(git=1)
379 rightunfi = rightctx._repo.unfiltered()[rightctx.rev()]
379 rightunfi = rightctx._repo.unfiltered()[rightctx.rev()]
380 rightdiff = rightunfi.diff(git=1)
380 rightdiff = rightunfi.diff(git=1)
381
381
382 left, right = (0, 0)
382 left, right = (0, 0)
383 while None not in (left, right):
383 while None not in (left, right):
384 left = _getdifflines(leftdiff)
384 left = _getdifflines(leftdiff)
385 right = _getdifflines(rightdiff)
385 right = _getdifflines(rightdiff)
386
386
387 if left != right:
387 if left != right:
388 return False
388 return False
389 return True
389 return True
390
390
391 def geteffectflag(relation):
391 def geteffectflag(relation):
392 """ From an obs-marker relation, compute what changed between the
392 """ From an obs-marker relation, compute what changed between the
393 predecessor and the successor.
393 predecessor and the successor.
394 """
394 """
395 effects = 0
395 effects = 0
396
396
397 source = relation[0]
397 source = relation[0]
398
398
399 for changectx in relation[1]:
399 for changectx in relation[1]:
400 # Check if description has changed
400 # Check if description has changed
401 if changectx.description() != source.description():
401 if changectx.description() != source.description():
402 effects |= DESCCHANGED
402 effects |= DESCCHANGED
403
403
404 # Check if user has changed
404 # Check if user has changed
405 if changectx.user() != source.user():
405 if changectx.user() != source.user():
406 effects |= USERCHANGED
406 effects |= USERCHANGED
407
407
408 # Check if date has changed
408 # Check if date has changed
409 if changectx.date() != source.date():
409 if changectx.date() != source.date():
410 effects |= DATECHANGED
410 effects |= DATECHANGED
411
411
412 # Check if branch has changed
412 # Check if branch has changed
413 if changectx.branch() != source.branch():
413 if changectx.branch() != source.branch():
414 effects |= BRANCHCHANGED
414 effects |= BRANCHCHANGED
415
415
416 # Check if at least one of the parent has changed
416 # Check if at least one of the parent has changed
417 if changectx.parents() != source.parents():
417 if changectx.parents() != source.parents():
418 effects |= PARENTCHANGED
418 effects |= PARENTCHANGED
419
419
420 # Check if other meta has changed
420 # Check if other meta has changed
421 changeextra = changectx.extra().items()
421 changeextra = changectx.extra().items()
422 ctxmeta = filter(metanotblacklisted, changeextra)
422 ctxmeta = filter(metanotblacklisted, changeextra)
423
423
424 sourceextra = source.extra().items()
424 sourceextra = source.extra().items()
425 srcmeta = filter(metanotblacklisted, sourceextra)
425 srcmeta = filter(metanotblacklisted, sourceextra)
426
426
427 if ctxmeta != srcmeta:
427 if ctxmeta != srcmeta:
428 effects |= METACHANGED
428 effects |= METACHANGED
429
429
430 # Check if the diff has changed
430 # Check if the diff has changed
431 if not _cmpdiff(source, changectx):
431 if not _cmpdiff(source, changectx):
432 effects |= DIFFCHANGED
432 effects |= DIFFCHANGED
433
433
434 return effects
434 return effects
435
435
436 def getobsoleted(repo, tr):
436 def getobsoleted(repo, tr):
437 """return the set of pre-existing revisions obsoleted by a transaction"""
437 """return the set of pre-existing revisions obsoleted by a transaction"""
438 torev = repo.unfiltered().changelog.nodemap.get
438 torev = repo.unfiltered().changelog.nodemap.get
439 phase = repo._phasecache.phase
439 phase = repo._phasecache.phase
440 succsmarkers = repo.obsstore.successors.get
440 succsmarkers = repo.obsstore.successors.get
441 public = phases.public
441 public = phases.public
442 addedmarkers = tr.changes.get('obsmarkers')
442 addedmarkers = tr.changes.get('obsmarkers')
443 addedrevs = tr.changes.get('revs')
443 addedrevs = tr.changes.get('revs')
444 seenrevs = set(addedrevs)
444 seenrevs = set(addedrevs)
445 obsoleted = set()
445 obsoleted = set()
446 for mark in addedmarkers:
446 for mark in addedmarkers:
447 node = mark[0]
447 node = mark[0]
448 rev = torev(node)
448 rev = torev(node)
449 if rev is None or rev in seenrevs:
449 if rev is None or rev in seenrevs:
450 continue
450 continue
451 seenrevs.add(rev)
451 seenrevs.add(rev)
452 if phase(repo, rev) == public:
452 if phase(repo, rev) == public:
453 continue
453 continue
454 if set(succsmarkers(node) or []).issubset(addedmarkers):
454 if set(succsmarkers(node) or []).issubset(addedmarkers):
455 obsoleted.add(rev)
455 obsoleted.add(rev)
456 return obsoleted
456 return obsoleted
457
457
458 class _succs(list):
458 class _succs(list):
459 """small class to represent a successors with some metadata about it"""
459 """small class to represent a successors with some metadata about it"""
460
460
461 def __init__(self, *args, **kwargs):
461 def __init__(self, *args, **kwargs):
462 super(_succs, self).__init__(*args, **kwargs)
462 super(_succs, self).__init__(*args, **kwargs)
463 self.markers = set()
463 self.markers = set()
464
464
465 def copy(self):
465 def copy(self):
466 new = _succs(self)
466 new = _succs(self)
467 new.markers = self.markers.copy()
467 new.markers = self.markers.copy()
468 return new
468 return new
469
469
470 @util.propertycache
470 @util.propertycache
471 def _set(self):
471 def _set(self):
472 # immutable
472 # immutable
473 return set(self)
473 return set(self)
474
474
475 def canmerge(self, other):
475 def canmerge(self, other):
476 return self._set.issubset(other._set)
476 return self._set.issubset(other._set)
477
477
478 def successorssets(repo, initialnode, closest=False, cache=None):
478 def successorssets(repo, initialnode, closest=False, cache=None):
479 """Return set of all latest successors of initial nodes
479 """Return set of all latest successors of initial nodes
480
480
481 The successors set of a changeset A are the group of revisions that succeed
481 The successors set of a changeset A are the group of revisions that succeed
482 A. It succeeds A as a consistent whole, each revision being only a partial
482 A. It succeeds A as a consistent whole, each revision being only a partial
483 replacement. By default, the successors set contains non-obsolete
483 replacement. By default, the successors set contains non-obsolete
484 changesets only, walking the obsolescence graph until reaching a leaf. If
484 changesets only, walking the obsolescence graph until reaching a leaf. If
485 'closest' is set to True, closest successors-sets are return (the
485 'closest' is set to True, closest successors-sets are return (the
486 obsolescence walk stops on known changesets).
486 obsolescence walk stops on known changesets).
487
487
488 This function returns the full list of successor sets which is why it
488 This function returns the full list of successor sets which is why it
489 returns a list of tuples and not just a single tuple. Each tuple is a valid
489 returns a list of tuples and not just a single tuple. Each tuple is a valid
490 successors set. Note that (A,) may be a valid successors set for changeset A
490 successors set. Note that (A,) may be a valid successors set for changeset A
491 (see below).
491 (see below).
492
492
493 In most cases, a changeset A will have a single element (e.g. the changeset
493 In most cases, a changeset A will have a single element (e.g. the changeset
494 A is replaced by A') in its successors set. Though, it is also common for a
494 A is replaced by A') in its successors set. Though, it is also common for a
495 changeset A to have no elements in its successor set (e.g. the changeset
495 changeset A to have no elements in its successor set (e.g. the changeset
496 has been pruned). Therefore, the returned list of successors sets will be
496 has been pruned). Therefore, the returned list of successors sets will be
497 [(A',)] or [], respectively.
497 [(A',)] or [], respectively.
498
498
499 When a changeset A is split into A' and B', however, it will result in a
499 When a changeset A is split into A' and B', however, it will result in a
500 successors set containing more than a single element, i.e. [(A',B')].
500 successors set containing more than a single element, i.e. [(A',B')].
501 Divergent changesets will result in multiple successors sets, i.e. [(A',),
501 Divergent changesets will result in multiple successors sets, i.e. [(A',),
502 (A'')].
502 (A'')].
503
503
504 If a changeset A is not obsolete, then it will conceptually have no
504 If a changeset A is not obsolete, then it will conceptually have no
505 successors set. To distinguish this from a pruned changeset, the successor
505 successors set. To distinguish this from a pruned changeset, the successor
506 set will contain itself only, i.e. [(A,)].
506 set will contain itself only, i.e. [(A,)].
507
507
508 Finally, final successors unknown locally are considered to be pruned
508 Finally, final successors unknown locally are considered to be pruned
509 (pruned: obsoleted without any successors). (Final: successors not affected
509 (pruned: obsoleted without any successors). (Final: successors not affected
510 by markers).
510 by markers).
511
511
512 The 'closest' mode respect the repoview filtering. For example, without
512 The 'closest' mode respect the repoview filtering. For example, without
513 filter it will stop at the first locally known changeset, with 'visible'
513 filter it will stop at the first locally known changeset, with 'visible'
514 filter it will stop on visible changesets).
514 filter it will stop on visible changesets).
515
515
516 The optional `cache` parameter is a dictionary that may contains
516 The optional `cache` parameter is a dictionary that may contains
517 precomputed successors sets. It is meant to reuse the computation of a
517 precomputed successors sets. It is meant to reuse the computation of a
518 previous call to `successorssets` when multiple calls are made at the same
518 previous call to `successorssets` when multiple calls are made at the same
519 time. The cache dictionary is updated in place. The caller is responsible
519 time. The cache dictionary is updated in place. The caller is responsible
520 for its life span. Code that makes multiple calls to `successorssets`
520 for its life span. Code that makes multiple calls to `successorssets`
521 *should* use this cache mechanism or risk a performance hit.
521 *should* use this cache mechanism or risk a performance hit.
522
522
523 Since results are different depending of the 'closest' most, the same cache
523 Since results are different depending of the 'closest' most, the same cache
524 cannot be reused for both mode.
524 cannot be reused for both mode.
525 """
525 """
526
526
527 succmarkers = repo.obsstore.successors
527 succmarkers = repo.obsstore.successors
528
528
529 # Stack of nodes we search successors sets for
529 # Stack of nodes we search successors sets for
530 toproceed = [initialnode]
530 toproceed = [initialnode]
531 # set version of above list for fast loop detection
531 # set version of above list for fast loop detection
532 # element added to "toproceed" must be added here
532 # element added to "toproceed" must be added here
533 stackedset = set(toproceed)
533 stackedset = set(toproceed)
534 if cache is None:
534 if cache is None:
535 cache = {}
535 cache = {}
536
536
537 # This while loop is the flattened version of a recursive search for
537 # This while loop is the flattened version of a recursive search for
538 # successors sets
538 # successors sets
539 #
539 #
540 # def successorssets(x):
540 # def successorssets(x):
541 # successors = directsuccessors(x)
541 # successors = directsuccessors(x)
542 # ss = [[]]
542 # ss = [[]]
543 # for succ in directsuccessors(x):
543 # for succ in directsuccessors(x):
544 # # product as in itertools cartesian product
544 # # product as in itertools cartesian product
545 # ss = product(ss, successorssets(succ))
545 # ss = product(ss, successorssets(succ))
546 # return ss
546 # return ss
547 #
547 #
548 # But we can not use plain recursive calls here:
548 # But we can not use plain recursive calls here:
549 # - that would blow the python call stack
549 # - that would blow the python call stack
550 # - obsolescence markers may have cycles, we need to handle them.
550 # - obsolescence markers may have cycles, we need to handle them.
551 #
551 #
552 # The `toproceed` list act as our call stack. Every node we search
552 # The `toproceed` list act as our call stack. Every node we search
553 # successors set for are stacked there.
553 # successors set for are stacked there.
554 #
554 #
555 # The `stackedset` is set version of this stack used to check if a node is
555 # The `stackedset` is set version of this stack used to check if a node is
556 # already stacked. This check is used to detect cycles and prevent infinite
556 # already stacked. This check is used to detect cycles and prevent infinite
557 # loop.
557 # loop.
558 #
558 #
559 # successors set of all nodes are stored in the `cache` dictionary.
559 # successors set of all nodes are stored in the `cache` dictionary.
560 #
560 #
561 # After this while loop ends we use the cache to return the successors sets
561 # After this while loop ends we use the cache to return the successors sets
562 # for the node requested by the caller.
562 # for the node requested by the caller.
563 while toproceed:
563 while toproceed:
564 # Every iteration tries to compute the successors sets of the topmost
564 # Every iteration tries to compute the successors sets of the topmost
565 # node of the stack: CURRENT.
565 # node of the stack: CURRENT.
566 #
566 #
567 # There are four possible outcomes:
567 # There are four possible outcomes:
568 #
568 #
569 # 1) We already know the successors sets of CURRENT:
569 # 1) We already know the successors sets of CURRENT:
570 # -> mission accomplished, pop it from the stack.
570 # -> mission accomplished, pop it from the stack.
571 # 2) Stop the walk:
571 # 2) Stop the walk:
572 # default case: Node is not obsolete
572 # default case: Node is not obsolete
573 # closest case: Node is known at this repo filter level
573 # closest case: Node is known at this repo filter level
574 # -> the node is its own successors sets. Add it to the cache.
574 # -> the node is its own successors sets. Add it to the cache.
575 # 3) We do not know successors set of direct successors of CURRENT:
575 # 3) We do not know successors set of direct successors of CURRENT:
576 # -> We add those successors to the stack.
576 # -> We add those successors to the stack.
577 # 4) We know successors sets of all direct successors of CURRENT:
577 # 4) We know successors sets of all direct successors of CURRENT:
578 # -> We can compute CURRENT successors set and add it to the
578 # -> We can compute CURRENT successors set and add it to the
579 # cache.
579 # cache.
580 #
580 #
581 current = toproceed[-1]
581 current = toproceed[-1]
582
582
583 # case 2 condition is a bit hairy because of closest,
583 # case 2 condition is a bit hairy because of closest,
584 # we compute it on its own
584 # we compute it on its own
585 case2condition = ((current not in succmarkers)
585 case2condition = ((current not in succmarkers)
586 or (closest and current != initialnode
586 or (closest and current != initialnode
587 and current in repo))
587 and current in repo))
588
588
589 if current in cache:
589 if current in cache:
590 # case (1): We already know the successors sets
590 # case (1): We already know the successors sets
591 stackedset.remove(toproceed.pop())
591 stackedset.remove(toproceed.pop())
592 elif case2condition:
592 elif case2condition:
593 # case (2): end of walk.
593 # case (2): end of walk.
594 if current in repo:
594 if current in repo:
595 # We have a valid successors.
595 # We have a valid successors.
596 cache[current] = [_succs((current,))]
596 cache[current] = [_succs((current,))]
597 else:
597 else:
598 # Final obsolete version is unknown locally.
598 # Final obsolete version is unknown locally.
599 # Do not count that as a valid successors
599 # Do not count that as a valid successors
600 cache[current] = []
600 cache[current] = []
601 else:
601 else:
602 # cases (3) and (4)
602 # cases (3) and (4)
603 #
603 #
604 # We proceed in two phases. Phase 1 aims to distinguish case (3)
604 # We proceed in two phases. Phase 1 aims to distinguish case (3)
605 # from case (4):
605 # from case (4):
606 #
606 #
607 # For each direct successors of CURRENT, we check whether its
607 # For each direct successors of CURRENT, we check whether its
608 # successors sets are known. If they are not, we stack the
608 # successors sets are known. If they are not, we stack the
609 # unknown node and proceed to the next iteration of the while
609 # unknown node and proceed to the next iteration of the while
610 # loop. (case 3)
610 # loop. (case 3)
611 #
611 #
612 # During this step, we may detect obsolescence cycles: a node
612 # During this step, we may detect obsolescence cycles: a node
613 # with unknown successors sets but already in the call stack.
613 # with unknown successors sets but already in the call stack.
614 # In such a situation, we arbitrary set the successors sets of
614 # In such a situation, we arbitrary set the successors sets of
615 # the node to nothing (node pruned) to break the cycle.
615 # the node to nothing (node pruned) to break the cycle.
616 #
616 #
617 # If no break was encountered we proceed to phase 2.
617 # If no break was encountered we proceed to phase 2.
618 #
618 #
619 # Phase 2 computes successors sets of CURRENT (case 4); see details
619 # Phase 2 computes successors sets of CURRENT (case 4); see details
620 # in phase 2 itself.
620 # in phase 2 itself.
621 #
621 #
622 # Note the two levels of iteration in each phase.
622 # Note the two levels of iteration in each phase.
623 # - The first one handles obsolescence markers using CURRENT as
623 # - The first one handles obsolescence markers using CURRENT as
624 # precursor (successors markers of CURRENT).
624 # precursor (successors markers of CURRENT).
625 #
625 #
626 # Having multiple entry here means divergence.
626 # Having multiple entry here means divergence.
627 #
627 #
628 # - The second one handles successors defined in each marker.
628 # - The second one handles successors defined in each marker.
629 #
629 #
630 # Having none means pruned node, multiple successors means split,
630 # Having none means pruned node, multiple successors means split,
631 # single successors are standard replacement.
631 # single successors are standard replacement.
632 #
632 #
633 for mark in sorted(succmarkers[current]):
633 for mark in sorted(succmarkers[current]):
634 for suc in mark[1]:
634 for suc in mark[1]:
635 if suc not in cache:
635 if suc not in cache:
636 if suc in stackedset:
636 if suc in stackedset:
637 # cycle breaking
637 # cycle breaking
638 cache[suc] = []
638 cache[suc] = []
639 else:
639 else:
640 # case (3) If we have not computed successors sets
640 # case (3) If we have not computed successors sets
641 # of one of those successors we add it to the
641 # of one of those successors we add it to the
642 # `toproceed` stack and stop all work for this
642 # `toproceed` stack and stop all work for this
643 # iteration.
643 # iteration.
644 toproceed.append(suc)
644 toproceed.append(suc)
645 stackedset.add(suc)
645 stackedset.add(suc)
646 break
646 break
647 else:
647 else:
648 continue
648 continue
649 break
649 break
650 else:
650 else:
651 # case (4): we know all successors sets of all direct
651 # case (4): we know all successors sets of all direct
652 # successors
652 # successors
653 #
653 #
654 # Successors set contributed by each marker depends on the
654 # Successors set contributed by each marker depends on the
655 # successors sets of all its "successors" node.
655 # successors sets of all its "successors" node.
656 #
656 #
657 # Each different marker is a divergence in the obsolescence
657 # Each different marker is a divergence in the obsolescence
658 # history. It contributes successors sets distinct from other
658 # history. It contributes successors sets distinct from other
659 # markers.
659 # markers.
660 #
660 #
661 # Within a marker, a successor may have divergent successors
661 # Within a marker, a successor may have divergent successors
662 # sets. In such a case, the marker will contribute multiple
662 # sets. In such a case, the marker will contribute multiple
663 # divergent successors sets. If multiple successors have
663 # divergent successors sets. If multiple successors have
664 # divergent successors sets, a Cartesian product is used.
664 # divergent successors sets, a Cartesian product is used.
665 #
665 #
666 # At the end we post-process successors sets to remove
666 # At the end we post-process successors sets to remove
667 # duplicated entry and successors set that are strict subset of
667 # duplicated entry and successors set that are strict subset of
668 # another one.
668 # another one.
669 succssets = []
669 succssets = []
670 for mark in sorted(succmarkers[current]):
670 for mark in sorted(succmarkers[current]):
671 # successors sets contributed by this marker
671 # successors sets contributed by this marker
672 base = _succs()
672 base = _succs()
673 base.markers.add(mark)
673 base.markers.add(mark)
674 markss = [base]
674 markss = [base]
675 for suc in mark[1]:
675 for suc in mark[1]:
676 # cardinal product with previous successors
676 # cardinal product with previous successors
677 productresult = []
677 productresult = []
678 for prefix in markss:
678 for prefix in markss:
679 for suffix in cache[suc]:
679 for suffix in cache[suc]:
680 newss = prefix.copy()
680 newss = prefix.copy()
681 newss.markers.update(suffix.markers)
681 newss.markers.update(suffix.markers)
682 for part in suffix:
682 for part in suffix:
683 # do not duplicated entry in successors set
683 # do not duplicated entry in successors set
684 # first entry wins.
684 # first entry wins.
685 if part not in newss:
685 if part not in newss:
686 newss.append(part)
686 newss.append(part)
687 productresult.append(newss)
687 productresult.append(newss)
688 markss = productresult
688 markss = productresult
689 succssets.extend(markss)
689 succssets.extend(markss)
690 # remove duplicated and subset
690 # remove duplicated and subset
691 seen = []
691 seen = []
692 final = []
692 final = []
693 candidates = sorted((s for s in succssets if s),
693 candidates = sorted((s for s in succssets if s),
694 key=len, reverse=True)
694 key=len, reverse=True)
695 for cand in candidates:
695 for cand in candidates:
696 for seensuccs in seen:
696 for seensuccs in seen:
697 if cand.canmerge(seensuccs):
697 if cand.canmerge(seensuccs):
698 seensuccs.markers.update(cand.markers)
698 seensuccs.markers.update(cand.markers)
699 break
699 break
700 else:
700 else:
701 final.append(cand)
701 final.append(cand)
702 seen.append(cand)
702 seen.append(cand)
703 final.reverse() # put small successors set first
703 final.reverse() # put small successors set first
704 cache[current] = final
704 cache[current] = final
705 return cache[initialnode]
705 return cache[initialnode]
706
706
707 def successorsandmarkers(repo, ctx):
707 def successorsandmarkers(repo, ctx):
708 """compute the raw data needed for computing obsfate
708 """compute the raw data needed for computing obsfate
709 Returns a list of dict, one dict per successors set
709 Returns a list of dict, one dict per successors set
710 """
710 """
711 if not ctx.obsolete():
711 if not ctx.obsolete():
712 return None
712 return None
713
713
714 ssets = successorssets(repo, ctx.node(), closest=True)
714 ssets = successorssets(repo, ctx.node(), closest=True)
715
715
716 # closestsuccessors returns an empty list for pruned revisions, remap it
716 # closestsuccessors returns an empty list for pruned revisions, remap it
717 # into a list containing an empty list for future processing
717 # into a list containing an empty list for future processing
718 if ssets == []:
718 if ssets == []:
719 ssets = [[]]
719 ssets = [[]]
720
720
721 # Try to recover pruned markers
721 # Try to recover pruned markers
722 succsmap = repo.obsstore.successors
722 succsmap = repo.obsstore.successors
723 fullsuccessorsets = [] # successor set + markers
723 fullsuccessorsets = [] # successor set + markers
724 for sset in ssets:
724 for sset in ssets:
725 if sset:
725 if sset:
726 fullsuccessorsets.append(sset)
726 fullsuccessorsets.append(sset)
727 else:
727 else:
728 # successorsset return an empty set() when ctx or one of its
728 # successorsset return an empty set() when ctx or one of its
729 # successors is pruned.
729 # successors is pruned.
730 # In this case, walk the obs-markers tree again starting with ctx
730 # In this case, walk the obs-markers tree again starting with ctx
731 # and find the relevant pruning obs-makers, the ones without
731 # and find the relevant pruning obs-makers, the ones without
732 # successors.
732 # successors.
733 # Having these markers allow us to compute some information about
733 # Having these markers allow us to compute some information about
734 # its fate, like who pruned this changeset and when.
734 # its fate, like who pruned this changeset and when.
735
735
736 # XXX we do not catch all prune markers (eg rewritten then pruned)
736 # XXX we do not catch all prune markers (eg rewritten then pruned)
737 # (fix me later)
737 # (fix me later)
738 foundany = False
738 foundany = False
739 for mark in succsmap.get(ctx.node(), ()):
739 for mark in succsmap.get(ctx.node(), ()):
740 if not mark[1]:
740 if not mark[1]:
741 foundany = True
741 foundany = True
742 sset = _succs()
742 sset = _succs()
743 sset.markers.add(mark)
743 sset.markers.add(mark)
744 fullsuccessorsets.append(sset)
744 fullsuccessorsets.append(sset)
745 if not foundany:
745 if not foundany:
746 fullsuccessorsets.append(_succs())
746 fullsuccessorsets.append(_succs())
747
747
748 values = []
748 values = []
749 for sset in fullsuccessorsets:
749 for sset in fullsuccessorsets:
750 values.append({'successors': sset, 'markers': sset.markers})
750 values.append({'successors': sset, 'markers': sset.markers})
751
751
752 return values
752 return values
753
753
754 def successorsetverb(successorset):
754 def successorsetverb(successorset):
755 """ Return the verb summarizing the successorset
755 """ Return the verb summarizing the successorset
756 """
756 """
757 if not successorset:
757 if not successorset:
758 verb = 'pruned'
758 verb = 'pruned'
759 elif len(successorset) == 1:
759 elif len(successorset) == 1:
760 verb = 'rewritten'
760 verb = 'rewritten'
761 else:
761 else:
762 verb = 'split'
762 verb = 'split'
763 return verb
763 return verb
764
764
765 def markersdates(markers):
765 def markersdates(markers):
766 """returns the list of dates for a list of markers
766 """returns the list of dates for a list of markers
767 """
767 """
768 return [m[4] for m in markers]
768 return [m[4] for m in markers]
769
769
770 def markersusers(markers):
770 def markersusers(markers):
771 """ Returns a sorted list of markers users without duplicates
771 """ Returns a sorted list of markers users without duplicates
772 """
772 """
773 markersmeta = [dict(m[3]) for m in markers]
773 markersmeta = [dict(m[3]) for m in markers]
774 users = set(meta.get('user') for meta in markersmeta if meta.get('user'))
774 users = set(meta.get('user') for meta in markersmeta if meta.get('user'))
775
775
776 return sorted(users)
776 return sorted(users)
777
777
778 def markersoperations(markers):
778 def markersoperations(markers):
779 """ Returns a sorted list of markers operations without duplicates
779 """ Returns a sorted list of markers operations without duplicates
780 """
780 """
781 markersmeta = [dict(m[3]) for m in markers]
781 markersmeta = [dict(m[3]) for m in markers]
782 operations = set(meta.get('operation') for meta in markersmeta
782 operations = set(meta.get('operation') for meta in markersmeta
783 if meta.get('operation'))
783 if meta.get('operation'))
784
784
785 return sorted(operations)
785 return sorted(operations)
786
787 def obsfateprinter(successors, markers, ui):
788 """ Build a obsfate string for a single successorset using all obsfate
789 related function defined in obsutil
790 """
791 line = []
792
793 # Verb
794 line.append(successorsetverb(successors))
795
796 # Operations
797 operations = markersoperations(markers)
798 if operations:
799 line.append(" using %s" % ", ".join(operations))
800
801 # Successors
802 if successors:
803 fmtsuccessors = [successors.joinfmt(succ) for succ in successors]
804 line.append(" as %s" % ", ".join(fmtsuccessors))
805
806 # Users
807 users = markersusers(markers)
808
809 if users:
810 line.append(" by %s" % ", ".join(users))
811
812 # Date
813 dates = markersdates(markers)
814
815 min_date = min(dates)
816 max_date = max(dates)
817
818 if min_date == max_date:
819 fmtmin_date = util.datestr(min_date, '%Y-%m-%d %H:%M %1%2')
820 line.append(" (at %s)" % fmtmin_date)
821 else:
822 fmtmin_date = util.datestr(min_date, '%Y-%m-%d %H:%M %1%2')
823 fmtmax_date = util.datestr(max_date, '%Y-%m-%d %H:%M %1%2')
824 line.append(" (between %s and %s)" % (fmtmin_date, fmtmax_date))
825
826 return "".join(line)
@@ -1,878 +1,895
1 # templatekw.py - common changeset template keywords
1 # templatekw.py - common changeset template keywords
2 #
2 #
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2009 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 hex,
12 hex,
13 nullid,
13 nullid,
14 )
14 )
15
15
16 from . import (
16 from . import (
17 encoding,
17 encoding,
18 error,
18 error,
19 hbisect,
19 hbisect,
20 obsutil,
20 obsutil,
21 patch,
21 patch,
22 pycompat,
22 pycompat,
23 registrar,
23 registrar,
24 scmutil,
24 scmutil,
25 util,
25 util,
26 )
26 )
27
27
28 class _hybrid(object):
28 class _hybrid(object):
29 """Wrapper for list or dict to support legacy template
29 """Wrapper for list or dict to support legacy template
30
30
31 This class allows us to handle both:
31 This class allows us to handle both:
32 - "{files}" (legacy command-line-specific list hack) and
32 - "{files}" (legacy command-line-specific list hack) and
33 - "{files % '{file}\n'}" (hgweb-style with inlining and function support)
33 - "{files % '{file}\n'}" (hgweb-style with inlining and function support)
34 and to access raw values:
34 and to access raw values:
35 - "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
35 - "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
36 - "{get(extras, key)}"
36 - "{get(extras, key)}"
37 - "{files|json}"
37 - "{files|json}"
38 """
38 """
39
39
40 def __init__(self, gen, values, makemap, joinfmt, keytype=None):
40 def __init__(self, gen, values, makemap, joinfmt, keytype=None):
41 if gen is not None:
41 if gen is not None:
42 self.gen = gen # generator or function returning generator
42 self.gen = gen # generator or function returning generator
43 self._values = values
43 self._values = values
44 self._makemap = makemap
44 self._makemap = makemap
45 self.joinfmt = joinfmt
45 self.joinfmt = joinfmt
46 self.keytype = keytype # hint for 'x in y' where type(x) is unresolved
46 self.keytype = keytype # hint for 'x in y' where type(x) is unresolved
47 def gen(self):
47 def gen(self):
48 """Default generator to stringify this as {join(self, ' ')}"""
48 """Default generator to stringify this as {join(self, ' ')}"""
49 for i, x in enumerate(self._values):
49 for i, x in enumerate(self._values):
50 if i > 0:
50 if i > 0:
51 yield ' '
51 yield ' '
52 yield self.joinfmt(x)
52 yield self.joinfmt(x)
53 def itermaps(self):
53 def itermaps(self):
54 makemap = self._makemap
54 makemap = self._makemap
55 for x in self._values:
55 for x in self._values:
56 yield makemap(x)
56 yield makemap(x)
57 def __contains__(self, x):
57 def __contains__(self, x):
58 return x in self._values
58 return x in self._values
59 def __getitem__(self, key):
59 def __getitem__(self, key):
60 return self._values[key]
60 return self._values[key]
61 def __len__(self):
61 def __len__(self):
62 return len(self._values)
62 return len(self._values)
63 def __iter__(self):
63 def __iter__(self):
64 return iter(self._values)
64 return iter(self._values)
65 def __getattr__(self, name):
65 def __getattr__(self, name):
66 if name not in ('get', 'items', 'iteritems', 'iterkeys', 'itervalues',
66 if name not in ('get', 'items', 'iteritems', 'iterkeys', 'itervalues',
67 'keys', 'values'):
67 'keys', 'values'):
68 raise AttributeError(name)
68 raise AttributeError(name)
69 return getattr(self._values, name)
69 return getattr(self._values, name)
70
70
71 class _mappable(object):
71 class _mappable(object):
72 """Wrapper for non-list/dict object to support map operation
72 """Wrapper for non-list/dict object to support map operation
73
73
74 This class allows us to handle both:
74 This class allows us to handle both:
75 - "{manifest}"
75 - "{manifest}"
76 - "{manifest % '{rev}:{node}'}"
76 - "{manifest % '{rev}:{node}'}"
77 - "{manifest.rev}"
77 - "{manifest.rev}"
78
78
79 Unlike a _hybrid, this does not simulate the behavior of the underling
79 Unlike a _hybrid, this does not simulate the behavior of the underling
80 value. Use unwrapvalue() or unwraphybrid() to obtain the inner object.
80 value. Use unwrapvalue() or unwraphybrid() to obtain the inner object.
81 """
81 """
82
82
83 def __init__(self, gen, key, value, makemap):
83 def __init__(self, gen, key, value, makemap):
84 if gen is not None:
84 if gen is not None:
85 self.gen = gen # generator or function returning generator
85 self.gen = gen # generator or function returning generator
86 self._key = key
86 self._key = key
87 self._value = value # may be generator of strings
87 self._value = value # may be generator of strings
88 self._makemap = makemap
88 self._makemap = makemap
89
89
90 def gen(self):
90 def gen(self):
91 yield pycompat.bytestr(self._value)
91 yield pycompat.bytestr(self._value)
92
92
93 def tomap(self):
93 def tomap(self):
94 return self._makemap(self._key)
94 return self._makemap(self._key)
95
95
96 def itermaps(self):
96 def itermaps(self):
97 yield self.tomap()
97 yield self.tomap()
98
98
99 def hybriddict(data, key='key', value='value', fmt='%s=%s', gen=None):
99 def hybriddict(data, key='key', value='value', fmt='%s=%s', gen=None):
100 """Wrap data to support both dict-like and string-like operations"""
100 """Wrap data to support both dict-like and string-like operations"""
101 return _hybrid(gen, data, lambda k: {key: k, value: data[k]},
101 return _hybrid(gen, data, lambda k: {key: k, value: data[k]},
102 lambda k: fmt % (k, data[k]))
102 lambda k: fmt % (k, data[k]))
103
103
104 def hybridlist(data, name, fmt='%s', gen=None):
104 def hybridlist(data, name, fmt='%s', gen=None):
105 """Wrap data to support both list-like and string-like operations"""
105 """Wrap data to support both list-like and string-like operations"""
106 return _hybrid(gen, data, lambda x: {name: x}, lambda x: fmt % x)
106 return _hybrid(gen, data, lambda x: {name: x}, lambda x: fmt % x)
107
107
108 def unwraphybrid(thing):
108 def unwraphybrid(thing):
109 """Return an object which can be stringified possibly by using a legacy
109 """Return an object which can be stringified possibly by using a legacy
110 template"""
110 template"""
111 gen = getattr(thing, 'gen', None)
111 gen = getattr(thing, 'gen', None)
112 if gen is None:
112 if gen is None:
113 return thing
113 return thing
114 if callable(gen):
114 if callable(gen):
115 return gen()
115 return gen()
116 return gen
116 return gen
117
117
118 def unwrapvalue(thing):
118 def unwrapvalue(thing):
119 """Move the inner value object out of the wrapper"""
119 """Move the inner value object out of the wrapper"""
120 if not util.safehasattr(thing, '_value'):
120 if not util.safehasattr(thing, '_value'):
121 return thing
121 return thing
122 return thing._value
122 return thing._value
123
123
124 def wraphybridvalue(container, key, value):
124 def wraphybridvalue(container, key, value):
125 """Wrap an element of hybrid container to be mappable
125 """Wrap an element of hybrid container to be mappable
126
126
127 The key is passed to the makemap function of the given container, which
127 The key is passed to the makemap function of the given container, which
128 should be an item generated by iter(container).
128 should be an item generated by iter(container).
129 """
129 """
130 makemap = getattr(container, '_makemap', None)
130 makemap = getattr(container, '_makemap', None)
131 if makemap is None:
131 if makemap is None:
132 return value
132 return value
133 if util.safehasattr(value, '_makemap'):
133 if util.safehasattr(value, '_makemap'):
134 # a nested hybrid list/dict, which has its own way of map operation
134 # a nested hybrid list/dict, which has its own way of map operation
135 return value
135 return value
136 return _mappable(None, key, value, makemap)
136 return _mappable(None, key, value, makemap)
137
137
138 def showdict(name, data, mapping, plural=None, key='key', value='value',
138 def showdict(name, data, mapping, plural=None, key='key', value='value',
139 fmt='%s=%s', separator=' '):
139 fmt='%s=%s', separator=' '):
140 c = [{key: k, value: v} for k, v in data.iteritems()]
140 c = [{key: k, value: v} for k, v in data.iteritems()]
141 f = _showlist(name, c, mapping, plural, separator)
141 f = _showlist(name, c, mapping, plural, separator)
142 return hybriddict(data, key=key, value=value, fmt=fmt, gen=f)
142 return hybriddict(data, key=key, value=value, fmt=fmt, gen=f)
143
143
144 def showlist(name, values, mapping, plural=None, element=None, separator=' '):
144 def showlist(name, values, mapping, plural=None, element=None, separator=' '):
145 if not element:
145 if not element:
146 element = name
146 element = name
147 f = _showlist(name, values, mapping, plural, separator)
147 f = _showlist(name, values, mapping, plural, separator)
148 return hybridlist(values, name=element, gen=f)
148 return hybridlist(values, name=element, gen=f)
149
149
150 def _showlist(name, values, mapping, plural=None, separator=' '):
150 def _showlist(name, values, mapping, plural=None, separator=' '):
151 '''expand set of values.
151 '''expand set of values.
152 name is name of key in template map.
152 name is name of key in template map.
153 values is list of strings or dicts.
153 values is list of strings or dicts.
154 plural is plural of name, if not simply name + 's'.
154 plural is plural of name, if not simply name + 's'.
155 separator is used to join values as a string
155 separator is used to join values as a string
156
156
157 expansion works like this, given name 'foo'.
157 expansion works like this, given name 'foo'.
158
158
159 if values is empty, expand 'no_foos'.
159 if values is empty, expand 'no_foos'.
160
160
161 if 'foo' not in template map, return values as a string,
161 if 'foo' not in template map, return values as a string,
162 joined by 'separator'.
162 joined by 'separator'.
163
163
164 expand 'start_foos'.
164 expand 'start_foos'.
165
165
166 for each value, expand 'foo'. if 'last_foo' in template
166 for each value, expand 'foo'. if 'last_foo' in template
167 map, expand it instead of 'foo' for last key.
167 map, expand it instead of 'foo' for last key.
168
168
169 expand 'end_foos'.
169 expand 'end_foos'.
170 '''
170 '''
171 templ = mapping['templ']
171 templ = mapping['templ']
172 strmapping = pycompat.strkwargs(mapping)
172 strmapping = pycompat.strkwargs(mapping)
173 if not plural:
173 if not plural:
174 plural = name + 's'
174 plural = name + 's'
175 if not values:
175 if not values:
176 noname = 'no_' + plural
176 noname = 'no_' + plural
177 if noname in templ:
177 if noname in templ:
178 yield templ(noname, **strmapping)
178 yield templ(noname, **strmapping)
179 return
179 return
180 if name not in templ:
180 if name not in templ:
181 if isinstance(values[0], bytes):
181 if isinstance(values[0], bytes):
182 yield separator.join(values)
182 yield separator.join(values)
183 else:
183 else:
184 for v in values:
184 for v in values:
185 yield dict(v, **strmapping)
185 yield dict(v, **strmapping)
186 return
186 return
187 startname = 'start_' + plural
187 startname = 'start_' + plural
188 if startname in templ:
188 if startname in templ:
189 yield templ(startname, **strmapping)
189 yield templ(startname, **strmapping)
190 vmapping = mapping.copy()
190 vmapping = mapping.copy()
191 def one(v, tag=name):
191 def one(v, tag=name):
192 try:
192 try:
193 vmapping.update(v)
193 vmapping.update(v)
194 except (AttributeError, ValueError):
194 except (AttributeError, ValueError):
195 try:
195 try:
196 for a, b in v:
196 for a, b in v:
197 vmapping[a] = b
197 vmapping[a] = b
198 except ValueError:
198 except ValueError:
199 vmapping[name] = v
199 vmapping[name] = v
200 return templ(tag, **pycompat.strkwargs(vmapping))
200 return templ(tag, **pycompat.strkwargs(vmapping))
201 lastname = 'last_' + name
201 lastname = 'last_' + name
202 if lastname in templ:
202 if lastname in templ:
203 last = values.pop()
203 last = values.pop()
204 else:
204 else:
205 last = None
205 last = None
206 for v in values:
206 for v in values:
207 yield one(v)
207 yield one(v)
208 if last is not None:
208 if last is not None:
209 yield one(last, tag=lastname)
209 yield one(last, tag=lastname)
210 endname = 'end_' + plural
210 endname = 'end_' + plural
211 if endname in templ:
211 if endname in templ:
212 yield templ(endname, **strmapping)
212 yield templ(endname, **strmapping)
213
213
214 def getfiles(repo, ctx, revcache):
214 def getfiles(repo, ctx, revcache):
215 if 'files' not in revcache:
215 if 'files' not in revcache:
216 revcache['files'] = repo.status(ctx.p1(), ctx)[:3]
216 revcache['files'] = repo.status(ctx.p1(), ctx)[:3]
217 return revcache['files']
217 return revcache['files']
218
218
219 def getlatesttags(repo, ctx, cache, pattern=None):
219 def getlatesttags(repo, ctx, cache, pattern=None):
220 '''return date, distance and name for the latest tag of rev'''
220 '''return date, distance and name for the latest tag of rev'''
221
221
222 cachename = 'latesttags'
222 cachename = 'latesttags'
223 if pattern is not None:
223 if pattern is not None:
224 cachename += '-' + pattern
224 cachename += '-' + pattern
225 match = util.stringmatcher(pattern)[2]
225 match = util.stringmatcher(pattern)[2]
226 else:
226 else:
227 match = util.always
227 match = util.always
228
228
229 if cachename not in cache:
229 if cachename not in cache:
230 # Cache mapping from rev to a tuple with tag date, tag
230 # Cache mapping from rev to a tuple with tag date, tag
231 # distance and tag name
231 # distance and tag name
232 cache[cachename] = {-1: (0, 0, ['null'])}
232 cache[cachename] = {-1: (0, 0, ['null'])}
233 latesttags = cache[cachename]
233 latesttags = cache[cachename]
234
234
235 rev = ctx.rev()
235 rev = ctx.rev()
236 todo = [rev]
236 todo = [rev]
237 while todo:
237 while todo:
238 rev = todo.pop()
238 rev = todo.pop()
239 if rev in latesttags:
239 if rev in latesttags:
240 continue
240 continue
241 ctx = repo[rev]
241 ctx = repo[rev]
242 tags = [t for t in ctx.tags()
242 tags = [t for t in ctx.tags()
243 if (repo.tagtype(t) and repo.tagtype(t) != 'local'
243 if (repo.tagtype(t) and repo.tagtype(t) != 'local'
244 and match(t))]
244 and match(t))]
245 if tags:
245 if tags:
246 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
246 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
247 continue
247 continue
248 try:
248 try:
249 ptags = [latesttags[p.rev()] for p in ctx.parents()]
249 ptags = [latesttags[p.rev()] for p in ctx.parents()]
250 if len(ptags) > 1:
250 if len(ptags) > 1:
251 if ptags[0][2] == ptags[1][2]:
251 if ptags[0][2] == ptags[1][2]:
252 # The tuples are laid out so the right one can be found by
252 # The tuples are laid out so the right one can be found by
253 # comparison in this case.
253 # comparison in this case.
254 pdate, pdist, ptag = max(ptags)
254 pdate, pdist, ptag = max(ptags)
255 else:
255 else:
256 def key(x):
256 def key(x):
257 changessincetag = len(repo.revs('only(%d, %s)',
257 changessincetag = len(repo.revs('only(%d, %s)',
258 ctx.rev(), x[2][0]))
258 ctx.rev(), x[2][0]))
259 # Smallest number of changes since tag wins. Date is
259 # Smallest number of changes since tag wins. Date is
260 # used as tiebreaker.
260 # used as tiebreaker.
261 return [-changessincetag, x[0]]
261 return [-changessincetag, x[0]]
262 pdate, pdist, ptag = max(ptags, key=key)
262 pdate, pdist, ptag = max(ptags, key=key)
263 else:
263 else:
264 pdate, pdist, ptag = ptags[0]
264 pdate, pdist, ptag = ptags[0]
265 except KeyError:
265 except KeyError:
266 # Cache miss - recurse
266 # Cache miss - recurse
267 todo.append(rev)
267 todo.append(rev)
268 todo.extend(p.rev() for p in ctx.parents())
268 todo.extend(p.rev() for p in ctx.parents())
269 continue
269 continue
270 latesttags[rev] = pdate, pdist + 1, ptag
270 latesttags[rev] = pdate, pdist + 1, ptag
271 return latesttags[rev]
271 return latesttags[rev]
272
272
273 def getrenamedfn(repo, endrev=None):
273 def getrenamedfn(repo, endrev=None):
274 rcache = {}
274 rcache = {}
275 if endrev is None:
275 if endrev is None:
276 endrev = len(repo)
276 endrev = len(repo)
277
277
278 def getrenamed(fn, rev):
278 def getrenamed(fn, rev):
279 '''looks up all renames for a file (up to endrev) the first
279 '''looks up all renames for a file (up to endrev) the first
280 time the file is given. It indexes on the changerev and only
280 time the file is given. It indexes on the changerev and only
281 parses the manifest if linkrev != changerev.
281 parses the manifest if linkrev != changerev.
282 Returns rename info for fn at changerev rev.'''
282 Returns rename info for fn at changerev rev.'''
283 if fn not in rcache:
283 if fn not in rcache:
284 rcache[fn] = {}
284 rcache[fn] = {}
285 fl = repo.file(fn)
285 fl = repo.file(fn)
286 for i in fl:
286 for i in fl:
287 lr = fl.linkrev(i)
287 lr = fl.linkrev(i)
288 renamed = fl.renamed(fl.node(i))
288 renamed = fl.renamed(fl.node(i))
289 rcache[fn][lr] = renamed
289 rcache[fn][lr] = renamed
290 if lr >= endrev:
290 if lr >= endrev:
291 break
291 break
292 if rev in rcache[fn]:
292 if rev in rcache[fn]:
293 return rcache[fn][rev]
293 return rcache[fn][rev]
294
294
295 # If linkrev != rev (i.e. rev not found in rcache) fallback to
295 # If linkrev != rev (i.e. rev not found in rcache) fallback to
296 # filectx logic.
296 # filectx logic.
297 try:
297 try:
298 return repo[rev][fn].renamed()
298 return repo[rev][fn].renamed()
299 except error.LookupError:
299 except error.LookupError:
300 return None
300 return None
301
301
302 return getrenamed
302 return getrenamed
303
303
304 # default templates internally used for rendering of lists
304 # default templates internally used for rendering of lists
305 defaulttempl = {
305 defaulttempl = {
306 'parent': '{rev}:{node|formatnode} ',
306 'parent': '{rev}:{node|formatnode} ',
307 'manifest': '{rev}:{node|formatnode}',
307 'manifest': '{rev}:{node|formatnode}',
308 'file_copy': '{name} ({source})',
308 'file_copy': '{name} ({source})',
309 'envvar': '{key}={value}',
309 'envvar': '{key}={value}',
310 'extra': '{key}={value|stringescape}'
310 'extra': '{key}={value|stringescape}'
311 }
311 }
312 # filecopy is preserved for compatibility reasons
312 # filecopy is preserved for compatibility reasons
313 defaulttempl['filecopy'] = defaulttempl['file_copy']
313 defaulttempl['filecopy'] = defaulttempl['file_copy']
314
314
315 # keywords are callables like:
315 # keywords are callables like:
316 # fn(repo, ctx, templ, cache, revcache, **args)
316 # fn(repo, ctx, templ, cache, revcache, **args)
317 # with:
317 # with:
318 # repo - current repository instance
318 # repo - current repository instance
319 # ctx - the changectx being displayed
319 # ctx - the changectx being displayed
320 # templ - the templater instance
320 # templ - the templater instance
321 # cache - a cache dictionary for the whole templater run
321 # cache - a cache dictionary for the whole templater run
322 # revcache - a cache dictionary for the current revision
322 # revcache - a cache dictionary for the current revision
323 keywords = {}
323 keywords = {}
324
324
325 templatekeyword = registrar.templatekeyword(keywords)
325 templatekeyword = registrar.templatekeyword(keywords)
326
326
327 @templatekeyword('author')
327 @templatekeyword('author')
328 def showauthor(repo, ctx, templ, **args):
328 def showauthor(repo, ctx, templ, **args):
329 """String. The unmodified author of the changeset."""
329 """String. The unmodified author of the changeset."""
330 return ctx.user()
330 return ctx.user()
331
331
332 @templatekeyword('bisect')
332 @templatekeyword('bisect')
333 def showbisect(repo, ctx, templ, **args):
333 def showbisect(repo, ctx, templ, **args):
334 """String. The changeset bisection status."""
334 """String. The changeset bisection status."""
335 return hbisect.label(repo, ctx.node())
335 return hbisect.label(repo, ctx.node())
336
336
337 @templatekeyword('branch')
337 @templatekeyword('branch')
338 def showbranch(**args):
338 def showbranch(**args):
339 """String. The name of the branch on which the changeset was
339 """String. The name of the branch on which the changeset was
340 committed.
340 committed.
341 """
341 """
342 return args[r'ctx'].branch()
342 return args[r'ctx'].branch()
343
343
344 @templatekeyword('branches')
344 @templatekeyword('branches')
345 def showbranches(**args):
345 def showbranches(**args):
346 """List of strings. The name of the branch on which the
346 """List of strings. The name of the branch on which the
347 changeset was committed. Will be empty if the branch name was
347 changeset was committed. Will be empty if the branch name was
348 default. (DEPRECATED)
348 default. (DEPRECATED)
349 """
349 """
350 args = pycompat.byteskwargs(args)
350 args = pycompat.byteskwargs(args)
351 branch = args['ctx'].branch()
351 branch = args['ctx'].branch()
352 if branch != 'default':
352 if branch != 'default':
353 return showlist('branch', [branch], args, plural='branches')
353 return showlist('branch', [branch], args, plural='branches')
354 return showlist('branch', [], args, plural='branches')
354 return showlist('branch', [], args, plural='branches')
355
355
356 @templatekeyword('bookmarks')
356 @templatekeyword('bookmarks')
357 def showbookmarks(**args):
357 def showbookmarks(**args):
358 """List of strings. Any bookmarks associated with the
358 """List of strings. Any bookmarks associated with the
359 changeset. Also sets 'active', the name of the active bookmark.
359 changeset. Also sets 'active', the name of the active bookmark.
360 """
360 """
361 args = pycompat.byteskwargs(args)
361 args = pycompat.byteskwargs(args)
362 repo = args['ctx']._repo
362 repo = args['ctx']._repo
363 bookmarks = args['ctx'].bookmarks()
363 bookmarks = args['ctx'].bookmarks()
364 active = repo._activebookmark
364 active = repo._activebookmark
365 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active}
365 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active}
366 f = _showlist('bookmark', bookmarks, args)
366 f = _showlist('bookmark', bookmarks, args)
367 return _hybrid(f, bookmarks, makemap, pycompat.identity)
367 return _hybrid(f, bookmarks, makemap, pycompat.identity)
368
368
369 @templatekeyword('children')
369 @templatekeyword('children')
370 def showchildren(**args):
370 def showchildren(**args):
371 """List of strings. The children of the changeset."""
371 """List of strings. The children of the changeset."""
372 args = pycompat.byteskwargs(args)
372 args = pycompat.byteskwargs(args)
373 ctx = args['ctx']
373 ctx = args['ctx']
374 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
374 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
375 return showlist('children', childrevs, args, element='child')
375 return showlist('children', childrevs, args, element='child')
376
376
377 # Deprecated, but kept alive for help generation a purpose.
377 # Deprecated, but kept alive for help generation a purpose.
378 @templatekeyword('currentbookmark')
378 @templatekeyword('currentbookmark')
379 def showcurrentbookmark(**args):
379 def showcurrentbookmark(**args):
380 """String. The active bookmark, if it is associated with the changeset.
380 """String. The active bookmark, if it is associated with the changeset.
381 (DEPRECATED)"""
381 (DEPRECATED)"""
382 return showactivebookmark(**args)
382 return showactivebookmark(**args)
383
383
384 @templatekeyword('activebookmark')
384 @templatekeyword('activebookmark')
385 def showactivebookmark(**args):
385 def showactivebookmark(**args):
386 """String. The active bookmark, if it is associated with the changeset."""
386 """String. The active bookmark, if it is associated with the changeset."""
387 active = args[r'repo']._activebookmark
387 active = args[r'repo']._activebookmark
388 if active and active in args[r'ctx'].bookmarks():
388 if active and active in args[r'ctx'].bookmarks():
389 return active
389 return active
390 return ''
390 return ''
391
391
392 @templatekeyword('date')
392 @templatekeyword('date')
393 def showdate(repo, ctx, templ, **args):
393 def showdate(repo, ctx, templ, **args):
394 """Date information. The date when the changeset was committed."""
394 """Date information. The date when the changeset was committed."""
395 return ctx.date()
395 return ctx.date()
396
396
397 @templatekeyword('desc')
397 @templatekeyword('desc')
398 def showdescription(repo, ctx, templ, **args):
398 def showdescription(repo, ctx, templ, **args):
399 """String. The text of the changeset description."""
399 """String. The text of the changeset description."""
400 s = ctx.description()
400 s = ctx.description()
401 if isinstance(s, encoding.localstr):
401 if isinstance(s, encoding.localstr):
402 # try hard to preserve utf-8 bytes
402 # try hard to preserve utf-8 bytes
403 return encoding.tolocal(encoding.fromlocal(s).strip())
403 return encoding.tolocal(encoding.fromlocal(s).strip())
404 else:
404 else:
405 return s.strip()
405 return s.strip()
406
406
407 @templatekeyword('diffstat')
407 @templatekeyword('diffstat')
408 def showdiffstat(repo, ctx, templ, **args):
408 def showdiffstat(repo, ctx, templ, **args):
409 """String. Statistics of changes with the following format:
409 """String. Statistics of changes with the following format:
410 "modified files: +added/-removed lines"
410 "modified files: +added/-removed lines"
411 """
411 """
412 stats = patch.diffstatdata(util.iterlines(ctx.diff(noprefix=False)))
412 stats = patch.diffstatdata(util.iterlines(ctx.diff(noprefix=False)))
413 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
413 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
414 return '%s: +%s/-%s' % (len(stats), adds, removes)
414 return '%s: +%s/-%s' % (len(stats), adds, removes)
415
415
416 @templatekeyword('envvars')
416 @templatekeyword('envvars')
417 def showenvvars(repo, **args):
417 def showenvvars(repo, **args):
418 """A dictionary of environment variables. (EXPERIMENTAL)"""
418 """A dictionary of environment variables. (EXPERIMENTAL)"""
419 args = pycompat.byteskwargs(args)
419 args = pycompat.byteskwargs(args)
420 env = repo.ui.exportableenviron()
420 env = repo.ui.exportableenviron()
421 env = util.sortdict((k, env[k]) for k in sorted(env))
421 env = util.sortdict((k, env[k]) for k in sorted(env))
422 return showdict('envvar', env, args, plural='envvars')
422 return showdict('envvar', env, args, plural='envvars')
423
423
424 @templatekeyword('extras')
424 @templatekeyword('extras')
425 def showextras(**args):
425 def showextras(**args):
426 """List of dicts with key, value entries of the 'extras'
426 """List of dicts with key, value entries of the 'extras'
427 field of this changeset."""
427 field of this changeset."""
428 args = pycompat.byteskwargs(args)
428 args = pycompat.byteskwargs(args)
429 extras = args['ctx'].extra()
429 extras = args['ctx'].extra()
430 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
430 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
431 makemap = lambda k: {'key': k, 'value': extras[k]}
431 makemap = lambda k: {'key': k, 'value': extras[k]}
432 c = [makemap(k) for k in extras]
432 c = [makemap(k) for k in extras]
433 f = _showlist('extra', c, args, plural='extras')
433 f = _showlist('extra', c, args, plural='extras')
434 return _hybrid(f, extras, makemap,
434 return _hybrid(f, extras, makemap,
435 lambda k: '%s=%s' % (k, util.escapestr(extras[k])))
435 lambda k: '%s=%s' % (k, util.escapestr(extras[k])))
436
436
437 @templatekeyword('file_adds')
437 @templatekeyword('file_adds')
438 def showfileadds(**args):
438 def showfileadds(**args):
439 """List of strings. Files added by this changeset."""
439 """List of strings. Files added by this changeset."""
440 args = pycompat.byteskwargs(args)
440 args = pycompat.byteskwargs(args)
441 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
441 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
442 return showlist('file_add', getfiles(repo, ctx, revcache)[1], args,
442 return showlist('file_add', getfiles(repo, ctx, revcache)[1], args,
443 element='file')
443 element='file')
444
444
445 @templatekeyword('file_copies')
445 @templatekeyword('file_copies')
446 def showfilecopies(**args):
446 def showfilecopies(**args):
447 """List of strings. Files copied in this changeset with
447 """List of strings. Files copied in this changeset with
448 their sources.
448 their sources.
449 """
449 """
450 args = pycompat.byteskwargs(args)
450 args = pycompat.byteskwargs(args)
451 cache, ctx = args['cache'], args['ctx']
451 cache, ctx = args['cache'], args['ctx']
452 copies = args['revcache'].get('copies')
452 copies = args['revcache'].get('copies')
453 if copies is None:
453 if copies is None:
454 if 'getrenamed' not in cache:
454 if 'getrenamed' not in cache:
455 cache['getrenamed'] = getrenamedfn(args['repo'])
455 cache['getrenamed'] = getrenamedfn(args['repo'])
456 copies = []
456 copies = []
457 getrenamed = cache['getrenamed']
457 getrenamed = cache['getrenamed']
458 for fn in ctx.files():
458 for fn in ctx.files():
459 rename = getrenamed(fn, ctx.rev())
459 rename = getrenamed(fn, ctx.rev())
460 if rename:
460 if rename:
461 copies.append((fn, rename[0]))
461 copies.append((fn, rename[0]))
462
462
463 copies = util.sortdict(copies)
463 copies = util.sortdict(copies)
464 return showdict('file_copy', copies, args, plural='file_copies',
464 return showdict('file_copy', copies, args, plural='file_copies',
465 key='name', value='source', fmt='%s (%s)')
465 key='name', value='source', fmt='%s (%s)')
466
466
467 # showfilecopiesswitch() displays file copies only if copy records are
467 # showfilecopiesswitch() displays file copies only if copy records are
468 # provided before calling the templater, usually with a --copies
468 # provided before calling the templater, usually with a --copies
469 # command line switch.
469 # command line switch.
470 @templatekeyword('file_copies_switch')
470 @templatekeyword('file_copies_switch')
471 def showfilecopiesswitch(**args):
471 def showfilecopiesswitch(**args):
472 """List of strings. Like "file_copies" but displayed
472 """List of strings. Like "file_copies" but displayed
473 only if the --copied switch is set.
473 only if the --copied switch is set.
474 """
474 """
475 args = pycompat.byteskwargs(args)
475 args = pycompat.byteskwargs(args)
476 copies = args['revcache'].get('copies') or []
476 copies = args['revcache'].get('copies') or []
477 copies = util.sortdict(copies)
477 copies = util.sortdict(copies)
478 return showdict('file_copy', copies, args, plural='file_copies',
478 return showdict('file_copy', copies, args, plural='file_copies',
479 key='name', value='source', fmt='%s (%s)')
479 key='name', value='source', fmt='%s (%s)')
480
480
481 @templatekeyword('file_dels')
481 @templatekeyword('file_dels')
482 def showfiledels(**args):
482 def showfiledels(**args):
483 """List of strings. Files removed by this changeset."""
483 """List of strings. Files removed by this changeset."""
484 args = pycompat.byteskwargs(args)
484 args = pycompat.byteskwargs(args)
485 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
485 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
486 return showlist('file_del', getfiles(repo, ctx, revcache)[2], args,
486 return showlist('file_del', getfiles(repo, ctx, revcache)[2], args,
487 element='file')
487 element='file')
488
488
489 @templatekeyword('file_mods')
489 @templatekeyword('file_mods')
490 def showfilemods(**args):
490 def showfilemods(**args):
491 """List of strings. Files modified by this changeset."""
491 """List of strings. Files modified by this changeset."""
492 args = pycompat.byteskwargs(args)
492 args = pycompat.byteskwargs(args)
493 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
493 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
494 return showlist('file_mod', getfiles(repo, ctx, revcache)[0], args,
494 return showlist('file_mod', getfiles(repo, ctx, revcache)[0], args,
495 element='file')
495 element='file')
496
496
497 @templatekeyword('files')
497 @templatekeyword('files')
498 def showfiles(**args):
498 def showfiles(**args):
499 """List of strings. All files modified, added, or removed by this
499 """List of strings. All files modified, added, or removed by this
500 changeset.
500 changeset.
501 """
501 """
502 args = pycompat.byteskwargs(args)
502 args = pycompat.byteskwargs(args)
503 return showlist('file', args['ctx'].files(), args)
503 return showlist('file', args['ctx'].files(), args)
504
504
505 @templatekeyword('graphnode')
505 @templatekeyword('graphnode')
506 def showgraphnode(repo, ctx, **args):
506 def showgraphnode(repo, ctx, **args):
507 """String. The character representing the changeset node in an ASCII
507 """String. The character representing the changeset node in an ASCII
508 revision graph."""
508 revision graph."""
509 wpnodes = repo.dirstate.parents()
509 wpnodes = repo.dirstate.parents()
510 if wpnodes[1] == nullid:
510 if wpnodes[1] == nullid:
511 wpnodes = wpnodes[:1]
511 wpnodes = wpnodes[:1]
512 if ctx.node() in wpnodes:
512 if ctx.node() in wpnodes:
513 return '@'
513 return '@'
514 elif ctx.obsolete():
514 elif ctx.obsolete():
515 return 'x'
515 return 'x'
516 elif ctx.closesbranch():
516 elif ctx.closesbranch():
517 return '_'
517 return '_'
518 else:
518 else:
519 return 'o'
519 return 'o'
520
520
521 @templatekeyword('graphwidth')
521 @templatekeyword('graphwidth')
522 def showgraphwidth(repo, ctx, templ, **args):
522 def showgraphwidth(repo, ctx, templ, **args):
523 """Integer. The width of the graph drawn by 'log --graph' or zero."""
523 """Integer. The width of the graph drawn by 'log --graph' or zero."""
524 # The value args['graphwidth'] will be this function, so we use an internal
524 # The value args['graphwidth'] will be this function, so we use an internal
525 # name to pass the value through props into this function.
525 # name to pass the value through props into this function.
526 return args.get('_graphwidth', 0)
526 return args.get('_graphwidth', 0)
527
527
528 @templatekeyword('index')
528 @templatekeyword('index')
529 def showindex(**args):
529 def showindex(**args):
530 """Integer. The current iteration of the loop. (0 indexed)"""
530 """Integer. The current iteration of the loop. (0 indexed)"""
531 # just hosts documentation; should be overridden by template mapping
531 # just hosts documentation; should be overridden by template mapping
532 raise error.Abort(_("can't use index in this context"))
532 raise error.Abort(_("can't use index in this context"))
533
533
534 @templatekeyword('latesttag')
534 @templatekeyword('latesttag')
535 def showlatesttag(**args):
535 def showlatesttag(**args):
536 """List of strings. The global tags on the most recent globally
536 """List of strings. The global tags on the most recent globally
537 tagged ancestor of this changeset. If no such tags exist, the list
537 tagged ancestor of this changeset. If no such tags exist, the list
538 consists of the single string "null".
538 consists of the single string "null".
539 """
539 """
540 return showlatesttags(None, **args)
540 return showlatesttags(None, **args)
541
541
542 def showlatesttags(pattern, **args):
542 def showlatesttags(pattern, **args):
543 """helper method for the latesttag keyword and function"""
543 """helper method for the latesttag keyword and function"""
544 args = pycompat.byteskwargs(args)
544 args = pycompat.byteskwargs(args)
545 repo, ctx = args['repo'], args['ctx']
545 repo, ctx = args['repo'], args['ctx']
546 cache = args['cache']
546 cache = args['cache']
547 latesttags = getlatesttags(repo, ctx, cache, pattern)
547 latesttags = getlatesttags(repo, ctx, cache, pattern)
548
548
549 # latesttag[0] is an implementation detail for sorting csets on different
549 # latesttag[0] is an implementation detail for sorting csets on different
550 # branches in a stable manner- it is the date the tagged cset was created,
550 # branches in a stable manner- it is the date the tagged cset was created,
551 # not the date the tag was created. Therefore it isn't made visible here.
551 # not the date the tag was created. Therefore it isn't made visible here.
552 makemap = lambda v: {
552 makemap = lambda v: {
553 'changes': _showchangessincetag,
553 'changes': _showchangessincetag,
554 'distance': latesttags[1],
554 'distance': latesttags[1],
555 'latesttag': v, # BC with {latesttag % '{latesttag}'}
555 'latesttag': v, # BC with {latesttag % '{latesttag}'}
556 'tag': v
556 'tag': v
557 }
557 }
558
558
559 tags = latesttags[2]
559 tags = latesttags[2]
560 f = _showlist('latesttag', tags, args, separator=':')
560 f = _showlist('latesttag', tags, args, separator=':')
561 return _hybrid(f, tags, makemap, pycompat.identity)
561 return _hybrid(f, tags, makemap, pycompat.identity)
562
562
563 @templatekeyword('latesttagdistance')
563 @templatekeyword('latesttagdistance')
564 def showlatesttagdistance(repo, ctx, templ, cache, **args):
564 def showlatesttagdistance(repo, ctx, templ, cache, **args):
565 """Integer. Longest path to the latest tag."""
565 """Integer. Longest path to the latest tag."""
566 return getlatesttags(repo, ctx, cache)[1]
566 return getlatesttags(repo, ctx, cache)[1]
567
567
568 @templatekeyword('changessincelatesttag')
568 @templatekeyword('changessincelatesttag')
569 def showchangessincelatesttag(repo, ctx, templ, cache, **args):
569 def showchangessincelatesttag(repo, ctx, templ, cache, **args):
570 """Integer. All ancestors not in the latest tag."""
570 """Integer. All ancestors not in the latest tag."""
571 latesttag = getlatesttags(repo, ctx, cache)[2][0]
571 latesttag = getlatesttags(repo, ctx, cache)[2][0]
572
572
573 return _showchangessincetag(repo, ctx, tag=latesttag, **args)
573 return _showchangessincetag(repo, ctx, tag=latesttag, **args)
574
574
575 def _showchangessincetag(repo, ctx, **args):
575 def _showchangessincetag(repo, ctx, **args):
576 offset = 0
576 offset = 0
577 revs = [ctx.rev()]
577 revs = [ctx.rev()]
578 tag = args[r'tag']
578 tag = args[r'tag']
579
579
580 # The only() revset doesn't currently support wdir()
580 # The only() revset doesn't currently support wdir()
581 if ctx.rev() is None:
581 if ctx.rev() is None:
582 offset = 1
582 offset = 1
583 revs = [p.rev() for p in ctx.parents()]
583 revs = [p.rev() for p in ctx.parents()]
584
584
585 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset
585 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset
586
586
587 @templatekeyword('manifest')
587 @templatekeyword('manifest')
588 def showmanifest(**args):
588 def showmanifest(**args):
589 repo, ctx, templ = args[r'repo'], args[r'ctx'], args[r'templ']
589 repo, ctx, templ = args[r'repo'], args[r'ctx'], args[r'templ']
590 mnode = ctx.manifestnode()
590 mnode = ctx.manifestnode()
591 if mnode is None:
591 if mnode is None:
592 # just avoid crash, we might want to use the 'ff...' hash in future
592 # just avoid crash, we might want to use the 'ff...' hash in future
593 return
593 return
594 mrev = repo.manifestlog._revlog.rev(mnode)
594 mrev = repo.manifestlog._revlog.rev(mnode)
595 mhex = hex(mnode)
595 mhex = hex(mnode)
596 args = args.copy()
596 args = args.copy()
597 args.update({r'rev': mrev, r'node': mhex})
597 args.update({r'rev': mrev, r'node': mhex})
598 f = templ('manifest', **args)
598 f = templ('manifest', **args)
599 # TODO: perhaps 'ctx' should be dropped from mapping because manifest
599 # TODO: perhaps 'ctx' should be dropped from mapping because manifest
600 # rev and node are completely different from changeset's.
600 # rev and node are completely different from changeset's.
601 return _mappable(f, None, f, lambda x: {'rev': mrev, 'node': mhex})
601 return _mappable(f, None, f, lambda x: {'rev': mrev, 'node': mhex})
602
602
603 @templatekeyword('obsfate')
604 def showobsfate(**args):
605 # this function returns a list containing pre-formatted obsfate strings.
606 #
607 # This function will be replaced by templates fragments when we will have
608 # the verbosity templatekw available.
609 succsandmarkers = showsuccsandmarkers(**args)
610
611 ui = args['ui']
612
613 values = []
614
615 for x in succsandmarkers:
616 values.append(obsutil.obsfateprinter(x['successors'], x['markers'], ui))
617
618 return showlist("fate", values, args)
619
603 def shownames(namespace, **args):
620 def shownames(namespace, **args):
604 """helper method to generate a template keyword for a namespace"""
621 """helper method to generate a template keyword for a namespace"""
605 args = pycompat.byteskwargs(args)
622 args = pycompat.byteskwargs(args)
606 ctx = args['ctx']
623 ctx = args['ctx']
607 repo = ctx.repo()
624 repo = ctx.repo()
608 ns = repo.names[namespace]
625 ns = repo.names[namespace]
609 names = ns.names(repo, ctx.node())
626 names = ns.names(repo, ctx.node())
610 return showlist(ns.templatename, names, args, plural=namespace)
627 return showlist(ns.templatename, names, args, plural=namespace)
611
628
612 @templatekeyword('namespaces')
629 @templatekeyword('namespaces')
613 def shownamespaces(**args):
630 def shownamespaces(**args):
614 """Dict of lists. Names attached to this changeset per
631 """Dict of lists. Names attached to this changeset per
615 namespace."""
632 namespace."""
616 args = pycompat.byteskwargs(args)
633 args = pycompat.byteskwargs(args)
617 ctx = args['ctx']
634 ctx = args['ctx']
618 repo = ctx.repo()
635 repo = ctx.repo()
619
636
620 namespaces = util.sortdict()
637 namespaces = util.sortdict()
621 def makensmapfn(ns):
638 def makensmapfn(ns):
622 # 'name' for iterating over namespaces, templatename for local reference
639 # 'name' for iterating over namespaces, templatename for local reference
623 return lambda v: {'name': v, ns.templatename: v}
640 return lambda v: {'name': v, ns.templatename: v}
624
641
625 for k, ns in repo.names.iteritems():
642 for k, ns in repo.names.iteritems():
626 names = ns.names(repo, ctx.node())
643 names = ns.names(repo, ctx.node())
627 f = _showlist('name', names, args)
644 f = _showlist('name', names, args)
628 namespaces[k] = _hybrid(f, names, makensmapfn(ns), pycompat.identity)
645 namespaces[k] = _hybrid(f, names, makensmapfn(ns), pycompat.identity)
629
646
630 f = _showlist('namespace', list(namespaces), args)
647 f = _showlist('namespace', list(namespaces), args)
631
648
632 def makemap(ns):
649 def makemap(ns):
633 return {
650 return {
634 'namespace': ns,
651 'namespace': ns,
635 'names': namespaces[ns],
652 'names': namespaces[ns],
636 'builtin': repo.names[ns].builtin,
653 'builtin': repo.names[ns].builtin,
637 'colorname': repo.names[ns].colorname,
654 'colorname': repo.names[ns].colorname,
638 }
655 }
639
656
640 return _hybrid(f, namespaces, makemap, pycompat.identity)
657 return _hybrid(f, namespaces, makemap, pycompat.identity)
641
658
642 @templatekeyword('node')
659 @templatekeyword('node')
643 def shownode(repo, ctx, templ, **args):
660 def shownode(repo, ctx, templ, **args):
644 """String. The changeset identification hash, as a 40 hexadecimal
661 """String. The changeset identification hash, as a 40 hexadecimal
645 digit string.
662 digit string.
646 """
663 """
647 return ctx.hex()
664 return ctx.hex()
648
665
649 @templatekeyword('obsolete')
666 @templatekeyword('obsolete')
650 def showobsolete(repo, ctx, templ, **args):
667 def showobsolete(repo, ctx, templ, **args):
651 """String. Whether the changeset is obsolete. (EXPERIMENTAL)"""
668 """String. Whether the changeset is obsolete. (EXPERIMENTAL)"""
652 if ctx.obsolete():
669 if ctx.obsolete():
653 return 'obsolete'
670 return 'obsolete'
654 return ''
671 return ''
655
672
656 @templatekeyword('peerurls')
673 @templatekeyword('peerurls')
657 def showpeerurls(repo, **args):
674 def showpeerurls(repo, **args):
658 """A dictionary of repository locations defined in the [paths] section
675 """A dictionary of repository locations defined in the [paths] section
659 of your configuration file."""
676 of your configuration file."""
660 # see commands.paths() for naming of dictionary keys
677 # see commands.paths() for naming of dictionary keys
661 paths = repo.ui.paths
678 paths = repo.ui.paths
662 urls = util.sortdict((k, p.rawloc) for k, p in sorted(paths.iteritems()))
679 urls = util.sortdict((k, p.rawloc) for k, p in sorted(paths.iteritems()))
663 def makemap(k):
680 def makemap(k):
664 p = paths[k]
681 p = paths[k]
665 d = {'name': k, 'url': p.rawloc}
682 d = {'name': k, 'url': p.rawloc}
666 d.update((o, v) for o, v in sorted(p.suboptions.iteritems()))
683 d.update((o, v) for o, v in sorted(p.suboptions.iteritems()))
667 return d
684 return d
668 return _hybrid(None, urls, makemap, lambda k: '%s=%s' % (k, urls[k]))
685 return _hybrid(None, urls, makemap, lambda k: '%s=%s' % (k, urls[k]))
669
686
670 @templatekeyword("predecessors")
687 @templatekeyword("predecessors")
671 def showpredecessors(repo, ctx, **args):
688 def showpredecessors(repo, ctx, **args):
672 """Returns the list if the closest visible successors. (EXPERIMENTAL)"""
689 """Returns the list if the closest visible successors. (EXPERIMENTAL)"""
673 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
690 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
674 predecessors = map(hex, predecessors)
691 predecessors = map(hex, predecessors)
675
692
676 return _hybrid(None, predecessors,
693 return _hybrid(None, predecessors,
677 lambda x: {'ctx': repo[x], 'revcache': {}},
694 lambda x: {'ctx': repo[x], 'revcache': {}},
678 lambda x: scmutil.formatchangeid(repo[x]))
695 lambda x: scmutil.formatchangeid(repo[x]))
679
696
680 @templatekeyword("successorssets")
697 @templatekeyword("successorssets")
681 def showsuccessorssets(repo, ctx, **args):
698 def showsuccessorssets(repo, ctx, **args):
682 """Returns a string of sets of successors for a changectx. Format used
699 """Returns a string of sets of successors for a changectx. Format used
683 is: [ctx1, ctx2], [ctx3] if ctx has been splitted into ctx1 and ctx2
700 is: [ctx1, ctx2], [ctx3] if ctx has been splitted into ctx1 and ctx2
684 while also diverged into ctx3. (EXPERIMENTAL)"""
701 while also diverged into ctx3. (EXPERIMENTAL)"""
685 if not ctx.obsolete():
702 if not ctx.obsolete():
686 return ''
703 return ''
687 args = pycompat.byteskwargs(args)
704 args = pycompat.byteskwargs(args)
688
705
689 ssets = obsutil.successorssets(repo, ctx.node(), closest=True)
706 ssets = obsutil.successorssets(repo, ctx.node(), closest=True)
690 ssets = [[hex(n) for n in ss] for ss in ssets]
707 ssets = [[hex(n) for n in ss] for ss in ssets]
691
708
692 data = []
709 data = []
693 for ss in ssets:
710 for ss in ssets:
694 h = _hybrid(None, ss, lambda x: {'ctx': repo[x], 'revcache': {}},
711 h = _hybrid(None, ss, lambda x: {'ctx': repo[x], 'revcache': {}},
695 lambda x: scmutil.formatchangeid(repo[x]))
712 lambda x: scmutil.formatchangeid(repo[x]))
696 data.append(h)
713 data.append(h)
697
714
698 # Format the successorssets
715 # Format the successorssets
699 def render(d):
716 def render(d):
700 t = []
717 t = []
701 for i in d.gen():
718 for i in d.gen():
702 t.append(i)
719 t.append(i)
703 return "".join(t)
720 return "".join(t)
704
721
705 def gen(data):
722 def gen(data):
706 yield "; ".join(render(d) for d in data)
723 yield "; ".join(render(d) for d in data)
707
724
708 return _hybrid(gen(data), data, lambda x: {'successorset': x},
725 return _hybrid(gen(data), data, lambda x: {'successorset': x},
709 pycompat.identity)
726 pycompat.identity)
710
727
711 @templatekeyword("succsandmarkers")
728 @templatekeyword("succsandmarkers")
712 def showsuccsandmarkers(repo, ctx, **args):
729 def showsuccsandmarkers(repo, ctx, **args):
713 """Returns a list of dict for each final successor of ctx. The dict
730 """Returns a list of dict for each final successor of ctx. The dict
714 contains successors node id in "successors" keys and the list of
731 contains successors node id in "successors" keys and the list of
715 obs-markers from ctx to the set of successors in "markers".
732 obs-markers from ctx to the set of successors in "markers".
716 (EXPERIMENTAL)
733 (EXPERIMENTAL)
717 """
734 """
718
735
719 values = obsutil.successorsandmarkers(repo, ctx)
736 values = obsutil.successorsandmarkers(repo, ctx)
720
737
721 if values is None:
738 if values is None:
722 values = []
739 values = []
723
740
724 # Format successors and markers to avoid exposing binary to templates
741 # Format successors and markers to avoid exposing binary to templates
725 data = []
742 data = []
726 for i in values:
743 for i in values:
727 # Format successors
744 # Format successors
728 successors = i['successors']
745 successors = i['successors']
729
746
730 successors = [hex(n) for n in successors]
747 successors = [hex(n) for n in successors]
731 successors = _hybrid(None, successors,
748 successors = _hybrid(None, successors,
732 lambda x: {'ctx': repo[x], 'revcache': {}},
749 lambda x: {'ctx': repo[x], 'revcache': {}},
733 lambda x: scmutil.formatchangeid(repo[x]))
750 lambda x: scmutil.formatchangeid(repo[x]))
734
751
735 # Format markers
752 # Format markers
736 finalmarkers = []
753 finalmarkers = []
737 for m in i['markers']:
754 for m in i['markers']:
738 hexprec = hex(m[0])
755 hexprec = hex(m[0])
739 hexsucs = tuple(hex(n) for n in m[1])
756 hexsucs = tuple(hex(n) for n in m[1])
740 hexparents = None
757 hexparents = None
741 if m[5] is not None:
758 if m[5] is not None:
742 hexparents = tuple(hex(n) for n in m[5])
759 hexparents = tuple(hex(n) for n in m[5])
743 newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
760 newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
744 finalmarkers.append(newmarker)
761 finalmarkers.append(newmarker)
745
762
746 data.append({'successors': successors, 'markers': finalmarkers})
763 data.append({'successors': successors, 'markers': finalmarkers})
747
764
748 f = _showlist('succsandmarkers', data, args)
765 f = _showlist('succsandmarkers', data, args)
749 return _hybrid(f, data, lambda x: x, pycompat.identity)
766 return _hybrid(f, data, lambda x: x, pycompat.identity)
750
767
751 @templatekeyword('p1rev')
768 @templatekeyword('p1rev')
752 def showp1rev(repo, ctx, templ, **args):
769 def showp1rev(repo, ctx, templ, **args):
753 """Integer. The repository-local revision number of the changeset's
770 """Integer. The repository-local revision number of the changeset's
754 first parent, or -1 if the changeset has no parents."""
771 first parent, or -1 if the changeset has no parents."""
755 return ctx.p1().rev()
772 return ctx.p1().rev()
756
773
757 @templatekeyword('p2rev')
774 @templatekeyword('p2rev')
758 def showp2rev(repo, ctx, templ, **args):
775 def showp2rev(repo, ctx, templ, **args):
759 """Integer. The repository-local revision number of the changeset's
776 """Integer. The repository-local revision number of the changeset's
760 second parent, or -1 if the changeset has no second parent."""
777 second parent, or -1 if the changeset has no second parent."""
761 return ctx.p2().rev()
778 return ctx.p2().rev()
762
779
763 @templatekeyword('p1node')
780 @templatekeyword('p1node')
764 def showp1node(repo, ctx, templ, **args):
781 def showp1node(repo, ctx, templ, **args):
765 """String. The identification hash of the changeset's first parent,
782 """String. The identification hash of the changeset's first parent,
766 as a 40 digit hexadecimal string. If the changeset has no parents, all
783 as a 40 digit hexadecimal string. If the changeset has no parents, all
767 digits are 0."""
784 digits are 0."""
768 return ctx.p1().hex()
785 return ctx.p1().hex()
769
786
770 @templatekeyword('p2node')
787 @templatekeyword('p2node')
771 def showp2node(repo, ctx, templ, **args):
788 def showp2node(repo, ctx, templ, **args):
772 """String. The identification hash of the changeset's second
789 """String. The identification hash of the changeset's second
773 parent, as a 40 digit hexadecimal string. If the changeset has no second
790 parent, as a 40 digit hexadecimal string. If the changeset has no second
774 parent, all digits are 0."""
791 parent, all digits are 0."""
775 return ctx.p2().hex()
792 return ctx.p2().hex()
776
793
777 @templatekeyword('parents')
794 @templatekeyword('parents')
778 def showparents(**args):
795 def showparents(**args):
779 """List of strings. The parents of the changeset in "rev:node"
796 """List of strings. The parents of the changeset in "rev:node"
780 format. If the changeset has only one "natural" parent (the predecessor
797 format. If the changeset has only one "natural" parent (the predecessor
781 revision) nothing is shown."""
798 revision) nothing is shown."""
782 args = pycompat.byteskwargs(args)
799 args = pycompat.byteskwargs(args)
783 repo = args['repo']
800 repo = args['repo']
784 ctx = args['ctx']
801 ctx = args['ctx']
785 pctxs = scmutil.meaningfulparents(repo, ctx)
802 pctxs = scmutil.meaningfulparents(repo, ctx)
786 prevs = [p.rev() for p in pctxs]
803 prevs = [p.rev() for p in pctxs]
787 parents = [[('rev', p.rev()),
804 parents = [[('rev', p.rev()),
788 ('node', p.hex()),
805 ('node', p.hex()),
789 ('phase', p.phasestr())]
806 ('phase', p.phasestr())]
790 for p in pctxs]
807 for p in pctxs]
791 f = _showlist('parent', parents, args)
808 f = _showlist('parent', parents, args)
792 return _hybrid(f, prevs, lambda x: {'ctx': repo[x], 'revcache': {}},
809 return _hybrid(f, prevs, lambda x: {'ctx': repo[x], 'revcache': {}},
793 lambda x: scmutil.formatchangeid(repo[x]), keytype=int)
810 lambda x: scmutil.formatchangeid(repo[x]), keytype=int)
794
811
795 @templatekeyword('phase')
812 @templatekeyword('phase')
796 def showphase(repo, ctx, templ, **args):
813 def showphase(repo, ctx, templ, **args):
797 """String. The changeset phase name."""
814 """String. The changeset phase name."""
798 return ctx.phasestr()
815 return ctx.phasestr()
799
816
800 @templatekeyword('phaseidx')
817 @templatekeyword('phaseidx')
801 def showphaseidx(repo, ctx, templ, **args):
818 def showphaseidx(repo, ctx, templ, **args):
802 """Integer. The changeset phase index."""
819 """Integer. The changeset phase index."""
803 return ctx.phase()
820 return ctx.phase()
804
821
805 @templatekeyword('rev')
822 @templatekeyword('rev')
806 def showrev(repo, ctx, templ, **args):
823 def showrev(repo, ctx, templ, **args):
807 """Integer. The repository-local changeset revision number."""
824 """Integer. The repository-local changeset revision number."""
808 return scmutil.intrev(ctx)
825 return scmutil.intrev(ctx)
809
826
810 def showrevslist(name, revs, **args):
827 def showrevslist(name, revs, **args):
811 """helper to generate a list of revisions in which a mapped template will
828 """helper to generate a list of revisions in which a mapped template will
812 be evaluated"""
829 be evaluated"""
813 args = pycompat.byteskwargs(args)
830 args = pycompat.byteskwargs(args)
814 repo = args['ctx'].repo()
831 repo = args['ctx'].repo()
815 f = _showlist(name, ['%d' % r for r in revs], args)
832 f = _showlist(name, ['%d' % r for r in revs], args)
816 return _hybrid(f, revs,
833 return _hybrid(f, revs,
817 lambda x: {name: x, 'ctx': repo[x], 'revcache': {}},
834 lambda x: {name: x, 'ctx': repo[x], 'revcache': {}},
818 pycompat.identity, keytype=int)
835 pycompat.identity, keytype=int)
819
836
820 @templatekeyword('subrepos')
837 @templatekeyword('subrepos')
821 def showsubrepos(**args):
838 def showsubrepos(**args):
822 """List of strings. Updated subrepositories in the changeset."""
839 """List of strings. Updated subrepositories in the changeset."""
823 args = pycompat.byteskwargs(args)
840 args = pycompat.byteskwargs(args)
824 ctx = args['ctx']
841 ctx = args['ctx']
825 substate = ctx.substate
842 substate = ctx.substate
826 if not substate:
843 if not substate:
827 return showlist('subrepo', [], args)
844 return showlist('subrepo', [], args)
828 psubstate = ctx.parents()[0].substate or {}
845 psubstate = ctx.parents()[0].substate or {}
829 subrepos = []
846 subrepos = []
830 for sub in substate:
847 for sub in substate:
831 if sub not in psubstate or substate[sub] != psubstate[sub]:
848 if sub not in psubstate or substate[sub] != psubstate[sub]:
832 subrepos.append(sub) # modified or newly added in ctx
849 subrepos.append(sub) # modified or newly added in ctx
833 for sub in psubstate:
850 for sub in psubstate:
834 if sub not in substate:
851 if sub not in substate:
835 subrepos.append(sub) # removed in ctx
852 subrepos.append(sub) # removed in ctx
836 return showlist('subrepo', sorted(subrepos), args)
853 return showlist('subrepo', sorted(subrepos), args)
837
854
838 # don't remove "showtags" definition, even though namespaces will put
855 # don't remove "showtags" definition, even though namespaces will put
839 # a helper function for "tags" keyword into "keywords" map automatically,
856 # a helper function for "tags" keyword into "keywords" map automatically,
840 # because online help text is built without namespaces initialization
857 # because online help text is built without namespaces initialization
841 @templatekeyword('tags')
858 @templatekeyword('tags')
842 def showtags(**args):
859 def showtags(**args):
843 """List of strings. Any tags associated with the changeset."""
860 """List of strings. Any tags associated with the changeset."""
844 return shownames('tags', **args)
861 return shownames('tags', **args)
845
862
846 def loadkeyword(ui, extname, registrarobj):
863 def loadkeyword(ui, extname, registrarobj):
847 """Load template keyword from specified registrarobj
864 """Load template keyword from specified registrarobj
848 """
865 """
849 for name, func in registrarobj._table.iteritems():
866 for name, func in registrarobj._table.iteritems():
850 keywords[name] = func
867 keywords[name] = func
851
868
852 @templatekeyword('termwidth')
869 @templatekeyword('termwidth')
853 def showtermwidth(repo, ctx, templ, **args):
870 def showtermwidth(repo, ctx, templ, **args):
854 """Integer. The width of the current terminal."""
871 """Integer. The width of the current terminal."""
855 return repo.ui.termwidth()
872 return repo.ui.termwidth()
856
873
857 @templatekeyword('troubles')
874 @templatekeyword('troubles')
858 def showtroubles(repo, **args):
875 def showtroubles(repo, **args):
859 """List of strings. Evolution troubles affecting the changeset.
876 """List of strings. Evolution troubles affecting the changeset.
860 (DEPRECATED)
877 (DEPRECATED)
861 """
878 """
862 msg = ("'troubles' is deprecated, "
879 msg = ("'troubles' is deprecated, "
863 "use 'instabilities'")
880 "use 'instabilities'")
864 repo.ui.deprecwarn(msg, '4.4')
881 repo.ui.deprecwarn(msg, '4.4')
865
882
866 return showinstabilities(repo=repo, **args)
883 return showinstabilities(repo=repo, **args)
867
884
868 @templatekeyword('instabilities')
885 @templatekeyword('instabilities')
869 def showinstabilities(**args):
886 def showinstabilities(**args):
870 """List of strings. Evolution instabilities affecting the changeset.
887 """List of strings. Evolution instabilities affecting the changeset.
871 (EXPERIMENTAL)
888 (EXPERIMENTAL)
872 """
889 """
873 args = pycompat.byteskwargs(args)
890 args = pycompat.byteskwargs(args)
874 return showlist('instability', args['ctx'].instabilities(), args,
891 return showlist('instability', args['ctx'].instabilities(), args,
875 plural='instabilities')
892 plural='instabilities')
876
893
877 # tell hggettext to extract docstrings from these functions:
894 # tell hggettext to extract docstrings from these functions:
878 i18nfunctions = keywords.values()
895 i18nfunctions = keywords.values()
@@ -1,494 +1,487
1 =============================
1 =============================
2 Test distributed obsolescence
2 Test distributed obsolescence
3 =============================
3 =============================
4
4
5 This file test various cases where data (changeset, phase, obsmarkers) is
5 This file test various cases where data (changeset, phase, obsmarkers) is
6 added to the repository in a specific order. Usually, this order is unlikely
6 added to the repository in a specific order. Usually, this order is unlikely
7 to happen in the local case but can easily happen in the distributed case.
7 to happen in the local case but can easily happen in the distributed case.
8
8
9 $ unset HGUSER
9 $ unset HGUSER
10 $ unset EMAIL
10 $ unset EMAIL
11 $ . $TESTDIR/testlib/obsmarker-common.sh
11 $ . $TESTDIR/testlib/obsmarker-common.sh
12 $ cat >> $HGRCPATH << EOF
12 $ cat >> $HGRCPATH << EOF
13 > [extensions]
13 > [extensions]
14 > rebase =
14 > rebase =
15 > [experimental]
15 > [experimental]
16 > evolution = all
16 > evolution = all
17 > [phases]
17 > [phases]
18 > publish = False
18 > publish = False
19 > [templates]
20 > obsfatesuccessors = "{if(successors, " as ")}{join(successors, ", ")}"
21 > obsfateverb = "{obsfateverb(successors)}"
22 > obsfateoperations = "{if(obsfateoperations(markers), " using {join(obsfateoperations(markers), ", ")}")}"
23 > obsfateusers = "{if(obsfateusers(markers), " by {join(obsfateusers(markers), ", ")}")}"
24 > obsfatedate = "{if(obsfatedate(markers), "{ifeq(min(obsfatedate(markers)), max(obsfatedate(markers)), " (at {min(obsfatedate(markers))|isodate})", " (between {min(obsfatedate(markers))|isodate} and {max(obsfatedate(markers))|isodate})")}")}"
25 > obsfate = "{obsfateverb}{obsfateoperations}{obsfatesuccessors}{obsfateusers}{obsfatedate}; "
26 > [ui]
19 > [ui]
27 > logtemplate= {rev}:{node|short} {desc} {if(succsandmarkers, "[{succsandmarkers % "{obsfate}"}]")}\n
20 > logtemplate= {rev}:{node|short} {desc}{if(obsfate, " [{join(obsfate, "; ")}]")}\n
28 > EOF
21 > EOF
29
22
30 Check distributed chain building
23 Check distributed chain building
31 ================================
24 ================================
32
25
33 Test case where a changeset is marked as a successor of another local
26 Test case where a changeset is marked as a successor of another local
34 changeset while the successor has already been obsoleted remotely.
27 changeset while the successor has already been obsoleted remotely.
35
28
36 The chain of evolution should seamlessly connect and all but the new version
29 The chain of evolution should seamlessly connect and all but the new version
37 (created remotely) should be seen as obsolete.
30 (created remotely) should be seen as obsolete.
38
31
39 Initial setup
32 Initial setup
40
33
41 $ mkdir distributed-chain-building
34 $ mkdir distributed-chain-building
42 $ cd distributed-chain-building
35 $ cd distributed-chain-building
43 $ hg init server
36 $ hg init server
44 $ cd server
37 $ cd server
45 $ cat << EOF >> .hg/hgrc
38 $ cat << EOF >> .hg/hgrc
46 > [ui]
39 > [ui]
47 > username = server
40 > username = server
48 > EOF
41 > EOF
49 $ mkcommit ROOT
42 $ mkcommit ROOT
50 $ mkcommit c_A0
43 $ mkcommit c_A0
51 $ hg up 'desc("ROOT")'
44 $ hg up 'desc("ROOT")'
52 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
45 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
53 $ mkcommit c_A1
46 $ mkcommit c_A1
54 created new head
47 created new head
55 $ hg up 'desc("ROOT")'
48 $ hg up 'desc("ROOT")'
56 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
49 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
57 $ mkcommit c_B0
50 $ mkcommit c_B0
58 created new head
51 created new head
59 $ hg debugobsolete `getid 'desc("c_A0")'` `getid 'desc("c_A1")'`
52 $ hg debugobsolete `getid 'desc("c_A0")'` `getid 'desc("c_A1")'`
60 obsoleted 1 changesets
53 obsoleted 1 changesets
61 $ hg log -G --hidden
54 $ hg log -G --hidden
62 @ 3:e5d7dda7cd28 c_B0
55 @ 3:e5d7dda7cd28 c_B0
63 |
56 |
64 | o 2:7f6b0a6f5c25 c_A1
57 | o 2:7f6b0a6f5c25 c_A1
65 |/
58 |/
66 | x 1:e1b46f0f979f c_A0 [rewritten as 2:7f6b0a6f5c25 by server (at 1970-01-01 00:00 +0000); ]
59 | x 1:e1b46f0f979f c_A0 [rewritten as 2:7f6b0a6f5c25 by server (at 1970-01-01 00:00 +0000)]
67 |/
60 |/
68 o 0:e82fb8d02bbf ROOT
61 o 0:e82fb8d02bbf ROOT
69
62
70 $ hg debugobsolete
63 $ hg debugobsolete
71 e1b46f0f979f52748347ff8729c59f2ef56e6fe2 7f6b0a6f5c25345a83870963efd827c1798a5959 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
64 e1b46f0f979f52748347ff8729c59f2ef56e6fe2 7f6b0a6f5c25345a83870963efd827c1798a5959 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
72 $ cd ..
65 $ cd ..
73
66
74 duplicate the repo for the client:
67 duplicate the repo for the client:
75
68
76 $ cp -R server client
69 $ cp -R server client
77 $ cat << EOF >> client/.hg/hgrc
70 $ cat << EOF >> client/.hg/hgrc
78 > [paths]
71 > [paths]
79 > default = ../server/
72 > default = ../server/
80 > [ui]
73 > [ui]
81 > username = client
74 > username = client
82 > EOF
75 > EOF
83
76
84 server side: create new revision on the server (obsoleting another one)
77 server side: create new revision on the server (obsoleting another one)
85
78
86 $ cd server
79 $ cd server
87 $ hg up 'desc("ROOT")'
80 $ hg up 'desc("ROOT")'
88 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
81 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
89 $ mkcommit c_B1
82 $ mkcommit c_B1
90 created new head
83 created new head
91 $ hg debugobsolete `getid 'desc("c_B0")'` `getid 'desc("c_B1")'`
84 $ hg debugobsolete `getid 'desc("c_B0")'` `getid 'desc("c_B1")'`
92 obsoleted 1 changesets
85 obsoleted 1 changesets
93 $ hg log -G
86 $ hg log -G
94 @ 4:391a2bf12b1b c_B1
87 @ 4:391a2bf12b1b c_B1
95 |
88 |
96 | o 2:7f6b0a6f5c25 c_A1
89 | o 2:7f6b0a6f5c25 c_A1
97 |/
90 |/
98 o 0:e82fb8d02bbf ROOT
91 o 0:e82fb8d02bbf ROOT
99
92
100 $ hg log -G --hidden
93 $ hg log -G --hidden
101 @ 4:391a2bf12b1b c_B1
94 @ 4:391a2bf12b1b c_B1
102 |
95 |
103 | x 3:e5d7dda7cd28 c_B0 [rewritten as 4:391a2bf12b1b by server (at 1970-01-01 00:00 +0000); ]
96 | x 3:e5d7dda7cd28 c_B0 [rewritten as 4:391a2bf12b1b by server (at 1970-01-01 00:00 +0000)]
104 |/
97 |/
105 | o 2:7f6b0a6f5c25 c_A1
98 | o 2:7f6b0a6f5c25 c_A1
106 |/
99 |/
107 | x 1:e1b46f0f979f c_A0 [rewritten as 2:7f6b0a6f5c25 by server (at 1970-01-01 00:00 +0000); ]
100 | x 1:e1b46f0f979f c_A0 [rewritten as 2:7f6b0a6f5c25 by server (at 1970-01-01 00:00 +0000)]
108 |/
101 |/
109 o 0:e82fb8d02bbf ROOT
102 o 0:e82fb8d02bbf ROOT
110
103
111 $ hg debugobsolete
104 $ hg debugobsolete
112 e1b46f0f979f52748347ff8729c59f2ef56e6fe2 7f6b0a6f5c25345a83870963efd827c1798a5959 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
105 e1b46f0f979f52748347ff8729c59f2ef56e6fe2 7f6b0a6f5c25345a83870963efd827c1798a5959 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
113 e5d7dda7cd28e6b3f79437e5b8122a38ece0255c 391a2bf12b1b8b05a72400ae36b26d50a091dc22 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
106 e5d7dda7cd28e6b3f79437e5b8122a38ece0255c 391a2bf12b1b8b05a72400ae36b26d50a091dc22 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
114 $ cd ..
107 $ cd ..
115
108
116 client side: create a marker between two common changesets
109 client side: create a marker between two common changesets
117 (client is not aware of the server activity yet)
110 (client is not aware of the server activity yet)
118
111
119 $ cd client
112 $ cd client
120 $ hg debugobsolete `getid 'desc("c_A1")'` `getid 'desc("c_B0")'`
113 $ hg debugobsolete `getid 'desc("c_A1")'` `getid 'desc("c_B0")'`
121 obsoleted 1 changesets
114 obsoleted 1 changesets
122 $ hg log -G
115 $ hg log -G
123 @ 3:e5d7dda7cd28 c_B0
116 @ 3:e5d7dda7cd28 c_B0
124 |
117 |
125 o 0:e82fb8d02bbf ROOT
118 o 0:e82fb8d02bbf ROOT
126
119
127 $ hg log -G --hidden
120 $ hg log -G --hidden
128 @ 3:e5d7dda7cd28 c_B0
121 @ 3:e5d7dda7cd28 c_B0
129 |
122 |
130 | x 2:7f6b0a6f5c25 c_A1 [rewritten as 3:e5d7dda7cd28 by client (at 1970-01-01 00:00 +0000); ]
123 | x 2:7f6b0a6f5c25 c_A1 [rewritten as 3:e5d7dda7cd28 by client (at 1970-01-01 00:00 +0000)]
131 |/
124 |/
132 | x 1:e1b46f0f979f c_A0 [rewritten as 2:7f6b0a6f5c25 by server (at 1970-01-01 00:00 +0000); ]
125 | x 1:e1b46f0f979f c_A0 [rewritten as 2:7f6b0a6f5c25 by server (at 1970-01-01 00:00 +0000)]
133 |/
126 |/
134 o 0:e82fb8d02bbf ROOT
127 o 0:e82fb8d02bbf ROOT
135
128
136 $ hg debugobsolete
129 $ hg debugobsolete
137 e1b46f0f979f52748347ff8729c59f2ef56e6fe2 7f6b0a6f5c25345a83870963efd827c1798a5959 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
130 e1b46f0f979f52748347ff8729c59f2ef56e6fe2 7f6b0a6f5c25345a83870963efd827c1798a5959 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
138 7f6b0a6f5c25345a83870963efd827c1798a5959 e5d7dda7cd28e6b3f79437e5b8122a38ece0255c 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'client'}
131 7f6b0a6f5c25345a83870963efd827c1798a5959 e5d7dda7cd28e6b3f79437e5b8122a38ece0255c 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'client'}
139
132
140 client side: pull from the server
133 client side: pull from the server
141 (the new successors should take over)
134 (the new successors should take over)
142
135
143 $ hg up 'desc("ROOT")'
136 $ hg up 'desc("ROOT")'
144 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
137 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
145 $ hg pull
138 $ hg pull
146 pulling from $TESTTMP/distributed-chain-building/server (glob)
139 pulling from $TESTTMP/distributed-chain-building/server (glob)
147 searching for changes
140 searching for changes
148 adding changesets
141 adding changesets
149 adding manifests
142 adding manifests
150 adding file changes
143 adding file changes
151 added 1 changesets with 1 changes to 1 files (+1 heads)
144 added 1 changesets with 1 changes to 1 files (+1 heads)
152 1 new obsolescence markers
145 1 new obsolescence markers
153 obsoleted 1 changesets
146 obsoleted 1 changesets
154 new changesets 391a2bf12b1b
147 new changesets 391a2bf12b1b
155 (run 'hg heads' to see heads)
148 (run 'hg heads' to see heads)
156 $ hg log -G
149 $ hg log -G
157 o 4:391a2bf12b1b c_B1
150 o 4:391a2bf12b1b c_B1
158 |
151 |
159 @ 0:e82fb8d02bbf ROOT
152 @ 0:e82fb8d02bbf ROOT
160
153
161 $ hg log -G --hidden
154 $ hg log -G --hidden
162 o 4:391a2bf12b1b c_B1
155 o 4:391a2bf12b1b c_B1
163 |
156 |
164 | x 3:e5d7dda7cd28 c_B0 [rewritten as 4:391a2bf12b1b by server (at 1970-01-01 00:00 +0000); ]
157 | x 3:e5d7dda7cd28 c_B0 [rewritten as 4:391a2bf12b1b by server (at 1970-01-01 00:00 +0000)]
165 |/
158 |/
166 | x 2:7f6b0a6f5c25 c_A1 [rewritten as 3:e5d7dda7cd28 by client (at 1970-01-01 00:00 +0000); ]
159 | x 2:7f6b0a6f5c25 c_A1 [rewritten as 3:e5d7dda7cd28 by client (at 1970-01-01 00:00 +0000)]
167 |/
160 |/
168 | x 1:e1b46f0f979f c_A0 [rewritten as 2:7f6b0a6f5c25 by server (at 1970-01-01 00:00 +0000); ]
161 | x 1:e1b46f0f979f c_A0 [rewritten as 2:7f6b0a6f5c25 by server (at 1970-01-01 00:00 +0000)]
169 |/
162 |/
170 @ 0:e82fb8d02bbf ROOT
163 @ 0:e82fb8d02bbf ROOT
171
164
172 $ hg debugobsolete
165 $ hg debugobsolete
173 e1b46f0f979f52748347ff8729c59f2ef56e6fe2 7f6b0a6f5c25345a83870963efd827c1798a5959 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
166 e1b46f0f979f52748347ff8729c59f2ef56e6fe2 7f6b0a6f5c25345a83870963efd827c1798a5959 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
174 7f6b0a6f5c25345a83870963efd827c1798a5959 e5d7dda7cd28e6b3f79437e5b8122a38ece0255c 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'client'}
167 7f6b0a6f5c25345a83870963efd827c1798a5959 e5d7dda7cd28e6b3f79437e5b8122a38ece0255c 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'client'}
175 e5d7dda7cd28e6b3f79437e5b8122a38ece0255c 391a2bf12b1b8b05a72400ae36b26d50a091dc22 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
168 e5d7dda7cd28e6b3f79437e5b8122a38ece0255c 391a2bf12b1b8b05a72400ae36b26d50a091dc22 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
176
169
177 server side: receive client push
170 server side: receive client push
178 (the other way around, pushing to the server, the obsolete changesets stay
171 (the other way around, pushing to the server, the obsolete changesets stay
179 obsolete on the server side but the marker is sent out.)
172 obsolete on the server side but the marker is sent out.)
180
173
181 $ hg rollback
174 $ hg rollback
182 repository tip rolled back to revision 3 (undo pull)
175 repository tip rolled back to revision 3 (undo pull)
183 $ hg push -f
176 $ hg push -f
184 pushing to $TESTTMP/distributed-chain-building/server (glob)
177 pushing to $TESTTMP/distributed-chain-building/server (glob)
185 searching for changes
178 searching for changes
186 adding changesets
179 adding changesets
187 adding manifests
180 adding manifests
188 adding file changes
181 adding file changes
189 added 0 changesets with 0 changes to 1 files
182 added 0 changesets with 0 changes to 1 files
190 1 new obsolescence markers
183 1 new obsolescence markers
191 obsoleted 1 changesets
184 obsoleted 1 changesets
192 $ hg -R ../server/ log -G
185 $ hg -R ../server/ log -G
193 @ 4:391a2bf12b1b c_B1
186 @ 4:391a2bf12b1b c_B1
194 |
187 |
195 o 0:e82fb8d02bbf ROOT
188 o 0:e82fb8d02bbf ROOT
196
189
197 $ hg -R ../server/ log -G --hidden
190 $ hg -R ../server/ log -G --hidden
198 @ 4:391a2bf12b1b c_B1
191 @ 4:391a2bf12b1b c_B1
199 |
192 |
200 | x 3:e5d7dda7cd28 c_B0 [rewritten as 4:391a2bf12b1b by server (at 1970-01-01 00:00 +0000); ]
193 | x 3:e5d7dda7cd28 c_B0 [rewritten as 4:391a2bf12b1b by server (at 1970-01-01 00:00 +0000)]
201 |/
194 |/
202 | x 2:7f6b0a6f5c25 c_A1 [rewritten as 3:e5d7dda7cd28 by client (at 1970-01-01 00:00 +0000); ]
195 | x 2:7f6b0a6f5c25 c_A1 [rewritten as 3:e5d7dda7cd28 by client (at 1970-01-01 00:00 +0000)]
203 |/
196 |/
204 | x 1:e1b46f0f979f c_A0 [rewritten as 2:7f6b0a6f5c25 by server (at 1970-01-01 00:00 +0000); ]
197 | x 1:e1b46f0f979f c_A0 [rewritten as 2:7f6b0a6f5c25 by server (at 1970-01-01 00:00 +0000)]
205 |/
198 |/
206 o 0:e82fb8d02bbf ROOT
199 o 0:e82fb8d02bbf ROOT
207
200
208 $ hg debugobsolete
201 $ hg debugobsolete
209 e1b46f0f979f52748347ff8729c59f2ef56e6fe2 7f6b0a6f5c25345a83870963efd827c1798a5959 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
202 e1b46f0f979f52748347ff8729c59f2ef56e6fe2 7f6b0a6f5c25345a83870963efd827c1798a5959 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'server'}
210 7f6b0a6f5c25345a83870963efd827c1798a5959 e5d7dda7cd28e6b3f79437e5b8122a38ece0255c 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'client'}
203 7f6b0a6f5c25345a83870963efd827c1798a5959 e5d7dda7cd28e6b3f79437e5b8122a38ece0255c 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'client'}
211 $ cd ..
204 $ cd ..
212
205
213 Check getting changesets after getting the markers
206 Check getting changesets after getting the markers
214 =================================================
207 =================================================
215
208
216 This test case covers the scenario where commits are received -after- we
209 This test case covers the scenario where commits are received -after- we
217 received some obsolescence markers turning them obsolete.
210 received some obsolescence markers turning them obsolete.
218
211
219 For example, we pull some successors from a repository (with associated
212 For example, we pull some successors from a repository (with associated
220 predecessors marker chain) and then later we pull some intermediate
213 predecessors marker chain) and then later we pull some intermediate
221 precedessors changeset from another repository. Obsolescence markers must
214 precedessors changeset from another repository. Obsolescence markers must
222 apply to the intermediate changeset. They have to be obsolete (and hidden).
215 apply to the intermediate changeset. They have to be obsolete (and hidden).
223
216
224 Avoiding pulling the changeset in the first place is a tricky decision because
217 Avoiding pulling the changeset in the first place is a tricky decision because
225 there could be non-obsolete ancestors that need to be pulled, but the
218 there could be non-obsolete ancestors that need to be pulled, but the
226 discovery cannot currently find these (this is not the case in this tests). In
219 discovery cannot currently find these (this is not the case in this tests). In
227 addition, we could also have to pull the changeset because they have children.
220 addition, we could also have to pull the changeset because they have children.
228 In this case, they would not be hidden (yet) because of the orphan descendant,
221 In this case, they would not be hidden (yet) because of the orphan descendant,
229 but they would still have to be obsolete. (This is not tested in this case
222 but they would still have to be obsolete. (This is not tested in this case
230 either).
223 either).
231
224
232 $ mkdir distributed-chain-building
225 $ mkdir distributed-chain-building
233 $ cd distributed-chain-building
226 $ cd distributed-chain-building
234 $ hg init server
227 $ hg init server
235 $ cd server
228 $ cd server
236 $ cat << EOF >> .hg/hgrc
229 $ cat << EOF >> .hg/hgrc
237 > [ui]
230 > [ui]
238 > username = server
231 > username = server
239 > EOF
232 > EOF
240 $ mkcommit ROOT
233 $ mkcommit ROOT
241 $ cd ..
234 $ cd ..
242 $ hg clone server repo-Alice
235 $ hg clone server repo-Alice
243 updating to branch default
236 updating to branch default
244 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
237 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
245 $ cat << EOF >> repo-Alice/.hg/hgrc
238 $ cat << EOF >> repo-Alice/.hg/hgrc
246 > [ui]
239 > [ui]
247 > username = alice
240 > username = alice
248 > EOF
241 > EOF
249 $ hg clone server repo-Bob
242 $ hg clone server repo-Bob
250 updating to branch default
243 updating to branch default
251 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
244 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
252 $ cat << EOF >> repo-Bob/.hg/hgrc
245 $ cat << EOF >> repo-Bob/.hg/hgrc
253 > [ui]
246 > [ui]
254 > username = bob
247 > username = bob
255 > EOF
248 > EOF
256 $ hg clone server repo-Celeste
249 $ hg clone server repo-Celeste
257 updating to branch default
250 updating to branch default
258 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
251 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
259 $ cat << EOF >> repo-Celeste/.hg/hgrc
252 $ cat << EOF >> repo-Celeste/.hg/hgrc
260 > [ui]
253 > [ui]
261 > username = celeste
254 > username = celeste
262 > EOF
255 > EOF
263
256
264 Create some changesets locally
257 Create some changesets locally
265
258
266 $ cd repo-Alice
259 $ cd repo-Alice
267 $ mkcommit c_A0
260 $ mkcommit c_A0
268 $ mkcommit c_B0
261 $ mkcommit c_B0
269 $ cd ..
262 $ cd ..
270
263
271 Bob pulls from Alice and rewrites them
264 Bob pulls from Alice and rewrites them
272
265
273 $ cd repo-Bob
266 $ cd repo-Bob
274 $ hg pull ../repo-Alice
267 $ hg pull ../repo-Alice
275 pulling from ../repo-Alice
268 pulling from ../repo-Alice
276 searching for changes
269 searching for changes
277 adding changesets
270 adding changesets
278 adding manifests
271 adding manifests
279 adding file changes
272 adding file changes
280 added 2 changesets with 2 changes to 2 files
273 added 2 changesets with 2 changes to 2 files
281 new changesets d33b0a3a6464:ef908e42ce65
274 new changesets d33b0a3a6464:ef908e42ce65
282 (run 'hg update' to get a working copy)
275 (run 'hg update' to get a working copy)
283 $ hg up 'desc("c_A")'
276 $ hg up 'desc("c_A")'
284 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
285 $ hg commit --amend -m 'c_A1'
278 $ hg commit --amend -m 'c_A1'
286 $ hg rebase -r 'desc("c_B0")' -d . # no easy way to rewrite the message with the rebase
279 $ hg rebase -r 'desc("c_B0")' -d . # no easy way to rewrite the message with the rebase
287 rebasing 2:ef908e42ce65 "c_B0"
280 rebasing 2:ef908e42ce65 "c_B0"
288 $ hg up
281 $ hg up
289 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
282 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
290 $ hg commit --amend -m 'c_B1'
283 $ hg commit --amend -m 'c_B1'
291 $ hg log -G
284 $ hg log -G
292 @ 5:956063ac4557 c_B1
285 @ 5:956063ac4557 c_B1
293 |
286 |
294 o 3:5b5708a437f2 c_A1
287 o 3:5b5708a437f2 c_A1
295 |
288 |
296 o 0:e82fb8d02bbf ROOT
289 o 0:e82fb8d02bbf ROOT
297
290
298 $ hg log -G --hidden
291 $ hg log -G --hidden
299 @ 5:956063ac4557 c_B1
292 @ 5:956063ac4557 c_B1
300 |
293 |
301 | x 4:5ffb9e311b35 c_B0 [rewritten using amend as 5:956063ac4557 by bob (at 1970-01-01 00:00 +0000); ]
294 | x 4:5ffb9e311b35 c_B0 [rewritten using amend as 5:956063ac4557 by bob (at 1970-01-01 00:00 +0000)]
302 |/
295 |/
303 o 3:5b5708a437f2 c_A1
296 o 3:5b5708a437f2 c_A1
304 |
297 |
305 | x 2:ef908e42ce65 c_B0 [rewritten using rebase as 4:5ffb9e311b35 by bob (at 1970-01-01 00:00 +0000); ]
298 | x 2:ef908e42ce65 c_B0 [rewritten using rebase as 4:5ffb9e311b35 by bob (at 1970-01-01 00:00 +0000)]
306 | |
299 | |
307 | x 1:d33b0a3a6464 c_A0 [rewritten using amend as 3:5b5708a437f2 by bob (at 1970-01-01 00:00 +0000); ]
300 | x 1:d33b0a3a6464 c_A0 [rewritten using amend as 3:5b5708a437f2 by bob (at 1970-01-01 00:00 +0000)]
308 |/
301 |/
309 o 0:e82fb8d02bbf ROOT
302 o 0:e82fb8d02bbf ROOT
310
303
311 $ hg debugobsolete
304 $ hg debugobsolete
312 d33b0a3a64647d79583526be8107802b1f9fedfa 5b5708a437f27665db42c5a261a539a1bcb2a8c2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
305 d33b0a3a64647d79583526be8107802b1f9fedfa 5b5708a437f27665db42c5a261a539a1bcb2a8c2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
313 ef908e42ce65ef57f970d799acaddde26f58a4cc 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'bob'}
306 ef908e42ce65ef57f970d799acaddde26f58a4cc 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'bob'}
314 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 956063ac4557828781733b2d5677a351ce856f59 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
307 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 956063ac4557828781733b2d5677a351ce856f59 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
315 $ cd ..
308 $ cd ..
316
309
317 Celeste pulls from Bob and rewrites them again
310 Celeste pulls from Bob and rewrites them again
318
311
319 $ cd repo-Celeste
312 $ cd repo-Celeste
320 $ hg pull ../repo-Bob
313 $ hg pull ../repo-Bob
321 pulling from ../repo-Bob
314 pulling from ../repo-Bob
322 searching for changes
315 searching for changes
323 adding changesets
316 adding changesets
324 adding manifests
317 adding manifests
325 adding file changes
318 adding file changes
326 added 2 changesets with 2 changes to 2 files
319 added 2 changesets with 2 changes to 2 files
327 3 new obsolescence markers
320 3 new obsolescence markers
328 new changesets 5b5708a437f2:956063ac4557
321 new changesets 5b5708a437f2:956063ac4557
329 (run 'hg update' to get a working copy)
322 (run 'hg update' to get a working copy)
330 $ hg up 'desc("c_A")'
323 $ hg up 'desc("c_A")'
331 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
324 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
332 $ hg commit --amend -m 'c_A2'
325 $ hg commit --amend -m 'c_A2'
333 $ hg rebase -r 'desc("c_B1")' -d . # no easy way to rewrite the message with the rebase
326 $ hg rebase -r 'desc("c_B1")' -d . # no easy way to rewrite the message with the rebase
334 rebasing 2:956063ac4557 "c_B1"
327 rebasing 2:956063ac4557 "c_B1"
335 $ hg up
328 $ hg up
336 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
329 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
337 $ hg commit --amend -m 'c_B2'
330 $ hg commit --amend -m 'c_B2'
338 $ hg log -G
331 $ hg log -G
339 @ 5:77ae25d99ff0 c_B2
332 @ 5:77ae25d99ff0 c_B2
340 |
333 |
341 o 3:9866d64649a5 c_A2
334 o 3:9866d64649a5 c_A2
342 |
335 |
343 o 0:e82fb8d02bbf ROOT
336 o 0:e82fb8d02bbf ROOT
344
337
345 $ hg log -G --hidden
338 $ hg log -G --hidden
346 @ 5:77ae25d99ff0 c_B2
339 @ 5:77ae25d99ff0 c_B2
347 |
340 |
348 | x 4:3cf8de21cc22 c_B1 [rewritten using amend as 5:77ae25d99ff0 by celeste (at 1970-01-01 00:00 +0000); ]
341 | x 4:3cf8de21cc22 c_B1 [rewritten using amend as 5:77ae25d99ff0 by celeste (at 1970-01-01 00:00 +0000)]
349 |/
342 |/
350 o 3:9866d64649a5 c_A2
343 o 3:9866d64649a5 c_A2
351 |
344 |
352 | x 2:956063ac4557 c_B1 [rewritten using rebase as 4:3cf8de21cc22 by celeste (at 1970-01-01 00:00 +0000); ]
345 | x 2:956063ac4557 c_B1 [rewritten using rebase as 4:3cf8de21cc22 by celeste (at 1970-01-01 00:00 +0000)]
353 | |
346 | |
354 | x 1:5b5708a437f2 c_A1 [rewritten using amend as 3:9866d64649a5 by celeste (at 1970-01-01 00:00 +0000); ]
347 | x 1:5b5708a437f2 c_A1 [rewritten using amend as 3:9866d64649a5 by celeste (at 1970-01-01 00:00 +0000)]
355 |/
348 |/
356 o 0:e82fb8d02bbf ROOT
349 o 0:e82fb8d02bbf ROOT
357
350
358 $ hg debugobsolete
351 $ hg debugobsolete
359 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 956063ac4557828781733b2d5677a351ce856f59 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
352 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 956063ac4557828781733b2d5677a351ce856f59 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
360 d33b0a3a64647d79583526be8107802b1f9fedfa 5b5708a437f27665db42c5a261a539a1bcb2a8c2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
353 d33b0a3a64647d79583526be8107802b1f9fedfa 5b5708a437f27665db42c5a261a539a1bcb2a8c2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
361 ef908e42ce65ef57f970d799acaddde26f58a4cc 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'bob'}
354 ef908e42ce65ef57f970d799acaddde26f58a4cc 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'bob'}
362 5b5708a437f27665db42c5a261a539a1bcb2a8c2 9866d64649a5d9c5991fe119c7b2c33898114e10 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
355 5b5708a437f27665db42c5a261a539a1bcb2a8c2 9866d64649a5d9c5991fe119c7b2c33898114e10 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
363 956063ac4557828781733b2d5677a351ce856f59 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'celeste'}
356 956063ac4557828781733b2d5677a351ce856f59 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'celeste'}
364 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 77ae25d99ff07889e181126b1171b94bec8e5227 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
357 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 77ae25d99ff07889e181126b1171b94bec8e5227 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
365
358
366 Celeste now pushes to the server
359 Celeste now pushes to the server
367
360
368 (note: it would be enough to just have direct Celeste -> Alice exchange here.
361 (note: it would be enough to just have direct Celeste -> Alice exchange here.
369 However using a central server seems more common)
362 However using a central server seems more common)
370
363
371 $ hg push
364 $ hg push
372 pushing to $TESTTMP/distributed-chain-building/distributed-chain-building/server (glob)
365 pushing to $TESTTMP/distributed-chain-building/distributed-chain-building/server (glob)
373 searching for changes
366 searching for changes
374 adding changesets
367 adding changesets
375 adding manifests
368 adding manifests
376 adding file changes
369 adding file changes
377 added 2 changesets with 2 changes to 2 files
370 added 2 changesets with 2 changes to 2 files
378 6 new obsolescence markers
371 6 new obsolescence markers
379 $ cd ..
372 $ cd ..
380
373
381 Now Alice pulls from the server, then from Bob
374 Now Alice pulls from the server, then from Bob
382
375
383 Alice first retrieves the new evolution of its changesets and associated markers
376 Alice first retrieves the new evolution of its changesets and associated markers
384 from the server (note: could be from Celeste directly)
377 from the server (note: could be from Celeste directly)
385
378
386 $ cd repo-Alice
379 $ cd repo-Alice
387 $ hg up 'desc(ROOT)'
380 $ hg up 'desc(ROOT)'
388 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
381 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
389 $ hg pull
382 $ hg pull
390 pulling from $TESTTMP/distributed-chain-building/distributed-chain-building/server (glob)
383 pulling from $TESTTMP/distributed-chain-building/distributed-chain-building/server (glob)
391 searching for changes
384 searching for changes
392 adding changesets
385 adding changesets
393 adding manifests
386 adding manifests
394 adding file changes
387 adding file changes
395 added 2 changesets with 0 changes to 2 files (+1 heads)
388 added 2 changesets with 0 changes to 2 files (+1 heads)
396 6 new obsolescence markers
389 6 new obsolescence markers
397 obsoleted 2 changesets
390 obsoleted 2 changesets
398 new changesets 9866d64649a5:77ae25d99ff0
391 new changesets 9866d64649a5:77ae25d99ff0
399 (run 'hg heads' to see heads)
392 (run 'hg heads' to see heads)
400 $ hg debugobsolete
393 $ hg debugobsolete
401 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 77ae25d99ff07889e181126b1171b94bec8e5227 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
394 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 77ae25d99ff07889e181126b1171b94bec8e5227 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
402 5b5708a437f27665db42c5a261a539a1bcb2a8c2 9866d64649a5d9c5991fe119c7b2c33898114e10 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
395 5b5708a437f27665db42c5a261a539a1bcb2a8c2 9866d64649a5d9c5991fe119c7b2c33898114e10 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
403 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 956063ac4557828781733b2d5677a351ce856f59 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
396 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 956063ac4557828781733b2d5677a351ce856f59 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
404 956063ac4557828781733b2d5677a351ce856f59 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'celeste'}
397 956063ac4557828781733b2d5677a351ce856f59 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'celeste'}
405 d33b0a3a64647d79583526be8107802b1f9fedfa 5b5708a437f27665db42c5a261a539a1bcb2a8c2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
398 d33b0a3a64647d79583526be8107802b1f9fedfa 5b5708a437f27665db42c5a261a539a1bcb2a8c2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
406 ef908e42ce65ef57f970d799acaddde26f58a4cc 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'bob'}
399 ef908e42ce65ef57f970d799acaddde26f58a4cc 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'bob'}
407
400
408 Then, she pulls from Bob, pulling predecessors of the changeset she has
401 Then, she pulls from Bob, pulling predecessors of the changeset she has
409 already pulled. The changesets are not obsoleted in the Bob repo yet. Their
402 already pulled. The changesets are not obsoleted in the Bob repo yet. Their
410 successors do not exist in Bob repository yet.
403 successors do not exist in Bob repository yet.
411
404
412 $ hg pull ../repo-Bob
405 $ hg pull ../repo-Bob
413 pulling from ../repo-Bob
406 pulling from ../repo-Bob
414 searching for changes
407 searching for changes
415 adding changesets
408 adding changesets
416 adding manifests
409 adding manifests
417 adding file changes
410 adding file changes
418 added 2 changesets with 0 changes to 2 files (+1 heads)
411 added 2 changesets with 0 changes to 2 files (+1 heads)
419 (run 'hg heads' to see heads)
412 (run 'hg heads' to see heads)
420 $ hg log -G
413 $ hg log -G
421 o 4:77ae25d99ff0 c_B2
414 o 4:77ae25d99ff0 c_B2
422 |
415 |
423 o 3:9866d64649a5 c_A2
416 o 3:9866d64649a5 c_A2
424 |
417 |
425 @ 0:e82fb8d02bbf ROOT
418 @ 0:e82fb8d02bbf ROOT
426
419
427 $ hg debugobsolete
420 $ hg debugobsolete
428 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 77ae25d99ff07889e181126b1171b94bec8e5227 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
421 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 77ae25d99ff07889e181126b1171b94bec8e5227 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
429 5b5708a437f27665db42c5a261a539a1bcb2a8c2 9866d64649a5d9c5991fe119c7b2c33898114e10 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
422 5b5708a437f27665db42c5a261a539a1bcb2a8c2 9866d64649a5d9c5991fe119c7b2c33898114e10 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
430 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 956063ac4557828781733b2d5677a351ce856f59 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
423 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 956063ac4557828781733b2d5677a351ce856f59 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
431 956063ac4557828781733b2d5677a351ce856f59 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'celeste'}
424 956063ac4557828781733b2d5677a351ce856f59 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'celeste'}
432 d33b0a3a64647d79583526be8107802b1f9fedfa 5b5708a437f27665db42c5a261a539a1bcb2a8c2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
425 d33b0a3a64647d79583526be8107802b1f9fedfa 5b5708a437f27665db42c5a261a539a1bcb2a8c2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
433 ef908e42ce65ef57f970d799acaddde26f58a4cc 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'bob'}
426 ef908e42ce65ef57f970d799acaddde26f58a4cc 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'bob'}
434
427
435 Same tests, but change coming from a bundle
428 Same tests, but change coming from a bundle
436 (testing with a bundle is interesting because absolutely no discovery or
429 (testing with a bundle is interesting because absolutely no discovery or
437 decision is made in that case, so receiving the changesets are not an option).
430 decision is made in that case, so receiving the changesets are not an option).
438
431
439 $ hg rollback
432 $ hg rollback
440 repository tip rolled back to revision 4 (undo pull)
433 repository tip rolled back to revision 4 (undo pull)
441 $ hg log -G
434 $ hg log -G
442 o 4:77ae25d99ff0 c_B2
435 o 4:77ae25d99ff0 c_B2
443 |
436 |
444 o 3:9866d64649a5 c_A2
437 o 3:9866d64649a5 c_A2
445 |
438 |
446 @ 0:e82fb8d02bbf ROOT
439 @ 0:e82fb8d02bbf ROOT
447
440
448 $ hg debugobsolete
441 $ hg debugobsolete
449 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 77ae25d99ff07889e181126b1171b94bec8e5227 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
442 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 77ae25d99ff07889e181126b1171b94bec8e5227 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
450 5b5708a437f27665db42c5a261a539a1bcb2a8c2 9866d64649a5d9c5991fe119c7b2c33898114e10 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
443 5b5708a437f27665db42c5a261a539a1bcb2a8c2 9866d64649a5d9c5991fe119c7b2c33898114e10 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
451 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 956063ac4557828781733b2d5677a351ce856f59 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
444 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 956063ac4557828781733b2d5677a351ce856f59 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
452 956063ac4557828781733b2d5677a351ce856f59 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'celeste'}
445 956063ac4557828781733b2d5677a351ce856f59 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'celeste'}
453 d33b0a3a64647d79583526be8107802b1f9fedfa 5b5708a437f27665db42c5a261a539a1bcb2a8c2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
446 d33b0a3a64647d79583526be8107802b1f9fedfa 5b5708a437f27665db42c5a261a539a1bcb2a8c2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
454 ef908e42ce65ef57f970d799acaddde26f58a4cc 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'bob'}
447 ef908e42ce65ef57f970d799acaddde26f58a4cc 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'bob'}
455 $ hg -R ../repo-Bob bundle ../step-1.hg
448 $ hg -R ../repo-Bob bundle ../step-1.hg
456 searching for changes
449 searching for changes
457 2 changesets found
450 2 changesets found
458 $ hg unbundle ../step-1.hg
451 $ hg unbundle ../step-1.hg
459 adding changesets
452 adding changesets
460 adding manifests
453 adding manifests
461 adding file changes
454 adding file changes
462 added 2 changesets with 0 changes to 2 files (+1 heads)
455 added 2 changesets with 0 changes to 2 files (+1 heads)
463 (run 'hg heads' to see heads)
456 (run 'hg heads' to see heads)
464 $ hg log -G
457 $ hg log -G
465 o 4:77ae25d99ff0 c_B2
458 o 4:77ae25d99ff0 c_B2
466 |
459 |
467 o 3:9866d64649a5 c_A2
460 o 3:9866d64649a5 c_A2
468 |
461 |
469 @ 0:e82fb8d02bbf ROOT
462 @ 0:e82fb8d02bbf ROOT
470
463
471 $ hg log -G --hidden
464 $ hg log -G --hidden
472 x 6:956063ac4557 c_B1 [rewritten using amend, rebase as 4:77ae25d99ff0 by celeste (at 1970-01-01 00:00 +0000); ]
465 x 6:956063ac4557 c_B1 [rewritten using amend, rebase as 4:77ae25d99ff0 by celeste (at 1970-01-01 00:00 +0000)]
473 |
466 |
474 x 5:5b5708a437f2 c_A1 [rewritten using amend as 3:9866d64649a5 by celeste (at 1970-01-01 00:00 +0000); ]
467 x 5:5b5708a437f2 c_A1 [rewritten using amend as 3:9866d64649a5 by celeste (at 1970-01-01 00:00 +0000)]
475 |
468 |
476 | o 4:77ae25d99ff0 c_B2
469 | o 4:77ae25d99ff0 c_B2
477 | |
470 | |
478 | o 3:9866d64649a5 c_A2
471 | o 3:9866d64649a5 c_A2
479 |/
472 |/
480 | x 2:ef908e42ce65 c_B0 [rewritten using amend, rebase as 6:956063ac4557 by bob (at 1970-01-01 00:00 +0000); ]
473 | x 2:ef908e42ce65 c_B0 [rewritten using amend, rebase as 6:956063ac4557 by bob (at 1970-01-01 00:00 +0000)]
481 | |
474 | |
482 | x 1:d33b0a3a6464 c_A0 [rewritten using amend as 5:5b5708a437f2 by bob (at 1970-01-01 00:00 +0000); ]
475 | x 1:d33b0a3a6464 c_A0 [rewritten using amend as 5:5b5708a437f2 by bob (at 1970-01-01 00:00 +0000)]
483 |/
476 |/
484 @ 0:e82fb8d02bbf ROOT
477 @ 0:e82fb8d02bbf ROOT
485
478
486 $ hg debugobsolete
479 $ hg debugobsolete
487 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 77ae25d99ff07889e181126b1171b94bec8e5227 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
480 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 77ae25d99ff07889e181126b1171b94bec8e5227 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
488 5b5708a437f27665db42c5a261a539a1bcb2a8c2 9866d64649a5d9c5991fe119c7b2c33898114e10 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
481 5b5708a437f27665db42c5a261a539a1bcb2a8c2 9866d64649a5d9c5991fe119c7b2c33898114e10 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'celeste'}
489 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 956063ac4557828781733b2d5677a351ce856f59 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
482 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 956063ac4557828781733b2d5677a351ce856f59 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
490 956063ac4557828781733b2d5677a351ce856f59 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'celeste'}
483 956063ac4557828781733b2d5677a351ce856f59 3cf8de21cc2282186857d2266eb6b1f9cb85ecf3 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'celeste'}
491 d33b0a3a64647d79583526be8107802b1f9fedfa 5b5708a437f27665db42c5a261a539a1bcb2a8c2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
484 d33b0a3a64647d79583526be8107802b1f9fedfa 5b5708a437f27665db42c5a261a539a1bcb2a8c2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'bob'}
492 ef908e42ce65ef57f970d799acaddde26f58a4cc 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'bob'}
485 ef908e42ce65ef57f970d799acaddde26f58a4cc 5ffb9e311b35f6ab6f76f667ca5d6e595645481b 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'rebase', 'user': 'bob'}
493
486
494 $ cd ..
487 $ cd ..
@@ -1,685 +1,685
1 Test file dedicated to testing the divergent troubles from obsolete changeset.
1 Test file dedicated to testing the divergent troubles from obsolete changeset.
2
2
3 This is the most complex troubles from far so we isolate it in a dedicated
3 This is the most complex troubles from far so we isolate it in a dedicated
4 file.
4 file.
5
5
6 Enable obsolete
6 Enable obsolete
7
7
8 $ cat >> $HGRCPATH << EOF
8 $ cat >> $HGRCPATH << EOF
9 > [ui]
9 > [ui]
10 > logtemplate = {rev}:{node|short} {desc}\n
10 > logtemplate = {rev}:{node|short} {desc}{if(obsfate, " [{join(obsfate, "; ")}]")}\n
11 > [experimental]
11 > [experimental]
12 > stabilization=createmarkers
12 > stabilization=createmarkers
13 > [extensions]
13 > [extensions]
14 > drawdag=$TESTDIR/drawdag.py
14 > drawdag=$TESTDIR/drawdag.py
15 > [alias]
15 > [alias]
16 > debugobsolete = debugobsolete -d '0 0'
16 > debugobsolete = debugobsolete -d '0 0'
17 > [phases]
17 > [phases]
18 > publish=False
18 > publish=False
19 > EOF
19 > EOF
20
20
21
21
22 $ mkcommit() {
22 $ mkcommit() {
23 > echo "$1" > "$1"
23 > echo "$1" > "$1"
24 > hg add "$1"
24 > hg add "$1"
25 > hg ci -m "$1"
25 > hg ci -m "$1"
26 > }
26 > }
27 $ getid() {
27 $ getid() {
28 > hg log --hidden -r "desc('$1')" -T '{node}\n'
28 > hg log --hidden -r "desc('$1')" -T '{node}\n'
29 > }
29 > }
30
30
31 setup repo
31 setup repo
32
32
33 $ hg init reference
33 $ hg init reference
34 $ cd reference
34 $ cd reference
35 $ mkcommit base
35 $ mkcommit base
36 $ mkcommit A_0
36 $ mkcommit A_0
37 $ hg up 0
37 $ hg up 0
38 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
38 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
39 $ mkcommit A_1
39 $ mkcommit A_1
40 created new head
40 created new head
41 $ hg up 0
41 $ hg up 0
42 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
42 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
43 $ mkcommit A_2
43 $ mkcommit A_2
44 created new head
44 created new head
45 $ hg up 0
45 $ hg up 0
46 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
46 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
47 $ cd ..
47 $ cd ..
48
48
49
49
50 $ newcase() {
50 $ newcase() {
51 > hg clone -u 0 -q reference $1
51 > hg clone -u 0 -q reference $1
52 > cd $1
52 > cd $1
53 > }
53 > }
54
54
55 direct divergence
55 direct divergence
56 -----------------
56 -----------------
57
57
58 A_1 have two direct and divergent successors A_1 and A_1
58 A_1 have two direct and divergent successors A_1 and A_1
59
59
60 $ newcase direct
60 $ newcase direct
61 $ hg debugobsolete `getid A_0` `getid A_1`
61 $ hg debugobsolete `getid A_0` `getid A_1`
62 obsoleted 1 changesets
62 obsoleted 1 changesets
63 $ hg debugobsolete `getid A_0` `getid A_2`
63 $ hg debugobsolete `getid A_0` `getid A_2`
64 $ hg log -G --hidden
64 $ hg log -G --hidden
65 o 3:392fd25390da A_2
65 o 3:392fd25390da A_2
66 |
66 |
67 | o 2:82623d38b9ba A_1
67 | o 2:82623d38b9ba A_1
68 |/
68 |/
69 | x 1:007dc284c1f8 A_0
69 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba by test (at 1970-01-01 00:00 +0000); rewritten as 3:392fd25390da by test (at 1970-01-01 00:00 +0000)]
70 |/
70 |/
71 @ 0:d20a80d4def3 base
71 @ 0:d20a80d4def3 base
72
72
73 $ hg debugsuccessorssets --hidden 'all()'
73 $ hg debugsuccessorssets --hidden 'all()'
74 d20a80d4def3
74 d20a80d4def3
75 d20a80d4def3
75 d20a80d4def3
76 007dc284c1f8
76 007dc284c1f8
77 82623d38b9ba
77 82623d38b9ba
78 392fd25390da
78 392fd25390da
79 82623d38b9ba
79 82623d38b9ba
80 82623d38b9ba
80 82623d38b9ba
81 392fd25390da
81 392fd25390da
82 392fd25390da
82 392fd25390da
83 $ hg log -r 'contentdivergent()'
83 $ hg log -r 'contentdivergent()'
84 2:82623d38b9ba A_1
84 2:82623d38b9ba A_1
85 3:392fd25390da A_2
85 3:392fd25390da A_2
86 $ hg debugsuccessorssets 'all()' --closest
86 $ hg debugsuccessorssets 'all()' --closest
87 d20a80d4def3
87 d20a80d4def3
88 d20a80d4def3
88 d20a80d4def3
89 82623d38b9ba
89 82623d38b9ba
90 82623d38b9ba
90 82623d38b9ba
91 392fd25390da
91 392fd25390da
92 392fd25390da
92 392fd25390da
93 $ hg debugsuccessorssets 'all()' --closest --hidden
93 $ hg debugsuccessorssets 'all()' --closest --hidden
94 d20a80d4def3
94 d20a80d4def3
95 d20a80d4def3
95 d20a80d4def3
96 007dc284c1f8
96 007dc284c1f8
97 82623d38b9ba
97 82623d38b9ba
98 392fd25390da
98 392fd25390da
99 82623d38b9ba
99 82623d38b9ba
100 82623d38b9ba
100 82623d38b9ba
101 392fd25390da
101 392fd25390da
102 392fd25390da
102 392fd25390da
103
103
104 check that mercurial refuse to push
104 check that mercurial refuse to push
105
105
106 $ hg init ../other
106 $ hg init ../other
107 $ hg push ../other
107 $ hg push ../other
108 pushing to ../other
108 pushing to ../other
109 searching for changes
109 searching for changes
110 abort: push includes content-divergent changeset: 392fd25390da!
110 abort: push includes content-divergent changeset: 392fd25390da!
111 [255]
111 [255]
112
112
113 $ cd ..
113 $ cd ..
114
114
115
115
116 indirect divergence with known changeset
116 indirect divergence with known changeset
117 -------------------------------------------
117 -------------------------------------------
118
118
119 $ newcase indirect_known
119 $ newcase indirect_known
120 $ hg debugobsolete `getid A_0` `getid A_1`
120 $ hg debugobsolete `getid A_0` `getid A_1`
121 obsoleted 1 changesets
121 obsoleted 1 changesets
122 $ hg debugobsolete `getid A_0` `getid A_2`
122 $ hg debugobsolete `getid A_0` `getid A_2`
123 $ mkcommit A_3
123 $ mkcommit A_3
124 created new head
124 created new head
125 $ hg debugobsolete `getid A_2` `getid A_3`
125 $ hg debugobsolete `getid A_2` `getid A_3`
126 obsoleted 1 changesets
126 obsoleted 1 changesets
127 $ hg log -G --hidden
127 $ hg log -G --hidden
128 @ 4:01f36c5a8fda A_3
128 @ 4:01f36c5a8fda A_3
129 |
129 |
130 | x 3:392fd25390da A_2
130 | x 3:392fd25390da A_2 [rewritten as 4:01f36c5a8fda by test (at 1970-01-01 00:00 +0000)]
131 |/
131 |/
132 | o 2:82623d38b9ba A_1
132 | o 2:82623d38b9ba A_1
133 |/
133 |/
134 | x 1:007dc284c1f8 A_0
134 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba by test (at 1970-01-01 00:00 +0000); rewritten as 3:392fd25390da by test (at 1970-01-01 00:00 +0000)]
135 |/
135 |/
136 o 0:d20a80d4def3 base
136 o 0:d20a80d4def3 base
137
137
138 $ hg debugsuccessorssets --hidden 'all()'
138 $ hg debugsuccessorssets --hidden 'all()'
139 d20a80d4def3
139 d20a80d4def3
140 d20a80d4def3
140 d20a80d4def3
141 007dc284c1f8
141 007dc284c1f8
142 82623d38b9ba
142 82623d38b9ba
143 01f36c5a8fda
143 01f36c5a8fda
144 82623d38b9ba
144 82623d38b9ba
145 82623d38b9ba
145 82623d38b9ba
146 392fd25390da
146 392fd25390da
147 01f36c5a8fda
147 01f36c5a8fda
148 01f36c5a8fda
148 01f36c5a8fda
149 01f36c5a8fda
149 01f36c5a8fda
150 $ hg log -r 'contentdivergent()'
150 $ hg log -r 'contentdivergent()'
151 2:82623d38b9ba A_1
151 2:82623d38b9ba A_1
152 4:01f36c5a8fda A_3
152 4:01f36c5a8fda A_3
153 $ hg debugsuccessorssets 'all()' --closest
153 $ hg debugsuccessorssets 'all()' --closest
154 d20a80d4def3
154 d20a80d4def3
155 d20a80d4def3
155 d20a80d4def3
156 82623d38b9ba
156 82623d38b9ba
157 82623d38b9ba
157 82623d38b9ba
158 01f36c5a8fda
158 01f36c5a8fda
159 01f36c5a8fda
159 01f36c5a8fda
160 $ hg debugsuccessorssets 'all()' --closest --hidden
160 $ hg debugsuccessorssets 'all()' --closest --hidden
161 d20a80d4def3
161 d20a80d4def3
162 d20a80d4def3
162 d20a80d4def3
163 007dc284c1f8
163 007dc284c1f8
164 82623d38b9ba
164 82623d38b9ba
165 392fd25390da
165 392fd25390da
166 82623d38b9ba
166 82623d38b9ba
167 82623d38b9ba
167 82623d38b9ba
168 392fd25390da
168 392fd25390da
169 392fd25390da
169 392fd25390da
170 01f36c5a8fda
170 01f36c5a8fda
171 01f36c5a8fda
171 01f36c5a8fda
172 $ cd ..
172 $ cd ..
173
173
174
174
175 indirect divergence with known changeset
175 indirect divergence with known changeset
176 -------------------------------------------
176 -------------------------------------------
177
177
178 $ newcase indirect_unknown
178 $ newcase indirect_unknown
179 $ hg debugobsolete `getid A_0` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
179 $ hg debugobsolete `getid A_0` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
180 obsoleted 1 changesets
180 obsoleted 1 changesets
181 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid A_1`
181 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid A_1`
182 $ hg debugobsolete `getid A_0` `getid A_2`
182 $ hg debugobsolete `getid A_0` `getid A_2`
183 $ hg log -G --hidden
183 $ hg log -G --hidden
184 o 3:392fd25390da A_2
184 o 3:392fd25390da A_2
185 |
185 |
186 | o 2:82623d38b9ba A_1
186 | o 2:82623d38b9ba A_1
187 |/
187 |/
188 | x 1:007dc284c1f8 A_0
188 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba by test (at 1970-01-01 00:00 +0000); rewritten as 3:392fd25390da by test (at 1970-01-01 00:00 +0000)]
189 |/
189 |/
190 @ 0:d20a80d4def3 base
190 @ 0:d20a80d4def3 base
191
191
192 $ hg debugsuccessorssets --hidden 'all()'
192 $ hg debugsuccessorssets --hidden 'all()'
193 d20a80d4def3
193 d20a80d4def3
194 d20a80d4def3
194 d20a80d4def3
195 007dc284c1f8
195 007dc284c1f8
196 82623d38b9ba
196 82623d38b9ba
197 392fd25390da
197 392fd25390da
198 82623d38b9ba
198 82623d38b9ba
199 82623d38b9ba
199 82623d38b9ba
200 392fd25390da
200 392fd25390da
201 392fd25390da
201 392fd25390da
202 $ hg log -r 'contentdivergent()'
202 $ hg log -r 'contentdivergent()'
203 2:82623d38b9ba A_1
203 2:82623d38b9ba A_1
204 3:392fd25390da A_2
204 3:392fd25390da A_2
205 $ hg debugsuccessorssets 'all()' --closest
205 $ hg debugsuccessorssets 'all()' --closest
206 d20a80d4def3
206 d20a80d4def3
207 d20a80d4def3
207 d20a80d4def3
208 82623d38b9ba
208 82623d38b9ba
209 82623d38b9ba
209 82623d38b9ba
210 392fd25390da
210 392fd25390da
211 392fd25390da
211 392fd25390da
212 $ hg debugsuccessorssets 'all()' --closest --hidden
212 $ hg debugsuccessorssets 'all()' --closest --hidden
213 d20a80d4def3
213 d20a80d4def3
214 d20a80d4def3
214 d20a80d4def3
215 007dc284c1f8
215 007dc284c1f8
216 82623d38b9ba
216 82623d38b9ba
217 392fd25390da
217 392fd25390da
218 82623d38b9ba
218 82623d38b9ba
219 82623d38b9ba
219 82623d38b9ba
220 392fd25390da
220 392fd25390da
221 392fd25390da
221 392fd25390da
222 $ cd ..
222 $ cd ..
223
223
224 do not take unknown node in account if they are final
224 do not take unknown node in account if they are final
225 -----------------------------------------------------
225 -----------------------------------------------------
226
226
227 $ newcase final-unknown
227 $ newcase final-unknown
228 $ hg debugobsolete `getid A_0` `getid A_1`
228 $ hg debugobsolete `getid A_0` `getid A_1`
229 obsoleted 1 changesets
229 obsoleted 1 changesets
230 $ hg debugobsolete `getid A_1` `getid A_2`
230 $ hg debugobsolete `getid A_1` `getid A_2`
231 obsoleted 1 changesets
231 obsoleted 1 changesets
232 $ hg debugobsolete `getid A_0` bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
232 $ hg debugobsolete `getid A_0` bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
233 $ hg debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccccccccccc
233 $ hg debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccccccccccc
234 $ hg debugobsolete `getid A_1` dddddddddddddddddddddddddddddddddddddddd
234 $ hg debugobsolete `getid A_1` dddddddddddddddddddddddddddddddddddddddd
235
235
236 $ hg debugsuccessorssets --hidden 'desc('A_0')'
236 $ hg debugsuccessorssets --hidden 'desc('A_0')'
237 007dc284c1f8
237 007dc284c1f8
238 392fd25390da
238 392fd25390da
239 $ hg debugsuccessorssets 'desc('A_0')' --closest
239 $ hg debugsuccessorssets 'desc('A_0')' --closest
240 $ hg debugsuccessorssets 'desc('A_0')' --closest --hidden
240 $ hg debugsuccessorssets 'desc('A_0')' --closest --hidden
241 007dc284c1f8
241 007dc284c1f8
242 82623d38b9ba
242 82623d38b9ba
243
243
244 $ cd ..
244 $ cd ..
245
245
246 divergence that converge again is not divergence anymore
246 divergence that converge again is not divergence anymore
247 -----------------------------------------------------
247 -----------------------------------------------------
248
248
249 $ newcase converged_divergence
249 $ newcase converged_divergence
250 $ hg debugobsolete `getid A_0` `getid A_1`
250 $ hg debugobsolete `getid A_0` `getid A_1`
251 obsoleted 1 changesets
251 obsoleted 1 changesets
252 $ hg debugobsolete `getid A_0` `getid A_2`
252 $ hg debugobsolete `getid A_0` `getid A_2`
253 $ mkcommit A_3
253 $ mkcommit A_3
254 created new head
254 created new head
255 $ hg debugobsolete `getid A_1` `getid A_3`
255 $ hg debugobsolete `getid A_1` `getid A_3`
256 obsoleted 1 changesets
256 obsoleted 1 changesets
257 $ hg debugobsolete `getid A_2` `getid A_3`
257 $ hg debugobsolete `getid A_2` `getid A_3`
258 obsoleted 1 changesets
258 obsoleted 1 changesets
259 $ hg log -G --hidden
259 $ hg log -G --hidden
260 @ 4:01f36c5a8fda A_3
260 @ 4:01f36c5a8fda A_3
261 |
261 |
262 | x 3:392fd25390da A_2
262 | x 3:392fd25390da A_2 [rewritten as 4:01f36c5a8fda by test (at 1970-01-01 00:00 +0000)]
263 |/
263 |/
264 | x 2:82623d38b9ba A_1
264 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda by test (at 1970-01-01 00:00 +0000)]
265 |/
265 |/
266 | x 1:007dc284c1f8 A_0
266 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba by test (at 1970-01-01 00:00 +0000); rewritten as 3:392fd25390da by test (at 1970-01-01 00:00 +0000)]
267 |/
267 |/
268 o 0:d20a80d4def3 base
268 o 0:d20a80d4def3 base
269
269
270 $ hg debugsuccessorssets --hidden 'all()'
270 $ hg debugsuccessorssets --hidden 'all()'
271 d20a80d4def3
271 d20a80d4def3
272 d20a80d4def3
272 d20a80d4def3
273 007dc284c1f8
273 007dc284c1f8
274 01f36c5a8fda
274 01f36c5a8fda
275 82623d38b9ba
275 82623d38b9ba
276 01f36c5a8fda
276 01f36c5a8fda
277 392fd25390da
277 392fd25390da
278 01f36c5a8fda
278 01f36c5a8fda
279 01f36c5a8fda
279 01f36c5a8fda
280 01f36c5a8fda
280 01f36c5a8fda
281 $ hg log -r 'contentdivergent()'
281 $ hg log -r 'contentdivergent()'
282 $ hg debugsuccessorssets 'all()' --closest
282 $ hg debugsuccessorssets 'all()' --closest
283 d20a80d4def3
283 d20a80d4def3
284 d20a80d4def3
284 d20a80d4def3
285 01f36c5a8fda
285 01f36c5a8fda
286 01f36c5a8fda
286 01f36c5a8fda
287 $ hg debugsuccessorssets 'all()' --closest --hidden
287 $ hg debugsuccessorssets 'all()' --closest --hidden
288 d20a80d4def3
288 d20a80d4def3
289 d20a80d4def3
289 d20a80d4def3
290 007dc284c1f8
290 007dc284c1f8
291 82623d38b9ba
291 82623d38b9ba
292 392fd25390da
292 392fd25390da
293 82623d38b9ba
293 82623d38b9ba
294 82623d38b9ba
294 82623d38b9ba
295 392fd25390da
295 392fd25390da
296 392fd25390da
296 392fd25390da
297 01f36c5a8fda
297 01f36c5a8fda
298 01f36c5a8fda
298 01f36c5a8fda
299 $ cd ..
299 $ cd ..
300
300
301 split is not divergences
301 split is not divergences
302 -----------------------------
302 -----------------------------
303
303
304 $ newcase split
304 $ newcase split
305 $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
305 $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
306 obsoleted 1 changesets
306 obsoleted 1 changesets
307 $ hg log -G --hidden
307 $ hg log -G --hidden
308 o 3:392fd25390da A_2
308 o 3:392fd25390da A_2
309 |
309 |
310 | o 2:82623d38b9ba A_1
310 | o 2:82623d38b9ba A_1
311 |/
311 |/
312 | x 1:007dc284c1f8 A_0
312 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da by test (at 1970-01-01 00:00 +0000)]
313 |/
313 |/
314 @ 0:d20a80d4def3 base
314 @ 0:d20a80d4def3 base
315
315
316 $ hg debugsuccessorssets --hidden 'all()'
316 $ hg debugsuccessorssets --hidden 'all()'
317 d20a80d4def3
317 d20a80d4def3
318 d20a80d4def3
318 d20a80d4def3
319 007dc284c1f8
319 007dc284c1f8
320 82623d38b9ba 392fd25390da
320 82623d38b9ba 392fd25390da
321 82623d38b9ba
321 82623d38b9ba
322 82623d38b9ba
322 82623d38b9ba
323 392fd25390da
323 392fd25390da
324 392fd25390da
324 392fd25390da
325 $ hg log -r 'contentdivergent()'
325 $ hg log -r 'contentdivergent()'
326 $ hg debugsuccessorssets 'all()' --closest
326 $ hg debugsuccessorssets 'all()' --closest
327 d20a80d4def3
327 d20a80d4def3
328 d20a80d4def3
328 d20a80d4def3
329 82623d38b9ba
329 82623d38b9ba
330 82623d38b9ba
330 82623d38b9ba
331 392fd25390da
331 392fd25390da
332 392fd25390da
332 392fd25390da
333 $ hg debugsuccessorssets 'all()' --closest --hidden
333 $ hg debugsuccessorssets 'all()' --closest --hidden
334 d20a80d4def3
334 d20a80d4def3
335 d20a80d4def3
335 d20a80d4def3
336 007dc284c1f8
336 007dc284c1f8
337 82623d38b9ba 392fd25390da
337 82623d38b9ba 392fd25390da
338 82623d38b9ba
338 82623d38b9ba
339 82623d38b9ba
339 82623d38b9ba
340 392fd25390da
340 392fd25390da
341 392fd25390da
341 392fd25390da
342
342
343 Even when subsequent rewriting happen
343 Even when subsequent rewriting happen
344
344
345 $ mkcommit A_3
345 $ mkcommit A_3
346 created new head
346 created new head
347 $ hg debugobsolete `getid A_1` `getid A_3`
347 $ hg debugobsolete `getid A_1` `getid A_3`
348 obsoleted 1 changesets
348 obsoleted 1 changesets
349 $ hg up 0
349 $ hg up 0
350 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
350 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
351 $ mkcommit A_4
351 $ mkcommit A_4
352 created new head
352 created new head
353 $ hg debugobsolete `getid A_2` `getid A_4`
353 $ hg debugobsolete `getid A_2` `getid A_4`
354 obsoleted 1 changesets
354 obsoleted 1 changesets
355 $ hg up 0
355 $ hg up 0
356 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
356 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
357 $ mkcommit A_5
357 $ mkcommit A_5
358 created new head
358 created new head
359 $ hg debugobsolete `getid A_4` `getid A_5`
359 $ hg debugobsolete `getid A_4` `getid A_5`
360 obsoleted 1 changesets
360 obsoleted 1 changesets
361 $ hg log -G --hidden
361 $ hg log -G --hidden
362 @ 6:e442cfc57690 A_5
362 @ 6:e442cfc57690 A_5
363 |
363 |
364 | x 5:6a411f0d7a0a A_4
364 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690 by test (at 1970-01-01 00:00 +0000)]
365 |/
365 |/
366 | o 4:01f36c5a8fda A_3
366 | o 4:01f36c5a8fda A_3
367 |/
367 |/
368 | x 3:392fd25390da A_2
368 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a by test (at 1970-01-01 00:00 +0000)]
369 |/
369 |/
370 | x 2:82623d38b9ba A_1
370 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda by test (at 1970-01-01 00:00 +0000)]
371 |/
371 |/
372 | x 1:007dc284c1f8 A_0
372 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da by test (at 1970-01-01 00:00 +0000)]
373 |/
373 |/
374 o 0:d20a80d4def3 base
374 o 0:d20a80d4def3 base
375
375
376 $ hg debugsuccessorssets --hidden 'all()'
376 $ hg debugsuccessorssets --hidden 'all()'
377 d20a80d4def3
377 d20a80d4def3
378 d20a80d4def3
378 d20a80d4def3
379 007dc284c1f8
379 007dc284c1f8
380 01f36c5a8fda e442cfc57690
380 01f36c5a8fda e442cfc57690
381 82623d38b9ba
381 82623d38b9ba
382 01f36c5a8fda
382 01f36c5a8fda
383 392fd25390da
383 392fd25390da
384 e442cfc57690
384 e442cfc57690
385 01f36c5a8fda
385 01f36c5a8fda
386 01f36c5a8fda
386 01f36c5a8fda
387 6a411f0d7a0a
387 6a411f0d7a0a
388 e442cfc57690
388 e442cfc57690
389 e442cfc57690
389 e442cfc57690
390 e442cfc57690
390 e442cfc57690
391 $ hg debugsuccessorssets 'all()' --closest
391 $ hg debugsuccessorssets 'all()' --closest
392 d20a80d4def3
392 d20a80d4def3
393 d20a80d4def3
393 d20a80d4def3
394 01f36c5a8fda
394 01f36c5a8fda
395 01f36c5a8fda
395 01f36c5a8fda
396 e442cfc57690
396 e442cfc57690
397 e442cfc57690
397 e442cfc57690
398 $ hg debugsuccessorssets 'all()' --closest --hidden
398 $ hg debugsuccessorssets 'all()' --closest --hidden
399 d20a80d4def3
399 d20a80d4def3
400 d20a80d4def3
400 d20a80d4def3
401 007dc284c1f8
401 007dc284c1f8
402 82623d38b9ba 392fd25390da
402 82623d38b9ba 392fd25390da
403 82623d38b9ba
403 82623d38b9ba
404 82623d38b9ba
404 82623d38b9ba
405 392fd25390da
405 392fd25390da
406 392fd25390da
406 392fd25390da
407 01f36c5a8fda
407 01f36c5a8fda
408 01f36c5a8fda
408 01f36c5a8fda
409 6a411f0d7a0a
409 6a411f0d7a0a
410 e442cfc57690
410 e442cfc57690
411 e442cfc57690
411 e442cfc57690
412 e442cfc57690
412 e442cfc57690
413 $ hg log -r 'contentdivergent()'
413 $ hg log -r 'contentdivergent()'
414
414
415 Check more complex obsolescence graft (with divergence)
415 Check more complex obsolescence graft (with divergence)
416
416
417 $ mkcommit B_0; hg up 0
417 $ mkcommit B_0; hg up 0
418 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
418 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
419 $ hg debugobsolete `getid B_0` `getid A_2`
419 $ hg debugobsolete `getid B_0` `getid A_2`
420 obsoleted 1 changesets
420 obsoleted 1 changesets
421 $ mkcommit A_7; hg up 0
421 $ mkcommit A_7; hg up 0
422 created new head
422 created new head
423 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
423 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
424 $ mkcommit A_8; hg up 0
424 $ mkcommit A_8; hg up 0
425 created new head
425 created new head
426 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
426 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
427 $ hg debugobsolete `getid A_5` `getid A_7` `getid A_8`
427 $ hg debugobsolete `getid A_5` `getid A_7` `getid A_8`
428 obsoleted 1 changesets
428 obsoleted 1 changesets
429 $ mkcommit A_9; hg up 0
429 $ mkcommit A_9; hg up 0
430 created new head
430 created new head
431 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
431 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
432 $ hg debugobsolete `getid A_5` `getid A_9`
432 $ hg debugobsolete `getid A_5` `getid A_9`
433 $ hg log -G --hidden
433 $ hg log -G --hidden
434 o 10:bed64f5d2f5a A_9
434 o 10:bed64f5d2f5a A_9
435 |
435 |
436 | o 9:14608b260df8 A_8
436 | o 9:14608b260df8 A_8
437 |/
437 |/
438 | o 8:7ae126973a96 A_7
438 | o 8:7ae126973a96 A_7
439 |/
439 |/
440 | x 7:3750ebee865d B_0
440 | x 7:3750ebee865d B_0 [rewritten as 3:392fd25390da by test (at 1970-01-01 00:00 +0000)]
441 | |
441 | |
442 | x 6:e442cfc57690 A_5
442 | x 6:e442cfc57690 A_5 [rewritten as 10:bed64f5d2f5a by test (at 1970-01-01 00:00 +0000); split as 8:7ae126973a96, 9:14608b260df8 by test (at 1970-01-01 00:00 +0000)]
443 |/
443 |/
444 | x 5:6a411f0d7a0a A_4
444 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690 by test (at 1970-01-01 00:00 +0000)]
445 |/
445 |/
446 | o 4:01f36c5a8fda A_3
446 | o 4:01f36c5a8fda A_3
447 |/
447 |/
448 | x 3:392fd25390da A_2
448 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a by test (at 1970-01-01 00:00 +0000)]
449 |/
449 |/
450 | x 2:82623d38b9ba A_1
450 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda by test (at 1970-01-01 00:00 +0000)]
451 |/
451 |/
452 | x 1:007dc284c1f8 A_0
452 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da by test (at 1970-01-01 00:00 +0000)]
453 |/
453 |/
454 @ 0:d20a80d4def3 base
454 @ 0:d20a80d4def3 base
455
455
456 $ hg debugsuccessorssets --hidden 'all()'
456 $ hg debugsuccessorssets --hidden 'all()'
457 d20a80d4def3
457 d20a80d4def3
458 d20a80d4def3
458 d20a80d4def3
459 007dc284c1f8
459 007dc284c1f8
460 01f36c5a8fda bed64f5d2f5a
460 01f36c5a8fda bed64f5d2f5a
461 01f36c5a8fda 7ae126973a96 14608b260df8
461 01f36c5a8fda 7ae126973a96 14608b260df8
462 82623d38b9ba
462 82623d38b9ba
463 01f36c5a8fda
463 01f36c5a8fda
464 392fd25390da
464 392fd25390da
465 bed64f5d2f5a
465 bed64f5d2f5a
466 7ae126973a96 14608b260df8
466 7ae126973a96 14608b260df8
467 01f36c5a8fda
467 01f36c5a8fda
468 01f36c5a8fda
468 01f36c5a8fda
469 6a411f0d7a0a
469 6a411f0d7a0a
470 bed64f5d2f5a
470 bed64f5d2f5a
471 7ae126973a96 14608b260df8
471 7ae126973a96 14608b260df8
472 e442cfc57690
472 e442cfc57690
473 bed64f5d2f5a
473 bed64f5d2f5a
474 7ae126973a96 14608b260df8
474 7ae126973a96 14608b260df8
475 3750ebee865d
475 3750ebee865d
476 bed64f5d2f5a
476 bed64f5d2f5a
477 7ae126973a96 14608b260df8
477 7ae126973a96 14608b260df8
478 7ae126973a96
478 7ae126973a96
479 7ae126973a96
479 7ae126973a96
480 14608b260df8
480 14608b260df8
481 14608b260df8
481 14608b260df8
482 bed64f5d2f5a
482 bed64f5d2f5a
483 bed64f5d2f5a
483 bed64f5d2f5a
484 $ hg debugsuccessorssets 'all()' --closest
484 $ hg debugsuccessorssets 'all()' --closest
485 d20a80d4def3
485 d20a80d4def3
486 d20a80d4def3
486 d20a80d4def3
487 01f36c5a8fda
487 01f36c5a8fda
488 01f36c5a8fda
488 01f36c5a8fda
489 7ae126973a96
489 7ae126973a96
490 7ae126973a96
490 7ae126973a96
491 14608b260df8
491 14608b260df8
492 14608b260df8
492 14608b260df8
493 bed64f5d2f5a
493 bed64f5d2f5a
494 bed64f5d2f5a
494 bed64f5d2f5a
495 $ hg debugsuccessorssets 'all()' --closest --hidden
495 $ hg debugsuccessorssets 'all()' --closest --hidden
496 d20a80d4def3
496 d20a80d4def3
497 d20a80d4def3
497 d20a80d4def3
498 007dc284c1f8
498 007dc284c1f8
499 82623d38b9ba 392fd25390da
499 82623d38b9ba 392fd25390da
500 82623d38b9ba
500 82623d38b9ba
501 82623d38b9ba
501 82623d38b9ba
502 392fd25390da
502 392fd25390da
503 392fd25390da
503 392fd25390da
504 01f36c5a8fda
504 01f36c5a8fda
505 01f36c5a8fda
505 01f36c5a8fda
506 6a411f0d7a0a
506 6a411f0d7a0a
507 e442cfc57690
507 e442cfc57690
508 e442cfc57690
508 e442cfc57690
509 e442cfc57690
509 e442cfc57690
510 3750ebee865d
510 3750ebee865d
511 392fd25390da
511 392fd25390da
512 7ae126973a96
512 7ae126973a96
513 7ae126973a96
513 7ae126973a96
514 14608b260df8
514 14608b260df8
515 14608b260df8
515 14608b260df8
516 bed64f5d2f5a
516 bed64f5d2f5a
517 bed64f5d2f5a
517 bed64f5d2f5a
518 $ hg log -r 'contentdivergent()'
518 $ hg log -r 'contentdivergent()'
519 4:01f36c5a8fda A_3
519 4:01f36c5a8fda A_3
520 8:7ae126973a96 A_7
520 8:7ae126973a96 A_7
521 9:14608b260df8 A_8
521 9:14608b260df8 A_8
522 10:bed64f5d2f5a A_9
522 10:bed64f5d2f5a A_9
523
523
524 fix the divergence
524 fix the divergence
525
525
526 $ mkcommit A_A; hg up 0
526 $ mkcommit A_A; hg up 0
527 created new head
527 created new head
528 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
528 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
529 $ hg debugobsolete `getid A_9` `getid A_A`
529 $ hg debugobsolete `getid A_9` `getid A_A`
530 obsoleted 1 changesets
530 obsoleted 1 changesets
531 $ hg debugobsolete `getid A_7` `getid A_A`
531 $ hg debugobsolete `getid A_7` `getid A_A`
532 obsoleted 1 changesets
532 obsoleted 1 changesets
533 $ hg debugobsolete `getid A_8` `getid A_A`
533 $ hg debugobsolete `getid A_8` `getid A_A`
534 obsoleted 1 changesets
534 obsoleted 1 changesets
535 $ hg log -G --hidden
535 $ hg log -G --hidden
536 o 11:a139f71be9da A_A
536 o 11:a139f71be9da A_A
537 |
537 |
538 | x 10:bed64f5d2f5a A_9
538 | x 10:bed64f5d2f5a A_9 [rewritten as 11:a139f71be9da by test (at 1970-01-01 00:00 +0000)]
539 |/
539 |/
540 | x 9:14608b260df8 A_8
540 | x 9:14608b260df8 A_8 [rewritten as 11:a139f71be9da by test (at 1970-01-01 00:00 +0000)]
541 |/
541 |/
542 | x 8:7ae126973a96 A_7
542 | x 8:7ae126973a96 A_7 [rewritten as 11:a139f71be9da by test (at 1970-01-01 00:00 +0000)]
543 |/
543 |/
544 | x 7:3750ebee865d B_0
544 | x 7:3750ebee865d B_0 [rewritten as 3:392fd25390da by test (at 1970-01-01 00:00 +0000)]
545 | |
545 | |
546 | x 6:e442cfc57690 A_5
546 | x 6:e442cfc57690 A_5 [rewritten as 10:bed64f5d2f5a by test (at 1970-01-01 00:00 +0000); split as 8:7ae126973a96, 9:14608b260df8 by test (at 1970-01-01 00:00 +0000)]
547 |/
547 |/
548 | x 5:6a411f0d7a0a A_4
548 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690 by test (at 1970-01-01 00:00 +0000)]
549 |/
549 |/
550 | o 4:01f36c5a8fda A_3
550 | o 4:01f36c5a8fda A_3
551 |/
551 |/
552 | x 3:392fd25390da A_2
552 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a by test (at 1970-01-01 00:00 +0000)]
553 |/
553 |/
554 | x 2:82623d38b9ba A_1
554 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda by test (at 1970-01-01 00:00 +0000)]
555 |/
555 |/
556 | x 1:007dc284c1f8 A_0
556 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da by test (at 1970-01-01 00:00 +0000)]
557 |/
557 |/
558 @ 0:d20a80d4def3 base
558 @ 0:d20a80d4def3 base
559
559
560 $ hg debugsuccessorssets --hidden 'all()'
560 $ hg debugsuccessorssets --hidden 'all()'
561 d20a80d4def3
561 d20a80d4def3
562 d20a80d4def3
562 d20a80d4def3
563 007dc284c1f8
563 007dc284c1f8
564 01f36c5a8fda a139f71be9da
564 01f36c5a8fda a139f71be9da
565 82623d38b9ba
565 82623d38b9ba
566 01f36c5a8fda
566 01f36c5a8fda
567 392fd25390da
567 392fd25390da
568 a139f71be9da
568 a139f71be9da
569 01f36c5a8fda
569 01f36c5a8fda
570 01f36c5a8fda
570 01f36c5a8fda
571 6a411f0d7a0a
571 6a411f0d7a0a
572 a139f71be9da
572 a139f71be9da
573 e442cfc57690
573 e442cfc57690
574 a139f71be9da
574 a139f71be9da
575 3750ebee865d
575 3750ebee865d
576 a139f71be9da
576 a139f71be9da
577 7ae126973a96
577 7ae126973a96
578 a139f71be9da
578 a139f71be9da
579 14608b260df8
579 14608b260df8
580 a139f71be9da
580 a139f71be9da
581 bed64f5d2f5a
581 bed64f5d2f5a
582 a139f71be9da
582 a139f71be9da
583 a139f71be9da
583 a139f71be9da
584 a139f71be9da
584 a139f71be9da
585 $ hg debugsuccessorssets 'all()' --closest
585 $ hg debugsuccessorssets 'all()' --closest
586 d20a80d4def3
586 d20a80d4def3
587 d20a80d4def3
587 d20a80d4def3
588 01f36c5a8fda
588 01f36c5a8fda
589 01f36c5a8fda
589 01f36c5a8fda
590 a139f71be9da
590 a139f71be9da
591 a139f71be9da
591 a139f71be9da
592 $ hg debugsuccessorssets 'all()' --closest --hidden
592 $ hg debugsuccessorssets 'all()' --closest --hidden
593 d20a80d4def3
593 d20a80d4def3
594 d20a80d4def3
594 d20a80d4def3
595 007dc284c1f8
595 007dc284c1f8
596 82623d38b9ba 392fd25390da
596 82623d38b9ba 392fd25390da
597 82623d38b9ba
597 82623d38b9ba
598 82623d38b9ba
598 82623d38b9ba
599 392fd25390da
599 392fd25390da
600 392fd25390da
600 392fd25390da
601 01f36c5a8fda
601 01f36c5a8fda
602 01f36c5a8fda
602 01f36c5a8fda
603 6a411f0d7a0a
603 6a411f0d7a0a
604 e442cfc57690
604 e442cfc57690
605 e442cfc57690
605 e442cfc57690
606 e442cfc57690
606 e442cfc57690
607 3750ebee865d
607 3750ebee865d
608 392fd25390da
608 392fd25390da
609 7ae126973a96
609 7ae126973a96
610 a139f71be9da
610 a139f71be9da
611 14608b260df8
611 14608b260df8
612 a139f71be9da
612 a139f71be9da
613 bed64f5d2f5a
613 bed64f5d2f5a
614 a139f71be9da
614 a139f71be9da
615 a139f71be9da
615 a139f71be9da
616 a139f71be9da
616 a139f71be9da
617 $ hg log -r 'contentdivergent()'
617 $ hg log -r 'contentdivergent()'
618
618
619 $ cd ..
619 $ cd ..
620
620
621
621
622 Subset does not diverge
622 Subset does not diverge
623 ------------------------------
623 ------------------------------
624
624
625 Do not report divergent successors-set if it is a subset of another
625 Do not report divergent successors-set if it is a subset of another
626 successors-set. (report [A,B] not [A] + [A,B])
626 successors-set. (report [A,B] not [A] + [A,B])
627
627
628 $ newcase subset
628 $ newcase subset
629 $ hg debugobsolete `getid A_0` `getid A_2`
629 $ hg debugobsolete `getid A_0` `getid A_2`
630 obsoleted 1 changesets
630 obsoleted 1 changesets
631 $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
631 $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
632 $ hg debugsuccessorssets --hidden 'desc('A_0')'
632 $ hg debugsuccessorssets --hidden 'desc('A_0')'
633 007dc284c1f8
633 007dc284c1f8
634 82623d38b9ba 392fd25390da
634 82623d38b9ba 392fd25390da
635 $ hg debugsuccessorssets 'desc('A_0')' --closest
635 $ hg debugsuccessorssets 'desc('A_0')' --closest
636 $ hg debugsuccessorssets 'desc('A_0')' --closest --hidden
636 $ hg debugsuccessorssets 'desc('A_0')' --closest --hidden
637 007dc284c1f8
637 007dc284c1f8
638 82623d38b9ba 392fd25390da
638 82623d38b9ba 392fd25390da
639
639
640 $ cd ..
640 $ cd ..
641
641
642 Use scmutil.cleanupnodes API to create divergence
642 Use scmutil.cleanupnodes API to create divergence
643
643
644 $ hg init cleanupnodes
644 $ hg init cleanupnodes
645 $ cd cleanupnodes
645 $ cd cleanupnodes
646 $ hg debugdrawdag <<'EOS'
646 $ hg debugdrawdag <<'EOS'
647 > B1 B3 B4
647 > B1 B3 B4
648 > | \|
648 > | \|
649 > A Z
649 > A Z
650 > EOS
650 > EOS
651
651
652 $ hg update -q B1
652 $ hg update -q B1
653 $ echo 3 >> B
653 $ echo 3 >> B
654 $ hg commit --amend -m B2
654 $ hg commit --amend -m B2
655 $ cat > $TESTTMP/scmutilcleanup.py <<EOF
655 $ cat > $TESTTMP/scmutilcleanup.py <<EOF
656 > from mercurial import registrar, scmutil
656 > from mercurial import registrar, scmutil
657 > cmdtable = {}
657 > cmdtable = {}
658 > command = registrar.command(cmdtable)
658 > command = registrar.command(cmdtable)
659 > @command('cleanup')
659 > @command('cleanup')
660 > def cleanup(ui, repo):
660 > def cleanup(ui, repo):
661 > def node(expr):
661 > def node(expr):
662 > unfi = repo.unfiltered()
662 > unfi = repo.unfiltered()
663 > rev = unfi.revs(expr).first()
663 > rev = unfi.revs(expr).first()
664 > return unfi.changelog.node(rev)
664 > return unfi.changelog.node(rev)
665 > with repo.wlock(), repo.lock(), repo.transaction('delayedstrip'):
665 > with repo.wlock(), repo.lock(), repo.transaction('delayedstrip'):
666 > mapping = {node('desc(B1)'): [node('desc(B3)')],
666 > mapping = {node('desc(B1)'): [node('desc(B3)')],
667 > node('desc(B3)'): [node('desc(B4)')]}
667 > node('desc(B3)'): [node('desc(B4)')]}
668 > scmutil.cleanupnodes(repo, mapping, 'test')
668 > scmutil.cleanupnodes(repo, mapping, 'test')
669 > EOF
669 > EOF
670
670
671 $ rm .hg/localtags
671 $ rm .hg/localtags
672 $ hg cleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
672 $ hg cleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
673 $ hg log -G -T '{rev}:{node|short} {desc} {instabilities}' -r 'sort(all(), topo)'
673 $ hg log -G -T '{rev}:{node|short} {desc} {instabilities}' -r 'sort(all(), topo)'
674 @ 5:1a2a9b5b0030 B2 content-divergent
674 @ 5:1a2a9b5b0030 B2 content-divergent
675 |
675 |
676 | o 4:70d5a63ca112 B4 content-divergent
676 | o 4:70d5a63ca112 B4 content-divergent
677 | |
677 | |
678 | o 1:48b9aae0607f Z
678 | o 1:48b9aae0607f Z
679 |
679 |
680 o 0:426bada5c675 A
680 o 0:426bada5c675 A
681
681
682 $ hg debugobsolete
682 $ hg debugobsolete
683 a178212c3433c4e77b573f6011e29affb8aefa33 1a2a9b5b0030632400aa78e00388c20f99d3ec44 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
683 a178212c3433c4e77b573f6011e29affb8aefa33 1a2a9b5b0030632400aa78e00388c20f99d3ec44 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
684 a178212c3433c4e77b573f6011e29affb8aefa33 ad6478fb94ecec98b86daae98722865d494ac561 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'test', 'user': 'test'}
684 a178212c3433c4e77b573f6011e29affb8aefa33 ad6478fb94ecec98b86daae98722865d494ac561 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'test', 'user': 'test'}
685 ad6478fb94ecec98b86daae98722865d494ac561 70d5a63ca112acb3764bc1d7320ca90ea688d671 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'test', 'user': 'test'}
685 ad6478fb94ecec98b86daae98722865d494ac561 70d5a63ca112acb3764bc1d7320ca90ea688d671 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'test', 'user': 'test'}
@@ -1,1508 +1,1508
1 $ cat >> $HGRCPATH << EOF
1 $ cat >> $HGRCPATH << EOF
2 > [phases]
2 > [phases]
3 > # public changeset are not obsolete
3 > # public changeset are not obsolete
4 > publish=false
4 > publish=false
5 > [ui]
5 > [ui]
6 > logtemplate="{rev}:{node|short} ({phase}{if(obsolete, ' *{obsolete}*')}{if(instabilities, ' {instabilities}')}) [{tags} {bookmarks}] {desc|firstline}\n"
6 > logtemplate="{rev}:{node|short} ({phase}{if(obsolete, ' *{obsolete}*')}{if(instabilities, ' {instabilities}')}) [{tags} {bookmarks}] {desc|firstline}{if(obsfate, " [{join(obsfate, "; ")}]")}\n"
7 > EOF
7 > EOF
8 $ mkcommit() {
8 $ mkcommit() {
9 > echo "$1" > "$1"
9 > echo "$1" > "$1"
10 > hg add "$1"
10 > hg add "$1"
11 > hg ci -m "add $1"
11 > hg ci -m "add $1"
12 > }
12 > }
13 $ getid() {
13 $ getid() {
14 > hg log -T "{node}\n" --hidden -r "desc('$1')"
14 > hg log -T "{node}\n" --hidden -r "desc('$1')"
15 > }
15 > }
16
16
17 $ cat > debugkeys.py <<EOF
17 $ cat > debugkeys.py <<EOF
18 > def reposetup(ui, repo):
18 > def reposetup(ui, repo):
19 > class debugkeysrepo(repo.__class__):
19 > class debugkeysrepo(repo.__class__):
20 > def listkeys(self, namespace):
20 > def listkeys(self, namespace):
21 > ui.write('listkeys %s\n' % (namespace,))
21 > ui.write('listkeys %s\n' % (namespace,))
22 > return super(debugkeysrepo, self).listkeys(namespace)
22 > return super(debugkeysrepo, self).listkeys(namespace)
23 >
23 >
24 > if repo.local():
24 > if repo.local():
25 > repo.__class__ = debugkeysrepo
25 > repo.__class__ = debugkeysrepo
26 > EOF
26 > EOF
27
27
28 $ hg init tmpa
28 $ hg init tmpa
29 $ cd tmpa
29 $ cd tmpa
30 $ mkcommit kill_me
30 $ mkcommit kill_me
31
31
32 Checking that the feature is properly disabled
32 Checking that the feature is properly disabled
33
33
34 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
34 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
35 abort: creating obsolete markers is not enabled on this repo
35 abort: creating obsolete markers is not enabled on this repo
36 [255]
36 [255]
37
37
38 Enabling it
38 Enabling it
39
39
40 $ cat >> $HGRCPATH << EOF
40 $ cat >> $HGRCPATH << EOF
41 > [experimental]
41 > [experimental]
42 > stabilization=createmarkers,exchange
42 > stabilization=createmarkers,exchange
43 > EOF
43 > EOF
44
44
45 Killing a single changeset without replacement
45 Killing a single changeset without replacement
46
46
47 $ hg debugobsolete 0
47 $ hg debugobsolete 0
48 abort: changeset references must be full hexadecimal node identifiers
48 abort: changeset references must be full hexadecimal node identifiers
49 [255]
49 [255]
50 $ hg debugobsolete '00'
50 $ hg debugobsolete '00'
51 abort: changeset references must be full hexadecimal node identifiers
51 abort: changeset references must be full hexadecimal node identifiers
52 [255]
52 [255]
53 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
53 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
54 obsoleted 1 changesets
54 obsoleted 1 changesets
55 $ hg debugobsolete
55 $ hg debugobsolete
56 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'babar'}
56 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'babar'}
57
57
58 (test that mercurial is not confused)
58 (test that mercurial is not confused)
59
59
60 $ hg up null --quiet # having 0 as parent prevents it to be hidden
60 $ hg up null --quiet # having 0 as parent prevents it to be hidden
61 $ hg tip
61 $ hg tip
62 -1:000000000000 (public) [tip ]
62 -1:000000000000 (public) [tip ]
63 $ hg up --hidden tip --quiet
63 $ hg up --hidden tip --quiet
64
64
65 Killing a single changeset with itself should fail
65 Killing a single changeset with itself should fail
66 (simple local safeguard)
66 (simple local safeguard)
67
67
68 $ hg debugobsolete `getid kill_me` `getid kill_me`
68 $ hg debugobsolete `getid kill_me` `getid kill_me`
69 abort: bad obsmarker input: in-marker cycle with 97b7c2d76b1845ed3eb988cd612611e72406cef0
69 abort: bad obsmarker input: in-marker cycle with 97b7c2d76b1845ed3eb988cd612611e72406cef0
70 [255]
70 [255]
71
71
72 $ cd ..
72 $ cd ..
73
73
74 Killing a single changeset with replacement
74 Killing a single changeset with replacement
75 (and testing the format option)
75 (and testing the format option)
76
76
77 $ hg init tmpb
77 $ hg init tmpb
78 $ cd tmpb
78 $ cd tmpb
79 $ mkcommit a
79 $ mkcommit a
80 $ mkcommit b
80 $ mkcommit b
81 $ mkcommit original_c
81 $ mkcommit original_c
82 $ hg up "desc('b')"
82 $ hg up "desc('b')"
83 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
83 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
84 $ mkcommit new_c
84 $ mkcommit new_c
85 created new head
85 created new head
86 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
86 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
87 $ hg debugobsolete --config format.obsstore-version=0 --flag 12 `getid original_c` `getid new_c` -d '121 120'
87 $ hg debugobsolete --config format.obsstore-version=0 --flag 12 `getid original_c` `getid new_c` -d '121 120'
88 obsoleted 1 changesets
88 obsoleted 1 changesets
89 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
89 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
90 2:245bde4270cd add original_c
90 2:245bde4270cd add original_c
91 $ hg debugrevlog -cd
91 $ hg debugrevlog -cd
92 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
92 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
93 0 -1 -1 0 59 0 0 0 0 58 58 0 1 0
93 0 -1 -1 0 59 0 0 0 0 58 58 0 1 0
94 1 0 -1 59 118 59 59 0 0 58 116 0 1 0
94 1 0 -1 59 118 59 59 0 0 58 116 0 1 0
95 2 1 -1 118 193 118 118 59 0 76 192 0 1 0
95 2 1 -1 118 193 118 118 59 0 76 192 0 1 0
96 3 1 -1 193 260 193 193 59 0 66 258 0 2 0
96 3 1 -1 193 260 193 193 59 0 66 258 0 2 0
97 $ hg debugobsolete
97 $ hg debugobsolete
98 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
98 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
99
99
100 (check for version number of the obsstore)
100 (check for version number of the obsstore)
101
101
102 $ dd bs=1 count=1 if=.hg/store/obsstore 2>/dev/null
102 $ dd bs=1 count=1 if=.hg/store/obsstore 2>/dev/null
103 \x00 (no-eol) (esc)
103 \x00 (no-eol) (esc)
104
104
105 do it again (it read the obsstore before adding new changeset)
105 do it again (it read the obsstore before adding new changeset)
106
106
107 $ hg up '.^'
107 $ hg up '.^'
108 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
108 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
109 $ mkcommit new_2_c
109 $ mkcommit new_2_c
110 created new head
110 created new head
111 $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
111 $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
112 obsoleted 1 changesets
112 obsoleted 1 changesets
113 $ hg debugobsolete
113 $ hg debugobsolete
114 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
114 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
115 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
115 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
116
116
117 Register two markers with a missing node
117 Register two markers with a missing node
118
118
119 $ hg up '.^'
119 $ hg up '.^'
120 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
120 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
121 $ mkcommit new_3_c
121 $ mkcommit new_3_c
122 created new head
122 created new head
123 $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
123 $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
124 obsoleted 1 changesets
124 obsoleted 1 changesets
125 $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
125 $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
126 $ hg debugobsolete
126 $ hg debugobsolete
127 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
127 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
128 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
128 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
129 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
129 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
130 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
130 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
131
131
132 Test the --index option of debugobsolete command
132 Test the --index option of debugobsolete command
133 $ hg debugobsolete --index
133 $ hg debugobsolete --index
134 0 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
134 0 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
135 1 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
135 1 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
136 2 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
136 2 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
137 3 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
137 3 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
138
138
139 Refuse pathological nullid successors
139 Refuse pathological nullid successors
140 $ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
140 $ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
141 transaction abort!
141 transaction abort!
142 rollback completed
142 rollback completed
143 abort: bad obsolescence marker detected: invalid successors nullid
143 abort: bad obsolescence marker detected: invalid successors nullid
144 [255]
144 [255]
145
145
146 Check that graphlog detect that a changeset is obsolete:
146 Check that graphlog detect that a changeset is obsolete:
147
147
148 $ hg log -G
148 $ hg log -G
149 @ 5:5601fb93a350 (draft) [tip ] add new_3_c
149 @ 5:5601fb93a350 (draft) [tip ] add new_3_c
150 |
150 |
151 o 1:7c3bad9141dc (draft) [ ] add b
151 o 1:7c3bad9141dc (draft) [ ] add b
152 |
152 |
153 o 0:1f0dee641bb7 (draft) [ ] add a
153 o 0:1f0dee641bb7 (draft) [ ] add a
154
154
155
155
156 check that heads does not report them
156 check that heads does not report them
157
157
158 $ hg heads
158 $ hg heads
159 5:5601fb93a350 (draft) [tip ] add new_3_c
159 5:5601fb93a350 (draft) [tip ] add new_3_c
160 $ hg heads --hidden
160 $ hg heads --hidden
161 5:5601fb93a350 (draft) [tip ] add new_3_c
161 5:5601fb93a350 (draft) [tip ] add new_3_c
162 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c
162 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350 by test (between 1970-01-01 00:22 +0000 and 1970-01-01 00:22 +0000)]
163 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c
163 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9 by test (at 1970-01-01 00:22 +0000)]
164 2:245bde4270cd (draft *obsolete*) [ ] add original_c
164 2:245bde4270cd (draft *obsolete*) [ ] add original_c [rewritten as 3:cdbce2fbb163 by test (at 1970-01-01 00:00 -0002)]
165
165
166
166
167 check that summary does not report them
167 check that summary does not report them
168
168
169 $ hg init ../sink
169 $ hg init ../sink
170 $ echo '[paths]' >> .hg/hgrc
170 $ echo '[paths]' >> .hg/hgrc
171 $ echo 'default=../sink' >> .hg/hgrc
171 $ echo 'default=../sink' >> .hg/hgrc
172 $ hg summary --remote
172 $ hg summary --remote
173 parent: 5:5601fb93a350 tip
173 parent: 5:5601fb93a350 tip
174 add new_3_c
174 add new_3_c
175 branch: default
175 branch: default
176 commit: (clean)
176 commit: (clean)
177 update: (current)
177 update: (current)
178 phases: 3 draft
178 phases: 3 draft
179 remote: 3 outgoing
179 remote: 3 outgoing
180
180
181 $ hg summary --remote --hidden
181 $ hg summary --remote --hidden
182 parent: 5:5601fb93a350 tip
182 parent: 5:5601fb93a350 tip
183 add new_3_c
183 add new_3_c
184 branch: default
184 branch: default
185 commit: (clean)
185 commit: (clean)
186 update: 3 new changesets, 4 branch heads (merge)
186 update: 3 new changesets, 4 branch heads (merge)
187 phases: 6 draft
187 phases: 6 draft
188 remote: 3 outgoing
188 remote: 3 outgoing
189
189
190 check that various commands work well with filtering
190 check that various commands work well with filtering
191
191
192 $ hg tip
192 $ hg tip
193 5:5601fb93a350 (draft) [tip ] add new_3_c
193 5:5601fb93a350 (draft) [tip ] add new_3_c
194 $ hg log -r 6
194 $ hg log -r 6
195 abort: unknown revision '6'!
195 abort: unknown revision '6'!
196 [255]
196 [255]
197 $ hg log -r 4
197 $ hg log -r 4
198 abort: hidden revision '4'!
198 abort: hidden revision '4'!
199 (use --hidden to access hidden revisions)
199 (use --hidden to access hidden revisions)
200 [255]
200 [255]
201 $ hg debugrevspec 'rev(6)'
201 $ hg debugrevspec 'rev(6)'
202 $ hg debugrevspec 'rev(4)'
202 $ hg debugrevspec 'rev(4)'
203 $ hg debugrevspec 'null'
203 $ hg debugrevspec 'null'
204 -1
204 -1
205
205
206 Check that public changeset are not accounted as obsolete:
206 Check that public changeset are not accounted as obsolete:
207
207
208 $ hg --hidden phase --public 2
208 $ hg --hidden phase --public 2
209 $ hg log -G
209 $ hg log -G
210 @ 5:5601fb93a350 (draft phase-divergent) [tip ] add new_3_c
210 @ 5:5601fb93a350 (draft phase-divergent) [tip ] add new_3_c
211 |
211 |
212 | o 2:245bde4270cd (public) [ ] add original_c
212 | o 2:245bde4270cd (public) [ ] add original_c
213 |/
213 |/
214 o 1:7c3bad9141dc (public) [ ] add b
214 o 1:7c3bad9141dc (public) [ ] add b
215 |
215 |
216 o 0:1f0dee641bb7 (public) [ ] add a
216 o 0:1f0dee641bb7 (public) [ ] add a
217
217
218
218
219 And that bumped changeset are detected
219 And that bumped changeset are detected
220 --------------------------------------
220 --------------------------------------
221
221
222 If we didn't filtered obsolete changesets out, 3 and 4 would show up too. Also
222 If we didn't filtered obsolete changesets out, 3 and 4 would show up too. Also
223 note that the bumped changeset (5:5601fb93a350) is not a direct successor of
223 note that the bumped changeset (5:5601fb93a350) is not a direct successor of
224 the public changeset
224 the public changeset
225
225
226 $ hg log --hidden -r 'phasedivergent()'
226 $ hg log --hidden -r 'phasedivergent()'
227 5:5601fb93a350 (draft phase-divergent) [tip ] add new_3_c
227 5:5601fb93a350 (draft phase-divergent) [tip ] add new_3_c
228
228
229 And that we can't push bumped changeset
229 And that we can't push bumped changeset
230
230
231 $ hg push ../tmpa -r 0 --force #(make repo related)
231 $ hg push ../tmpa -r 0 --force #(make repo related)
232 pushing to ../tmpa
232 pushing to ../tmpa
233 searching for changes
233 searching for changes
234 warning: repository is unrelated
234 warning: repository is unrelated
235 adding changesets
235 adding changesets
236 adding manifests
236 adding manifests
237 adding file changes
237 adding file changes
238 added 1 changesets with 1 changes to 1 files (+1 heads)
238 added 1 changesets with 1 changes to 1 files (+1 heads)
239 $ hg push ../tmpa
239 $ hg push ../tmpa
240 pushing to ../tmpa
240 pushing to ../tmpa
241 searching for changes
241 searching for changes
242 abort: push includes phase-divergent changeset: 5601fb93a350!
242 abort: push includes phase-divergent changeset: 5601fb93a350!
243 [255]
243 [255]
244
244
245 Fixing "bumped" situation
245 Fixing "bumped" situation
246 We need to create a clone of 5 and add a special marker with a flag
246 We need to create a clone of 5 and add a special marker with a flag
247
247
248 $ hg summary
248 $ hg summary
249 parent: 5:5601fb93a350 tip (phase-divergent)
249 parent: 5:5601fb93a350 tip (phase-divergent)
250 add new_3_c
250 add new_3_c
251 branch: default
251 branch: default
252 commit: (clean)
252 commit: (clean)
253 update: 1 new changesets, 2 branch heads (merge)
253 update: 1 new changesets, 2 branch heads (merge)
254 phases: 1 draft
254 phases: 1 draft
255 phase-divergent: 1 changesets
255 phase-divergent: 1 changesets
256 $ hg up '5^'
256 $ hg up '5^'
257 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
257 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
258 $ hg revert -ar 5
258 $ hg revert -ar 5
259 adding new_3_c
259 adding new_3_c
260 $ hg ci -m 'add n3w_3_c'
260 $ hg ci -m 'add n3w_3_c'
261 created new head
261 created new head
262 $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c`
262 $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c`
263 obsoleted 1 changesets
263 obsoleted 1 changesets
264 $ hg log -r 'phasedivergent()'
264 $ hg log -r 'phasedivergent()'
265 $ hg log -G
265 $ hg log -G
266 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
266 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
267 |
267 |
268 | o 2:245bde4270cd (public) [ ] add original_c
268 | o 2:245bde4270cd (public) [ ] add original_c
269 |/
269 |/
270 o 1:7c3bad9141dc (public) [ ] add b
270 o 1:7c3bad9141dc (public) [ ] add b
271 |
271 |
272 o 0:1f0dee641bb7 (public) [ ] add a
272 o 0:1f0dee641bb7 (public) [ ] add a
273
273
274
274
275 Basic exclusive testing
275 Basic exclusive testing
276
276
277 $ hg log -G --hidden
277 $ hg log -G --hidden
278 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
278 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
279 |
279 |
280 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c
280 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c [rewritten as 6:6f9641995072 by test (at 1970-01-01 00:22 +0000)]
281 |/
281 |/
282 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c
282 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350 by test (between 1970-01-01 00:22 +0000 and 1970-01-01 00:22 +0000)]
283 |/
283 |/
284 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c
284 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9 by test (at 1970-01-01 00:22 +0000)]
285 |/
285 |/
286 | o 2:245bde4270cd (public) [ ] add original_c
286 | o 2:245bde4270cd (public) [ ] add original_c
287 |/
287 |/
288 o 1:7c3bad9141dc (public) [ ] add b
288 o 1:7c3bad9141dc (public) [ ] add b
289 |
289 |
290 o 0:1f0dee641bb7 (public) [ ] add a
290 o 0:1f0dee641bb7 (public) [ ] add a
291
291
292 $ hg debugobsolete --rev 6f9641995072
292 $ hg debugobsolete --rev 6f9641995072
293 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
293 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
294 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
294 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
295 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
295 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
296 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
296 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
297 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
297 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
298 $ hg debugobsolete --rev 6f9641995072 --exclusive
298 $ hg debugobsolete --rev 6f9641995072 --exclusive
299 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
299 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
300 $ hg debugobsolete --rev 5601fb93a350 --hidden
300 $ hg debugobsolete --rev 5601fb93a350 --hidden
301 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
301 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
302 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
302 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
303 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
303 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
304 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
304 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
305 $ hg debugobsolete --rev 5601fb93a350 --hidden --exclusive
305 $ hg debugobsolete --rev 5601fb93a350 --hidden --exclusive
306 $ hg debugobsolete --rev 5601fb93a350+6f9641995072 --hidden --exclusive
306 $ hg debugobsolete --rev 5601fb93a350+6f9641995072 --hidden --exclusive
307 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
307 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
308 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
308 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
309 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
309 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
310
310
311 $ cd ..
311 $ cd ..
312
312
313 Revision 0 is hidden
313 Revision 0 is hidden
314 --------------------
314 --------------------
315
315
316 $ hg init rev0hidden
316 $ hg init rev0hidden
317 $ cd rev0hidden
317 $ cd rev0hidden
318
318
319 $ mkcommit kill0
319 $ mkcommit kill0
320 $ hg up -q null
320 $ hg up -q null
321 $ hg debugobsolete `getid kill0`
321 $ hg debugobsolete `getid kill0`
322 obsoleted 1 changesets
322 obsoleted 1 changesets
323 $ mkcommit a
323 $ mkcommit a
324 $ mkcommit b
324 $ mkcommit b
325
325
326 Should pick the first visible revision as "repo" node
326 Should pick the first visible revision as "repo" node
327
327
328 $ hg archive ../archive-null
328 $ hg archive ../archive-null
329 $ cat ../archive-null/.hg_archival.txt
329 $ cat ../archive-null/.hg_archival.txt
330 repo: 1f0dee641bb7258c56bd60e93edfa2405381c41e
330 repo: 1f0dee641bb7258c56bd60e93edfa2405381c41e
331 node: 7c3bad9141dcb46ff89abf5f61856facd56e476c
331 node: 7c3bad9141dcb46ff89abf5f61856facd56e476c
332 branch: default
332 branch: default
333 latesttag: null
333 latesttag: null
334 latesttagdistance: 2
334 latesttagdistance: 2
335 changessincelatesttag: 2
335 changessincelatesttag: 2
336
336
337
337
338 $ cd ..
338 $ cd ..
339
339
340 Exchange Test
340 Exchange Test
341 ============================
341 ============================
342
342
343 Destination repo does not have any data
343 Destination repo does not have any data
344 ---------------------------------------
344 ---------------------------------------
345
345
346 Simple incoming test
346 Simple incoming test
347
347
348 $ hg init tmpc
348 $ hg init tmpc
349 $ cd tmpc
349 $ cd tmpc
350 $ hg incoming ../tmpb
350 $ hg incoming ../tmpb
351 comparing with ../tmpb
351 comparing with ../tmpb
352 0:1f0dee641bb7 (public) [ ] add a
352 0:1f0dee641bb7 (public) [ ] add a
353 1:7c3bad9141dc (public) [ ] add b
353 1:7c3bad9141dc (public) [ ] add b
354 2:245bde4270cd (public) [ ] add original_c
354 2:245bde4270cd (public) [ ] add original_c
355 6:6f9641995072 (draft) [tip ] add n3w_3_c
355 6:6f9641995072 (draft) [tip ] add n3w_3_c
356
356
357 Try to pull markers
357 Try to pull markers
358 (extinct changeset are excluded but marker are pushed)
358 (extinct changeset are excluded but marker are pushed)
359
359
360 $ hg pull ../tmpb
360 $ hg pull ../tmpb
361 pulling from ../tmpb
361 pulling from ../tmpb
362 requesting all changes
362 requesting all changes
363 adding changesets
363 adding changesets
364 adding manifests
364 adding manifests
365 adding file changes
365 adding file changes
366 added 4 changesets with 4 changes to 4 files (+1 heads)
366 added 4 changesets with 4 changes to 4 files (+1 heads)
367 5 new obsolescence markers
367 5 new obsolescence markers
368 new changesets 1f0dee641bb7:6f9641995072
368 new changesets 1f0dee641bb7:6f9641995072
369 (run 'hg heads' to see heads, 'hg merge' to merge)
369 (run 'hg heads' to see heads, 'hg merge' to merge)
370 $ hg debugobsolete
370 $ hg debugobsolete
371 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
371 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
372 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
372 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
373 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
373 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
374 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
374 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
375 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
375 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
376
376
377 Rollback//Transaction support
377 Rollback//Transaction support
378
378
379 $ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
379 $ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
380 $ hg debugobsolete
380 $ hg debugobsolete
381 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
381 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
382 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
382 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
383 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
383 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
384 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
384 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
385 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
385 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
386 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:22:20 1970 +0000) {'user': 'test'}
386 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:22:20 1970 +0000) {'user': 'test'}
387 $ hg rollback -n
387 $ hg rollback -n
388 repository tip rolled back to revision 3 (undo debugobsolete)
388 repository tip rolled back to revision 3 (undo debugobsolete)
389 $ hg rollback
389 $ hg rollback
390 repository tip rolled back to revision 3 (undo debugobsolete)
390 repository tip rolled back to revision 3 (undo debugobsolete)
391 $ hg debugobsolete
391 $ hg debugobsolete
392 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
392 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
393 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
393 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
394 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
394 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
395 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
395 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
396 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
396 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
397
397
398 $ cd ..
398 $ cd ..
399
399
400 Try to push markers
400 Try to push markers
401
401
402 $ hg init tmpd
402 $ hg init tmpd
403 $ hg -R tmpb push tmpd
403 $ hg -R tmpb push tmpd
404 pushing to tmpd
404 pushing to tmpd
405 searching for changes
405 searching for changes
406 adding changesets
406 adding changesets
407 adding manifests
407 adding manifests
408 adding file changes
408 adding file changes
409 added 4 changesets with 4 changes to 4 files (+1 heads)
409 added 4 changesets with 4 changes to 4 files (+1 heads)
410 5 new obsolescence markers
410 5 new obsolescence markers
411 $ hg -R tmpd debugobsolete | sort
411 $ hg -R tmpd debugobsolete | sort
412 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
412 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
413 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
413 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
414 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
414 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
415 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
415 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
416 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
416 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
417
417
418 Check obsolete keys are exchanged only if source has an obsolete store
418 Check obsolete keys are exchanged only if source has an obsolete store
419
419
420 $ hg init empty
420 $ hg init empty
421 $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
421 $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
422 pushing to tmpd
422 pushing to tmpd
423 listkeys phases
423 listkeys phases
424 listkeys bookmarks
424 listkeys bookmarks
425 no changes found
425 no changes found
426 listkeys phases
426 listkeys phases
427 [1]
427 [1]
428
428
429 clone support
429 clone support
430 (markers are copied and extinct changesets are included to allow hardlinks)
430 (markers are copied and extinct changesets are included to allow hardlinks)
431
431
432 $ hg clone tmpb clone-dest
432 $ hg clone tmpb clone-dest
433 updating to branch default
433 updating to branch default
434 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
434 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
435 $ hg -R clone-dest log -G --hidden
435 $ hg -R clone-dest log -G --hidden
436 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
436 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
437 |
437 |
438 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c
438 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c [rewritten as 6:6f9641995072 by test (at 1970-01-01 00:22 +0000)]
439 |/
439 |/
440 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c
440 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350 by test (between 1970-01-01 00:22 +0000 and 1970-01-01 00:22 +0000)]
441 |/
441 |/
442 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c
442 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9 by test (at 1970-01-01 00:22 +0000)]
443 |/
443 |/
444 | o 2:245bde4270cd (public) [ ] add original_c
444 | o 2:245bde4270cd (public) [ ] add original_c
445 |/
445 |/
446 o 1:7c3bad9141dc (public) [ ] add b
446 o 1:7c3bad9141dc (public) [ ] add b
447 |
447 |
448 o 0:1f0dee641bb7 (public) [ ] add a
448 o 0:1f0dee641bb7 (public) [ ] add a
449
449
450 $ hg -R clone-dest debugobsolete
450 $ hg -R clone-dest debugobsolete
451 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
451 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
452 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
452 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
453 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
453 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
454 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
454 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
455 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
455 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
456
456
457
457
458 Destination repo have existing data
458 Destination repo have existing data
459 ---------------------------------------
459 ---------------------------------------
460
460
461 On pull
461 On pull
462
462
463 $ hg init tmpe
463 $ hg init tmpe
464 $ cd tmpe
464 $ cd tmpe
465 $ hg debugobsolete -d '1339 0' 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00
465 $ hg debugobsolete -d '1339 0' 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00
466 $ hg pull ../tmpb
466 $ hg pull ../tmpb
467 pulling from ../tmpb
467 pulling from ../tmpb
468 requesting all changes
468 requesting all changes
469 adding changesets
469 adding changesets
470 adding manifests
470 adding manifests
471 adding file changes
471 adding file changes
472 added 4 changesets with 4 changes to 4 files (+1 heads)
472 added 4 changesets with 4 changes to 4 files (+1 heads)
473 5 new obsolescence markers
473 5 new obsolescence markers
474 new changesets 1f0dee641bb7:6f9641995072
474 new changesets 1f0dee641bb7:6f9641995072
475 (run 'hg heads' to see heads, 'hg merge' to merge)
475 (run 'hg heads' to see heads, 'hg merge' to merge)
476 $ hg debugobsolete
476 $ hg debugobsolete
477 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
477 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
478 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
478 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
479 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
479 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
480 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
480 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
481 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
481 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
482 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
482 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
483
483
484
484
485 On push
485 On push
486
486
487 $ hg push ../tmpc
487 $ hg push ../tmpc
488 pushing to ../tmpc
488 pushing to ../tmpc
489 searching for changes
489 searching for changes
490 no changes found
490 no changes found
491 1 new obsolescence markers
491 1 new obsolescence markers
492 [1]
492 [1]
493 $ hg -R ../tmpc debugobsolete
493 $ hg -R ../tmpc debugobsolete
494 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
494 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
495 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
495 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
496 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
496 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
497 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
497 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
498 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
498 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
499 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
499 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
500
500
501 detect outgoing obsolete and unstable
501 detect outgoing obsolete and unstable
502 ---------------------------------------
502 ---------------------------------------
503
503
504
504
505 $ hg log -G
505 $ hg log -G
506 o 3:6f9641995072 (draft) [tip ] add n3w_3_c
506 o 3:6f9641995072 (draft) [tip ] add n3w_3_c
507 |
507 |
508 | o 2:245bde4270cd (public) [ ] add original_c
508 | o 2:245bde4270cd (public) [ ] add original_c
509 |/
509 |/
510 o 1:7c3bad9141dc (public) [ ] add b
510 o 1:7c3bad9141dc (public) [ ] add b
511 |
511 |
512 o 0:1f0dee641bb7 (public) [ ] add a
512 o 0:1f0dee641bb7 (public) [ ] add a
513
513
514 $ hg up 'desc("n3w_3_c")'
514 $ hg up 'desc("n3w_3_c")'
515 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
515 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
516 $ mkcommit original_d
516 $ mkcommit original_d
517 $ mkcommit original_e
517 $ mkcommit original_e
518 $ hg debugobsolete --record-parents `getid original_d` -d '0 0'
518 $ hg debugobsolete --record-parents `getid original_d` -d '0 0'
519 obsoleted 1 changesets
519 obsoleted 1 changesets
520 $ hg debugobsolete | grep `getid original_d`
520 $ hg debugobsolete | grep `getid original_d`
521 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
521 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
522 $ hg log -r 'obsolete()'
522 $ hg log -r 'obsolete()'
523 4:94b33453f93b (draft *obsolete*) [ ] add original_d
523 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned by test (at 1970-01-01 00:00 +0000)]
524 $ hg summary
524 $ hg summary
525 parent: 5:cda648ca50f5 tip (orphan)
525 parent: 5:cda648ca50f5 tip (orphan)
526 add original_e
526 add original_e
527 branch: default
527 branch: default
528 commit: (clean)
528 commit: (clean)
529 update: 1 new changesets, 2 branch heads (merge)
529 update: 1 new changesets, 2 branch heads (merge)
530 phases: 3 draft
530 phases: 3 draft
531 orphan: 1 changesets
531 orphan: 1 changesets
532 $ hg log -G -r '::orphan()'
532 $ hg log -G -r '::orphan()'
533 @ 5:cda648ca50f5 (draft orphan) [tip ] add original_e
533 @ 5:cda648ca50f5 (draft orphan) [tip ] add original_e
534 |
534 |
535 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d
535 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned by test (at 1970-01-01 00:00 +0000)]
536 |
536 |
537 o 3:6f9641995072 (draft) [ ] add n3w_3_c
537 o 3:6f9641995072 (draft) [ ] add n3w_3_c
538 |
538 |
539 o 1:7c3bad9141dc (public) [ ] add b
539 o 1:7c3bad9141dc (public) [ ] add b
540 |
540 |
541 o 0:1f0dee641bb7 (public) [ ] add a
541 o 0:1f0dee641bb7 (public) [ ] add a
542
542
543
543
544 refuse to push obsolete changeset
544 refuse to push obsolete changeset
545
545
546 $ hg push ../tmpc/ -r 'desc("original_d")'
546 $ hg push ../tmpc/ -r 'desc("original_d")'
547 pushing to ../tmpc/
547 pushing to ../tmpc/
548 searching for changes
548 searching for changes
549 abort: push includes obsolete changeset: 94b33453f93b!
549 abort: push includes obsolete changeset: 94b33453f93b!
550 [255]
550 [255]
551
551
552 refuse to push unstable changeset
552 refuse to push unstable changeset
553
553
554 $ hg push ../tmpc/
554 $ hg push ../tmpc/
555 pushing to ../tmpc/
555 pushing to ../tmpc/
556 searching for changes
556 searching for changes
557 abort: push includes orphan changeset: cda648ca50f5!
557 abort: push includes orphan changeset: cda648ca50f5!
558 [255]
558 [255]
559
559
560 Test that extinct changeset are properly detected
560 Test that extinct changeset are properly detected
561
561
562 $ hg log -r 'extinct()'
562 $ hg log -r 'extinct()'
563
563
564 Don't try to push extinct changeset
564 Don't try to push extinct changeset
565
565
566 $ hg init ../tmpf
566 $ hg init ../tmpf
567 $ hg out ../tmpf
567 $ hg out ../tmpf
568 comparing with ../tmpf
568 comparing with ../tmpf
569 searching for changes
569 searching for changes
570 0:1f0dee641bb7 (public) [ ] add a
570 0:1f0dee641bb7 (public) [ ] add a
571 1:7c3bad9141dc (public) [ ] add b
571 1:7c3bad9141dc (public) [ ] add b
572 2:245bde4270cd (public) [ ] add original_c
572 2:245bde4270cd (public) [ ] add original_c
573 3:6f9641995072 (draft) [ ] add n3w_3_c
573 3:6f9641995072 (draft) [ ] add n3w_3_c
574 4:94b33453f93b (draft *obsolete*) [ ] add original_d
574 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned by test (at 1970-01-01 00:00 +0000)]
575 5:cda648ca50f5 (draft orphan) [tip ] add original_e
575 5:cda648ca50f5 (draft orphan) [tip ] add original_e
576 $ hg push ../tmpf -f # -f because be push unstable too
576 $ hg push ../tmpf -f # -f because be push unstable too
577 pushing to ../tmpf
577 pushing to ../tmpf
578 searching for changes
578 searching for changes
579 adding changesets
579 adding changesets
580 adding manifests
580 adding manifests
581 adding file changes
581 adding file changes
582 added 6 changesets with 6 changes to 6 files (+1 heads)
582 added 6 changesets with 6 changes to 6 files (+1 heads)
583 7 new obsolescence markers
583 7 new obsolescence markers
584
584
585 no warning displayed
585 no warning displayed
586
586
587 $ hg push ../tmpf
587 $ hg push ../tmpf
588 pushing to ../tmpf
588 pushing to ../tmpf
589 searching for changes
589 searching for changes
590 no changes found
590 no changes found
591 [1]
591 [1]
592
592
593 Do not warn about new head when the new head is a successors of a remote one
593 Do not warn about new head when the new head is a successors of a remote one
594
594
595 $ hg log -G
595 $ hg log -G
596 @ 5:cda648ca50f5 (draft orphan) [tip ] add original_e
596 @ 5:cda648ca50f5 (draft orphan) [tip ] add original_e
597 |
597 |
598 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d
598 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned by test (at 1970-01-01 00:00 +0000)]
599 |
599 |
600 o 3:6f9641995072 (draft) [ ] add n3w_3_c
600 o 3:6f9641995072 (draft) [ ] add n3w_3_c
601 |
601 |
602 | o 2:245bde4270cd (public) [ ] add original_c
602 | o 2:245bde4270cd (public) [ ] add original_c
603 |/
603 |/
604 o 1:7c3bad9141dc (public) [ ] add b
604 o 1:7c3bad9141dc (public) [ ] add b
605 |
605 |
606 o 0:1f0dee641bb7 (public) [ ] add a
606 o 0:1f0dee641bb7 (public) [ ] add a
607
607
608 $ hg up -q 'desc(n3w_3_c)'
608 $ hg up -q 'desc(n3w_3_c)'
609 $ mkcommit obsolete_e
609 $ mkcommit obsolete_e
610 created new head
610 created new head
611 $ hg debugobsolete `getid 'original_e'` `getid 'obsolete_e'` \
611 $ hg debugobsolete `getid 'original_e'` `getid 'obsolete_e'` \
612 > -u 'test <test@example.net>'
612 > -u 'test <test@example.net>'
613 obsoleted 1 changesets
613 obsoleted 1 changesets
614 $ hg outgoing ../tmpf # parasite hg outgoing testin
614 $ hg outgoing ../tmpf # parasite hg outgoing testin
615 comparing with ../tmpf
615 comparing with ../tmpf
616 searching for changes
616 searching for changes
617 6:3de5eca88c00 (draft) [tip ] add obsolete_e
617 6:3de5eca88c00 (draft) [tip ] add obsolete_e
618 $ hg push ../tmpf
618 $ hg push ../tmpf
619 pushing to ../tmpf
619 pushing to ../tmpf
620 searching for changes
620 searching for changes
621 adding changesets
621 adding changesets
622 adding manifests
622 adding manifests
623 adding file changes
623 adding file changes
624 added 1 changesets with 1 changes to 1 files (+1 heads)
624 added 1 changesets with 1 changes to 1 files (+1 heads)
625 1 new obsolescence markers
625 1 new obsolescence markers
626 obsoleted 1 changesets
626 obsoleted 1 changesets
627
627
628 test relevance computation
628 test relevance computation
629 ---------------------------------------
629 ---------------------------------------
630
630
631 Checking simple case of "marker relevance".
631 Checking simple case of "marker relevance".
632
632
633
633
634 Reminder of the repo situation
634 Reminder of the repo situation
635
635
636 $ hg log --hidden --graph
636 $ hg log --hidden --graph
637 @ 6:3de5eca88c00 (draft) [tip ] add obsolete_e
637 @ 6:3de5eca88c00 (draft) [tip ] add obsolete_e
638 |
638 |
639 | x 5:cda648ca50f5 (draft *obsolete*) [ ] add original_e
639 | x 5:cda648ca50f5 (draft *obsolete*) [ ] add original_e [rewritten as 6:3de5eca88c00 by test <test@example.net> (at 1970-01-01 00:00 +0000)]
640 | |
640 | |
641 | x 4:94b33453f93b (draft *obsolete*) [ ] add original_d
641 | x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned by test (at 1970-01-01 00:00 +0000)]
642 |/
642 |/
643 o 3:6f9641995072 (draft) [ ] add n3w_3_c
643 o 3:6f9641995072 (draft) [ ] add n3w_3_c
644 |
644 |
645 | o 2:245bde4270cd (public) [ ] add original_c
645 | o 2:245bde4270cd (public) [ ] add original_c
646 |/
646 |/
647 o 1:7c3bad9141dc (public) [ ] add b
647 o 1:7c3bad9141dc (public) [ ] add b
648 |
648 |
649 o 0:1f0dee641bb7 (public) [ ] add a
649 o 0:1f0dee641bb7 (public) [ ] add a
650
650
651
651
652 List of all markers
652 List of all markers
653
653
654 $ hg debugobsolete
654 $ hg debugobsolete
655 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
655 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
656 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
656 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
657 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
657 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
658 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
658 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
659 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
659 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
660 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
660 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
661 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
661 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
662 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
662 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
663
663
664 List of changesets with no chain
664 List of changesets with no chain
665
665
666 $ hg debugobsolete --hidden --rev ::2
666 $ hg debugobsolete --hidden --rev ::2
667
667
668 List of changesets that are included on marker chain
668 List of changesets that are included on marker chain
669
669
670 $ hg debugobsolete --hidden --rev 6
670 $ hg debugobsolete --hidden --rev 6
671 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
671 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
672
672
673 List of changesets with a longer chain, (including a pruned children)
673 List of changesets with a longer chain, (including a pruned children)
674
674
675 $ hg debugobsolete --hidden --rev 3
675 $ hg debugobsolete --hidden --rev 3
676 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
676 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
677 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
677 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
678 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
678 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
679 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
679 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
680 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
680 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
681 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
681 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
682 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
682 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
683
683
684 List of both
684 List of both
685
685
686 $ hg debugobsolete --hidden --rev 3::6
686 $ hg debugobsolete --hidden --rev 3::6
687 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
687 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
688 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
688 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
689 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
689 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
690 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
690 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
691 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
691 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
692 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
692 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
693 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
693 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
694 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
694 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
695
695
696 List of all markers in JSON
696 List of all markers in JSON
697
697
698 $ hg debugobsolete -Tjson
698 $ hg debugobsolete -Tjson
699 [
699 [
700 {
700 {
701 "date": [1339.0, 0],
701 "date": [1339.0, 0],
702 "flag": 0,
702 "flag": 0,
703 "metadata": {"user": "test"},
703 "metadata": {"user": "test"},
704 "prednode": "1339133913391339133913391339133913391339",
704 "prednode": "1339133913391339133913391339133913391339",
705 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
705 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
706 },
706 },
707 {
707 {
708 "date": [1339.0, 0],
708 "date": [1339.0, 0],
709 "flag": 0,
709 "flag": 0,
710 "metadata": {"user": "test"},
710 "metadata": {"user": "test"},
711 "prednode": "1337133713371337133713371337133713371337",
711 "prednode": "1337133713371337133713371337133713371337",
712 "succnodes": ["5601fb93a350734d935195fee37f4054c529ff39"]
712 "succnodes": ["5601fb93a350734d935195fee37f4054c529ff39"]
713 },
713 },
714 {
714 {
715 "date": [121.0, 120],
715 "date": [121.0, 120],
716 "flag": 12,
716 "flag": 12,
717 "metadata": {"user": "test"},
717 "metadata": {"user": "test"},
718 "prednode": "245bde4270cd1072a27757984f9cda8ba26f08ca",
718 "prednode": "245bde4270cd1072a27757984f9cda8ba26f08ca",
719 "succnodes": ["cdbce2fbb16313928851e97e0d85413f3f7eb77f"]
719 "succnodes": ["cdbce2fbb16313928851e97e0d85413f3f7eb77f"]
720 },
720 },
721 {
721 {
722 "date": [1338.0, 0],
722 "date": [1338.0, 0],
723 "flag": 1,
723 "flag": 1,
724 "metadata": {"user": "test"},
724 "metadata": {"user": "test"},
725 "prednode": "5601fb93a350734d935195fee37f4054c529ff39",
725 "prednode": "5601fb93a350734d935195fee37f4054c529ff39",
726 "succnodes": ["6f96419950729f3671185b847352890f074f7557"]
726 "succnodes": ["6f96419950729f3671185b847352890f074f7557"]
727 },
727 },
728 {
728 {
729 "date": [1338.0, 0],
729 "date": [1338.0, 0],
730 "flag": 0,
730 "flag": 0,
731 "metadata": {"user": "test"},
731 "metadata": {"user": "test"},
732 "prednode": "ca819180edb99ed25ceafb3e9584ac287e240b00",
732 "prednode": "ca819180edb99ed25ceafb3e9584ac287e240b00",
733 "succnodes": ["1337133713371337133713371337133713371337"]
733 "succnodes": ["1337133713371337133713371337133713371337"]
734 },
734 },
735 {
735 {
736 "date": [1337.0, 0],
736 "date": [1337.0, 0],
737 "flag": 0,
737 "flag": 0,
738 "metadata": {"user": "test"},
738 "metadata": {"user": "test"},
739 "prednode": "cdbce2fbb16313928851e97e0d85413f3f7eb77f",
739 "prednode": "cdbce2fbb16313928851e97e0d85413f3f7eb77f",
740 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
740 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
741 },
741 },
742 {
742 {
743 "date": [0.0, 0],
743 "date": [0.0, 0],
744 "flag": 0,
744 "flag": 0,
745 "metadata": {"user": "test"},
745 "metadata": {"user": "test"},
746 "parentnodes": ["6f96419950729f3671185b847352890f074f7557"],
746 "parentnodes": ["6f96419950729f3671185b847352890f074f7557"],
747 "prednode": "94b33453f93bdb8d457ef9b770851a618bf413e1",
747 "prednode": "94b33453f93bdb8d457ef9b770851a618bf413e1",
748 "succnodes": []
748 "succnodes": []
749 },
749 },
750 {
750 {
751 "date": *, (glob)
751 "date": *, (glob)
752 "flag": 0,
752 "flag": 0,
753 "metadata": {"user": "test <test@example.net>"},
753 "metadata": {"user": "test <test@example.net>"},
754 "prednode": "cda648ca50f50482b7055c0b0c4c117bba6733d9",
754 "prednode": "cda648ca50f50482b7055c0b0c4c117bba6733d9",
755 "succnodes": ["3de5eca88c00aa039da7399a220f4a5221faa585"]
755 "succnodes": ["3de5eca88c00aa039da7399a220f4a5221faa585"]
756 }
756 }
757 ]
757 ]
758
758
759 Template keywords
759 Template keywords
760
760
761 $ hg debugobsolete -r6 -T '{succnodes % "{node|short}"} {date|shortdate}\n'
761 $ hg debugobsolete -r6 -T '{succnodes % "{node|short}"} {date|shortdate}\n'
762 3de5eca88c00 ????-??-?? (glob)
762 3de5eca88c00 ????-??-?? (glob)
763 $ hg debugobsolete -r6 -T '{join(metadata % "{key}={value}", " ")}\n'
763 $ hg debugobsolete -r6 -T '{join(metadata % "{key}={value}", " ")}\n'
764 user=test <test@example.net>
764 user=test <test@example.net>
765 $ hg debugobsolete -r6 -T '{metadata}\n{metadata}\n'
765 $ hg debugobsolete -r6 -T '{metadata}\n{metadata}\n'
766 'user': 'test <test@example.net>'
766 'user': 'test <test@example.net>'
767 'user': 'test <test@example.net>'
767 'user': 'test <test@example.net>'
768 $ hg debugobsolete -r6 -T '{succnodes}\n{succnodes}\n'
768 $ hg debugobsolete -r6 -T '{succnodes}\n{succnodes}\n'
769 3de5eca88c00aa039da7399a220f4a5221faa585
769 3de5eca88c00aa039da7399a220f4a5221faa585
770 3de5eca88c00aa039da7399a220f4a5221faa585
770 3de5eca88c00aa039da7399a220f4a5221faa585
771 $ hg debugobsolete -r6 -T '{flag} {get(metadata, "user")}\n'
771 $ hg debugobsolete -r6 -T '{flag} {get(metadata, "user")}\n'
772 0 test <test@example.net>
772 0 test <test@example.net>
773
773
774 Test the debug output for exchange
774 Test the debug output for exchange
775 ----------------------------------
775 ----------------------------------
776
776
777 $ hg pull ../tmpb --config 'experimental.obsmarkers-exchange-debug=True' # bundle2
777 $ hg pull ../tmpb --config 'experimental.obsmarkers-exchange-debug=True' # bundle2
778 pulling from ../tmpb
778 pulling from ../tmpb
779 searching for changes
779 searching for changes
780 no changes found
780 no changes found
781 obsmarker-exchange: 346 bytes received
781 obsmarker-exchange: 346 bytes received
782
782
783 check hgweb does not explode
783 check hgweb does not explode
784 ====================================
784 ====================================
785
785
786 $ hg unbundle $TESTDIR/bundles/hgweb+obs.hg
786 $ hg unbundle $TESTDIR/bundles/hgweb+obs.hg
787 adding changesets
787 adding changesets
788 adding manifests
788 adding manifests
789 adding file changes
789 adding file changes
790 added 62 changesets with 63 changes to 9 files (+60 heads)
790 added 62 changesets with 63 changes to 9 files (+60 heads)
791 new changesets 50c51b361e60:c15e9edfca13
791 new changesets 50c51b361e60:c15e9edfca13
792 (run 'hg heads .' to see heads, 'hg merge' to merge)
792 (run 'hg heads .' to see heads, 'hg merge' to merge)
793 $ for node in `hg log -r 'desc(babar_)' --template '{node}\n'`;
793 $ for node in `hg log -r 'desc(babar_)' --template '{node}\n'`;
794 > do
794 > do
795 > hg debugobsolete $node
795 > hg debugobsolete $node
796 > done
796 > done
797 obsoleted 1 changesets
797 obsoleted 1 changesets
798 obsoleted 1 changesets
798 obsoleted 1 changesets
799 obsoleted 1 changesets
799 obsoleted 1 changesets
800 obsoleted 1 changesets
800 obsoleted 1 changesets
801 obsoleted 1 changesets
801 obsoleted 1 changesets
802 obsoleted 1 changesets
802 obsoleted 1 changesets
803 obsoleted 1 changesets
803 obsoleted 1 changesets
804 obsoleted 1 changesets
804 obsoleted 1 changesets
805 obsoleted 1 changesets
805 obsoleted 1 changesets
806 obsoleted 1 changesets
806 obsoleted 1 changesets
807 obsoleted 1 changesets
807 obsoleted 1 changesets
808 obsoleted 1 changesets
808 obsoleted 1 changesets
809 obsoleted 1 changesets
809 obsoleted 1 changesets
810 obsoleted 1 changesets
810 obsoleted 1 changesets
811 obsoleted 1 changesets
811 obsoleted 1 changesets
812 obsoleted 1 changesets
812 obsoleted 1 changesets
813 obsoleted 1 changesets
813 obsoleted 1 changesets
814 obsoleted 1 changesets
814 obsoleted 1 changesets
815 obsoleted 1 changesets
815 obsoleted 1 changesets
816 obsoleted 1 changesets
816 obsoleted 1 changesets
817 obsoleted 1 changesets
817 obsoleted 1 changesets
818 obsoleted 1 changesets
818 obsoleted 1 changesets
819 obsoleted 1 changesets
819 obsoleted 1 changesets
820 obsoleted 1 changesets
820 obsoleted 1 changesets
821 obsoleted 1 changesets
821 obsoleted 1 changesets
822 obsoleted 1 changesets
822 obsoleted 1 changesets
823 obsoleted 1 changesets
823 obsoleted 1 changesets
824 obsoleted 1 changesets
824 obsoleted 1 changesets
825 obsoleted 1 changesets
825 obsoleted 1 changesets
826 obsoleted 1 changesets
826 obsoleted 1 changesets
827 obsoleted 1 changesets
827 obsoleted 1 changesets
828 obsoleted 1 changesets
828 obsoleted 1 changesets
829 obsoleted 1 changesets
829 obsoleted 1 changesets
830 obsoleted 1 changesets
830 obsoleted 1 changesets
831 obsoleted 1 changesets
831 obsoleted 1 changesets
832 obsoleted 1 changesets
832 obsoleted 1 changesets
833 obsoleted 1 changesets
833 obsoleted 1 changesets
834 obsoleted 1 changesets
834 obsoleted 1 changesets
835 obsoleted 1 changesets
835 obsoleted 1 changesets
836 obsoleted 1 changesets
836 obsoleted 1 changesets
837 obsoleted 1 changesets
837 obsoleted 1 changesets
838 obsoleted 1 changesets
838 obsoleted 1 changesets
839 obsoleted 1 changesets
839 obsoleted 1 changesets
840 obsoleted 1 changesets
840 obsoleted 1 changesets
841 obsoleted 1 changesets
841 obsoleted 1 changesets
842 obsoleted 1 changesets
842 obsoleted 1 changesets
843 obsoleted 1 changesets
843 obsoleted 1 changesets
844 obsoleted 1 changesets
844 obsoleted 1 changesets
845 obsoleted 1 changesets
845 obsoleted 1 changesets
846 obsoleted 1 changesets
846 obsoleted 1 changesets
847 obsoleted 1 changesets
847 obsoleted 1 changesets
848 obsoleted 1 changesets
848 obsoleted 1 changesets
849 obsoleted 1 changesets
849 obsoleted 1 changesets
850 obsoleted 1 changesets
850 obsoleted 1 changesets
851 obsoleted 1 changesets
851 obsoleted 1 changesets
852 obsoleted 1 changesets
852 obsoleted 1 changesets
853 obsoleted 1 changesets
853 obsoleted 1 changesets
854 obsoleted 1 changesets
854 obsoleted 1 changesets
855 obsoleted 1 changesets
855 obsoleted 1 changesets
856 obsoleted 1 changesets
856 obsoleted 1 changesets
857 $ hg up tip
857 $ hg up tip
858 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
858 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
859
859
860 #if serve
860 #if serve
861
861
862 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
862 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
863 $ cat hg.pid >> $DAEMON_PIDS
863 $ cat hg.pid >> $DAEMON_PIDS
864
864
865 check changelog view
865 check changelog view
866
866
867 $ get-with-headers.py --headeronly localhost:$HGPORT 'shortlog/'
867 $ get-with-headers.py --headeronly localhost:$HGPORT 'shortlog/'
868 200 Script output follows
868 200 Script output follows
869
869
870 check graph view
870 check graph view
871
871
872 $ get-with-headers.py --headeronly localhost:$HGPORT 'graph'
872 $ get-with-headers.py --headeronly localhost:$HGPORT 'graph'
873 200 Script output follows
873 200 Script output follows
874
874
875 check filelog view
875 check filelog view
876
876
877 $ get-with-headers.py --headeronly localhost:$HGPORT 'log/'`hg log -r . -T "{node}"`/'babar'
877 $ get-with-headers.py --headeronly localhost:$HGPORT 'log/'`hg log -r . -T "{node}"`/'babar'
878 200 Script output follows
878 200 Script output follows
879
879
880 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/68'
880 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/68'
881 200 Script output follows
881 200 Script output follows
882 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
882 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
883 404 Not Found
883 404 Not Found
884 [1]
884 [1]
885
885
886 check that web.view config option:
886 check that web.view config option:
887
887
888 $ killdaemons.py hg.pid
888 $ killdaemons.py hg.pid
889 $ cat >> .hg/hgrc << EOF
889 $ cat >> .hg/hgrc << EOF
890 > [web]
890 > [web]
891 > view=all
891 > view=all
892 > EOF
892 > EOF
893 $ wait
893 $ wait
894 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
894 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
895 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
895 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
896 200 Script output follows
896 200 Script output follows
897 $ killdaemons.py hg.pid
897 $ killdaemons.py hg.pid
898
898
899 Checking _enable=False warning if obsolete marker exists
899 Checking _enable=False warning if obsolete marker exists
900
900
901 $ echo '[experimental]' >> $HGRCPATH
901 $ echo '[experimental]' >> $HGRCPATH
902 $ echo "stabilization=" >> $HGRCPATH
902 $ echo "stabilization=" >> $HGRCPATH
903 $ hg log -r tip
903 $ hg log -r tip
904 obsolete feature not enabled but 68 markers found!
904 obsolete feature not enabled but 68 markers found!
905 68:c15e9edfca13 (draft) [tip ] add celestine
905 68:c15e9edfca13 (draft) [tip ] add celestine
906
906
907 reenable for later test
907 reenable for later test
908
908
909 $ echo '[experimental]' >> $HGRCPATH
909 $ echo '[experimental]' >> $HGRCPATH
910 $ echo "stabilization=createmarkers,exchange" >> $HGRCPATH
910 $ echo "stabilization=createmarkers,exchange" >> $HGRCPATH
911
911
912 $ rm hg.pid access.log errors.log
912 $ rm hg.pid access.log errors.log
913 #endif
913 #endif
914
914
915 Several troubles on the same changeset (create an unstable and bumped changeset)
915 Several troubles on the same changeset (create an unstable and bumped changeset)
916
916
917 $ hg debugobsolete `getid obsolete_e`
917 $ hg debugobsolete `getid obsolete_e`
918 obsoleted 1 changesets
918 obsoleted 1 changesets
919 $ hg debugobsolete `getid original_c` `getid babar`
919 $ hg debugobsolete `getid original_c` `getid babar`
920 $ hg log --config ui.logtemplate= -r 'phasedivergent() and orphan()'
920 $ hg log --config ui.logtemplate= -r 'phasedivergent() and orphan()'
921 changeset: 7:50c51b361e60
921 changeset: 7:50c51b361e60
922 user: test
922 user: test
923 date: Thu Jan 01 00:00:00 1970 +0000
923 date: Thu Jan 01 00:00:00 1970 +0000
924 instability: orphan, phase-divergent
924 instability: orphan, phase-divergent
925 summary: add babar
925 summary: add babar
926
926
927
927
928 test the "obsolete" templatekw
928 test the "obsolete" templatekw
929
929
930 $ hg log -r 'obsolete()'
930 $ hg log -r 'obsolete()'
931 6:3de5eca88c00 (draft *obsolete*) [ ] add obsolete_e
931 6:3de5eca88c00 (draft *obsolete*) [ ] add obsolete_e [pruned by test (at 1970-01-01 00:00 +0000)]
932
932
933 test the "troubles" templatekw
933 test the "troubles" templatekw
934
934
935 $ hg log -r 'phasedivergent() and orphan()'
935 $ hg log -r 'phasedivergent() and orphan()'
936 7:50c51b361e60 (draft orphan phase-divergent) [ ] add babar
936 7:50c51b361e60 (draft orphan phase-divergent) [ ] add babar
937
937
938 test the default cmdline template
938 test the default cmdline template
939
939
940 $ hg log -T default -r 'phasedivergent()'
940 $ hg log -T default -r 'phasedivergent()'
941 changeset: 7:50c51b361e60
941 changeset: 7:50c51b361e60
942 user: test
942 user: test
943 date: Thu Jan 01 00:00:00 1970 +0000
943 date: Thu Jan 01 00:00:00 1970 +0000
944 instability: orphan, phase-divergent
944 instability: orphan, phase-divergent
945 summary: add babar
945 summary: add babar
946
946
947 $ hg log -T default -r 'obsolete()'
947 $ hg log -T default -r 'obsolete()'
948 changeset: 6:3de5eca88c00
948 changeset: 6:3de5eca88c00
949 parent: 3:6f9641995072
949 parent: 3:6f9641995072
950 user: test
950 user: test
951 date: Thu Jan 01 00:00:00 1970 +0000
951 date: Thu Jan 01 00:00:00 1970 +0000
952 summary: add obsolete_e
952 summary: add obsolete_e
953
953
954
954
955 test the obsolete labels
955 test the obsolete labels
956
956
957 $ hg log --config ui.logtemplate= --color=debug -r 'phasedivergent()'
957 $ hg log --config ui.logtemplate= --color=debug -r 'phasedivergent()'
958 [log.changeset changeset.draft changeset.unstable instability.orphan instability.phase-divergent|changeset: 7:50c51b361e60]
958 [log.changeset changeset.draft changeset.unstable instability.orphan instability.phase-divergent|changeset: 7:50c51b361e60]
959 [log.user|user: test]
959 [log.user|user: test]
960 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
960 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
961 [log.instability|instability: orphan, phase-divergent]
961 [log.instability|instability: orphan, phase-divergent]
962 [log.summary|summary: add babar]
962 [log.summary|summary: add babar]
963
963
964
964
965 $ hg log -T default -r 'phasedivergent()' --color=debug
965 $ hg log -T default -r 'phasedivergent()' --color=debug
966 [log.changeset changeset.draft changeset.unstable instability.orphan instability.phase-divergent|changeset: 7:50c51b361e60]
966 [log.changeset changeset.draft changeset.unstable instability.orphan instability.phase-divergent|changeset: 7:50c51b361e60]
967 [log.user|user: test]
967 [log.user|user: test]
968 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
968 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
969 [log.instability|instability: orphan, phase-divergent]
969 [log.instability|instability: orphan, phase-divergent]
970 [log.summary|summary: add babar]
970 [log.summary|summary: add babar]
971
971
972
972
973 $ hg log --config ui.logtemplate= --color=debug -r "obsolete()"
973 $ hg log --config ui.logtemplate= --color=debug -r "obsolete()"
974 [log.changeset changeset.draft changeset.obsolete|changeset: 6:3de5eca88c00]
974 [log.changeset changeset.draft changeset.obsolete|changeset: 6:3de5eca88c00]
975 [log.parent changeset.draft|parent: 3:6f9641995072]
975 [log.parent changeset.draft|parent: 3:6f9641995072]
976 [log.user|user: test]
976 [log.user|user: test]
977 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
977 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
978 [log.summary|summary: add obsolete_e]
978 [log.summary|summary: add obsolete_e]
979
979
980
980
981 $ hg log -T default -r 'obsolete()' --color=debug
981 $ hg log -T default -r 'obsolete()' --color=debug
982 [log.changeset changeset.draft changeset.obsolete|changeset: 6:3de5eca88c00]
982 [log.changeset changeset.draft changeset.obsolete|changeset: 6:3de5eca88c00]
983 [log.parent changeset.draft|parent: 3:6f9641995072]
983 [log.parent changeset.draft|parent: 3:6f9641995072]
984 [log.user|user: test]
984 [log.user|user: test]
985 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
985 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
986 [log.summary|summary: add obsolete_e]
986 [log.summary|summary: add obsolete_e]
987
987
988
988
989 test summary output
989 test summary output
990
990
991 $ hg up -r 'phasedivergent() and orphan()'
991 $ hg up -r 'phasedivergent() and orphan()'
992 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
992 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
993 $ hg summary
993 $ hg summary
994 parent: 7:50c51b361e60 (orphan, phase-divergent)
994 parent: 7:50c51b361e60 (orphan, phase-divergent)
995 add babar
995 add babar
996 branch: default
996 branch: default
997 commit: (clean)
997 commit: (clean)
998 update: 2 new changesets (update)
998 update: 2 new changesets (update)
999 phases: 4 draft
999 phases: 4 draft
1000 orphan: 2 changesets
1000 orphan: 2 changesets
1001 phase-divergent: 1 changesets
1001 phase-divergent: 1 changesets
1002 $ hg up -r 'obsolete()'
1002 $ hg up -r 'obsolete()'
1003 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1003 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1004 $ hg summary
1004 $ hg summary
1005 parent: 6:3de5eca88c00 (obsolete)
1005 parent: 6:3de5eca88c00 (obsolete)
1006 add obsolete_e
1006 add obsolete_e
1007 branch: default
1007 branch: default
1008 commit: (clean)
1008 commit: (clean)
1009 update: 3 new changesets (update)
1009 update: 3 new changesets (update)
1010 phases: 4 draft
1010 phases: 4 draft
1011 orphan: 2 changesets
1011 orphan: 2 changesets
1012 phase-divergent: 1 changesets
1012 phase-divergent: 1 changesets
1013
1013
1014 Test incoming/outcoming with changesets obsoleted remotely, known locally
1014 Test incoming/outcoming with changesets obsoleted remotely, known locally
1015 ===============================================================================
1015 ===============================================================================
1016
1016
1017 This test issue 3805
1017 This test issue 3805
1018
1018
1019 $ hg init repo-issue3805
1019 $ hg init repo-issue3805
1020 $ cd repo-issue3805
1020 $ cd repo-issue3805
1021 $ echo "base" > base
1021 $ echo "base" > base
1022 $ hg ci -Am "base"
1022 $ hg ci -Am "base"
1023 adding base
1023 adding base
1024 $ echo "foo" > foo
1024 $ echo "foo" > foo
1025 $ hg ci -Am "A"
1025 $ hg ci -Am "A"
1026 adding foo
1026 adding foo
1027 $ hg clone . ../other-issue3805
1027 $ hg clone . ../other-issue3805
1028 updating to branch default
1028 updating to branch default
1029 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1029 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1030 $ echo "bar" >> foo
1030 $ echo "bar" >> foo
1031 $ hg ci --amend
1031 $ hg ci --amend
1032 $ cd ../other-issue3805
1032 $ cd ../other-issue3805
1033 $ hg log -G
1033 $ hg log -G
1034 @ 1:29f0c6921ddd (draft) [tip ] A
1034 @ 1:29f0c6921ddd (draft) [tip ] A
1035 |
1035 |
1036 o 0:d20a80d4def3 (draft) [ ] base
1036 o 0:d20a80d4def3 (draft) [ ] base
1037
1037
1038 $ hg log -G -R ../repo-issue3805
1038 $ hg log -G -R ../repo-issue3805
1039 @ 2:323a9c3ddd91 (draft) [tip ] A
1039 @ 2:323a9c3ddd91 (draft) [tip ] A
1040 |
1040 |
1041 o 0:d20a80d4def3 (draft) [ ] base
1041 o 0:d20a80d4def3 (draft) [ ] base
1042
1042
1043 $ hg incoming
1043 $ hg incoming
1044 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
1044 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
1045 searching for changes
1045 searching for changes
1046 2:323a9c3ddd91 (draft) [tip ] A
1046 2:323a9c3ddd91 (draft) [tip ] A
1047 $ hg incoming --bundle ../issue3805.hg
1047 $ hg incoming --bundle ../issue3805.hg
1048 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
1048 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
1049 searching for changes
1049 searching for changes
1050 2:323a9c3ddd91 (draft) [tip ] A
1050 2:323a9c3ddd91 (draft) [tip ] A
1051 $ hg outgoing
1051 $ hg outgoing
1052 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
1052 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
1053 searching for changes
1053 searching for changes
1054 1:29f0c6921ddd (draft) [tip ] A
1054 1:29f0c6921ddd (draft) [tip ] A
1055
1055
1056 #if serve
1056 #if serve
1057
1057
1058 $ hg serve -R ../repo-issue3805 -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1058 $ hg serve -R ../repo-issue3805 -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1059 $ cat hg.pid >> $DAEMON_PIDS
1059 $ cat hg.pid >> $DAEMON_PIDS
1060
1060
1061 $ hg incoming http://localhost:$HGPORT
1061 $ hg incoming http://localhost:$HGPORT
1062 comparing with http://localhost:$HGPORT/
1062 comparing with http://localhost:$HGPORT/
1063 searching for changes
1063 searching for changes
1064 2:323a9c3ddd91 (draft) [tip ] A
1064 2:323a9c3ddd91 (draft) [tip ] A
1065 $ hg outgoing http://localhost:$HGPORT
1065 $ hg outgoing http://localhost:$HGPORT
1066 comparing with http://localhost:$HGPORT/
1066 comparing with http://localhost:$HGPORT/
1067 searching for changes
1067 searching for changes
1068 1:29f0c6921ddd (draft) [tip ] A
1068 1:29f0c6921ddd (draft) [tip ] A
1069
1069
1070 $ killdaemons.py
1070 $ killdaemons.py
1071
1071
1072 #endif
1072 #endif
1073
1073
1074 This test issue 3814
1074 This test issue 3814
1075
1075
1076 (nothing to push but locally hidden changeset)
1076 (nothing to push but locally hidden changeset)
1077
1077
1078 $ cd ..
1078 $ cd ..
1079 $ hg init repo-issue3814
1079 $ hg init repo-issue3814
1080 $ cd repo-issue3805
1080 $ cd repo-issue3805
1081 $ hg push -r 323a9c3ddd91 ../repo-issue3814
1081 $ hg push -r 323a9c3ddd91 ../repo-issue3814
1082 pushing to ../repo-issue3814
1082 pushing to ../repo-issue3814
1083 searching for changes
1083 searching for changes
1084 adding changesets
1084 adding changesets
1085 adding manifests
1085 adding manifests
1086 adding file changes
1086 adding file changes
1087 added 2 changesets with 2 changes to 2 files
1087 added 2 changesets with 2 changes to 2 files
1088 1 new obsolescence markers
1088 1 new obsolescence markers
1089 $ hg out ../repo-issue3814
1089 $ hg out ../repo-issue3814
1090 comparing with ../repo-issue3814
1090 comparing with ../repo-issue3814
1091 searching for changes
1091 searching for changes
1092 no changes found
1092 no changes found
1093 [1]
1093 [1]
1094
1094
1095 Test that a local tag blocks a changeset from being hidden
1095 Test that a local tag blocks a changeset from being hidden
1096
1096
1097 $ hg tag -l visible -r 1 --hidden
1097 $ hg tag -l visible -r 1 --hidden
1098 $ hg log -G
1098 $ hg log -G
1099 @ 2:323a9c3ddd91 (draft) [tip ] A
1099 @ 2:323a9c3ddd91 (draft) [tip ] A
1100 |
1100 |
1101 | x 1:29f0c6921ddd (draft *obsolete*) [visible ] A
1101 | x 1:29f0c6921ddd (draft *obsolete*) [visible ] A [rewritten using amend as 2:323a9c3ddd91 by test (at 1970-01-01 00:00 +0000)]
1102 |/
1102 |/
1103 o 0:d20a80d4def3 (draft) [ ] base
1103 o 0:d20a80d4def3 (draft) [ ] base
1104
1104
1105 Test that removing a local tag does not cause some commands to fail
1105 Test that removing a local tag does not cause some commands to fail
1106
1106
1107 $ hg tag -l -r tip tiptag
1107 $ hg tag -l -r tip tiptag
1108 $ hg tags
1108 $ hg tags
1109 tiptag 2:323a9c3ddd91
1109 tiptag 2:323a9c3ddd91
1110 tip 2:323a9c3ddd91
1110 tip 2:323a9c3ddd91
1111 visible 1:29f0c6921ddd
1111 visible 1:29f0c6921ddd
1112 $ hg --config extensions.strip= strip -r tip --no-backup
1112 $ hg --config extensions.strip= strip -r tip --no-backup
1113 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1113 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1114 $ hg tags
1114 $ hg tags
1115 visible 1:29f0c6921ddd
1115 visible 1:29f0c6921ddd
1116 tip 1:29f0c6921ddd
1116 tip 1:29f0c6921ddd
1117
1117
1118 Test bundle overlay onto hidden revision
1118 Test bundle overlay onto hidden revision
1119
1119
1120 $ cd ..
1120 $ cd ..
1121 $ hg init repo-bundleoverlay
1121 $ hg init repo-bundleoverlay
1122 $ cd repo-bundleoverlay
1122 $ cd repo-bundleoverlay
1123 $ echo "A" > foo
1123 $ echo "A" > foo
1124 $ hg ci -Am "A"
1124 $ hg ci -Am "A"
1125 adding foo
1125 adding foo
1126 $ echo "B" >> foo
1126 $ echo "B" >> foo
1127 $ hg ci -m "B"
1127 $ hg ci -m "B"
1128 $ hg up 0
1128 $ hg up 0
1129 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1129 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1130 $ echo "C" >> foo
1130 $ echo "C" >> foo
1131 $ hg ci -m "C"
1131 $ hg ci -m "C"
1132 created new head
1132 created new head
1133 $ hg log -G
1133 $ hg log -G
1134 @ 2:c186d7714947 (draft) [tip ] C
1134 @ 2:c186d7714947 (draft) [tip ] C
1135 |
1135 |
1136 | o 1:44526ebb0f98 (draft) [ ] B
1136 | o 1:44526ebb0f98 (draft) [ ] B
1137 |/
1137 |/
1138 o 0:4b34ecfb0d56 (draft) [ ] A
1138 o 0:4b34ecfb0d56 (draft) [ ] A
1139
1139
1140
1140
1141 $ hg clone -r1 . ../other-bundleoverlay
1141 $ hg clone -r1 . ../other-bundleoverlay
1142 adding changesets
1142 adding changesets
1143 adding manifests
1143 adding manifests
1144 adding file changes
1144 adding file changes
1145 added 2 changesets with 2 changes to 1 files
1145 added 2 changesets with 2 changes to 1 files
1146 new changesets 4b34ecfb0d56:44526ebb0f98
1146 new changesets 4b34ecfb0d56:44526ebb0f98
1147 updating to branch default
1147 updating to branch default
1148 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1148 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1149 $ cd ../other-bundleoverlay
1149 $ cd ../other-bundleoverlay
1150 $ echo "B+" >> foo
1150 $ echo "B+" >> foo
1151 $ hg ci --amend -m "B+"
1151 $ hg ci --amend -m "B+"
1152 $ hg log -G --hidden
1152 $ hg log -G --hidden
1153 @ 2:b7d587542d40 (draft) [tip ] B+
1153 @ 2:b7d587542d40 (draft) [tip ] B+
1154 |
1154 |
1155 | x 1:44526ebb0f98 (draft *obsolete*) [ ] B
1155 | x 1:44526ebb0f98 (draft *obsolete*) [ ] B [rewritten using amend as 2:b7d587542d40 by test (at 1970-01-01 00:00 +0000)]
1156 |/
1156 |/
1157 o 0:4b34ecfb0d56 (draft) [ ] A
1157 o 0:4b34ecfb0d56 (draft) [ ] A
1158
1158
1159
1159
1160 $ hg incoming ../repo-bundleoverlay --bundle ../bundleoverlay.hg
1160 $ hg incoming ../repo-bundleoverlay --bundle ../bundleoverlay.hg
1161 comparing with ../repo-bundleoverlay
1161 comparing with ../repo-bundleoverlay
1162 searching for changes
1162 searching for changes
1163 1:44526ebb0f98 (draft) [ ] B
1163 1:44526ebb0f98 (draft) [ ] B
1164 2:c186d7714947 (draft) [tip ] C
1164 2:c186d7714947 (draft) [tip ] C
1165 $ hg log -G -R ../bundleoverlay.hg
1165 $ hg log -G -R ../bundleoverlay.hg
1166 o 3:c186d7714947 (draft) [tip ] C
1166 o 3:c186d7714947 (draft) [tip ] C
1167 |
1167 |
1168 | @ 2:b7d587542d40 (draft) [ ] B+
1168 | @ 2:b7d587542d40 (draft) [ ] B+
1169 |/
1169 |/
1170 o 0:4b34ecfb0d56 (draft) [ ] A
1170 o 0:4b34ecfb0d56 (draft) [ ] A
1171
1171
1172
1172
1173 #if serve
1173 #if serve
1174
1174
1175 Test issue 4506
1175 Test issue 4506
1176
1176
1177 $ cd ..
1177 $ cd ..
1178 $ hg init repo-issue4506
1178 $ hg init repo-issue4506
1179 $ cd repo-issue4506
1179 $ cd repo-issue4506
1180 $ echo "0" > foo
1180 $ echo "0" > foo
1181 $ hg add foo
1181 $ hg add foo
1182 $ hg ci -m "content-0"
1182 $ hg ci -m "content-0"
1183
1183
1184 $ hg up null
1184 $ hg up null
1185 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1185 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1186 $ echo "1" > bar
1186 $ echo "1" > bar
1187 $ hg add bar
1187 $ hg add bar
1188 $ hg ci -m "content-1"
1188 $ hg ci -m "content-1"
1189 created new head
1189 created new head
1190 $ hg up 0
1190 $ hg up 0
1191 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1191 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1192 $ hg graft 1
1192 $ hg graft 1
1193 grafting 1:1c9eddb02162 "content-1" (tip)
1193 grafting 1:1c9eddb02162 "content-1" (tip)
1194
1194
1195 $ hg debugobsolete `hg log -r1 -T'{node}'` `hg log -r2 -T'{node}'`
1195 $ hg debugobsolete `hg log -r1 -T'{node}'` `hg log -r2 -T'{node}'`
1196 obsoleted 1 changesets
1196 obsoleted 1 changesets
1197
1197
1198 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1198 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1199 $ cat hg.pid >> $DAEMON_PIDS
1199 $ cat hg.pid >> $DAEMON_PIDS
1200
1200
1201 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/1'
1201 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/1'
1202 404 Not Found
1202 404 Not Found
1203 [1]
1203 [1]
1204 $ get-with-headers.py --headeronly localhost:$HGPORT 'file/tip/bar'
1204 $ get-with-headers.py --headeronly localhost:$HGPORT 'file/tip/bar'
1205 200 Script output follows
1205 200 Script output follows
1206 $ get-with-headers.py --headeronly localhost:$HGPORT 'annotate/tip/bar'
1206 $ get-with-headers.py --headeronly localhost:$HGPORT 'annotate/tip/bar'
1207 200 Script output follows
1207 200 Script output follows
1208
1208
1209 $ killdaemons.py
1209 $ killdaemons.py
1210
1210
1211 #endif
1211 #endif
1212
1212
1213 Test heads computation on pending index changes with obsolescence markers
1213 Test heads computation on pending index changes with obsolescence markers
1214 $ cd ..
1214 $ cd ..
1215 $ cat >$TESTTMP/test_extension.py << EOF
1215 $ cat >$TESTTMP/test_extension.py << EOF
1216 > from __future__ import absolute_import
1216 > from __future__ import absolute_import
1217 > from mercurial.i18n import _
1217 > from mercurial.i18n import _
1218 > from mercurial import cmdutil, registrar
1218 > from mercurial import cmdutil, registrar
1219 >
1219 >
1220 > cmdtable = {}
1220 > cmdtable = {}
1221 > command = registrar.command(cmdtable)
1221 > command = registrar.command(cmdtable)
1222 > @command(b"amendtransient",[], _('hg amendtransient [rev]'))
1222 > @command(b"amendtransient",[], _('hg amendtransient [rev]'))
1223 > def amend(ui, repo, *pats, **opts):
1223 > def amend(ui, repo, *pats, **opts):
1224 > opts['message'] = 'Test'
1224 > opts['message'] = 'Test'
1225 > opts['logfile'] = None
1225 > opts['logfile'] = None
1226 > cmdutil.amend(ui, repo, repo['.'], {}, pats, opts)
1226 > cmdutil.amend(ui, repo, repo['.'], {}, pats, opts)
1227 > ui.write('%s\n' % repo.changelog.headrevs())
1227 > ui.write('%s\n' % repo.changelog.headrevs())
1228 > EOF
1228 > EOF
1229 $ cat >> $HGRCPATH << EOF
1229 $ cat >> $HGRCPATH << EOF
1230 > [extensions]
1230 > [extensions]
1231 > testextension=$TESTTMP/test_extension.py
1231 > testextension=$TESTTMP/test_extension.py
1232 > EOF
1232 > EOF
1233 $ hg init repo-issue-nativerevs-pending-changes
1233 $ hg init repo-issue-nativerevs-pending-changes
1234 $ cd repo-issue-nativerevs-pending-changes
1234 $ cd repo-issue-nativerevs-pending-changes
1235 $ mkcommit a
1235 $ mkcommit a
1236 $ mkcommit b
1236 $ mkcommit b
1237 $ hg up ".^"
1237 $ hg up ".^"
1238 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1238 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1239 $ echo aa > a
1239 $ echo aa > a
1240 $ hg amendtransient
1240 $ hg amendtransient
1241 [1, 2]
1241 [1, 2]
1242
1242
1243 Test cache consistency for the visible filter
1243 Test cache consistency for the visible filter
1244 1) We want to make sure that the cached filtered revs are invalidated when
1244 1) We want to make sure that the cached filtered revs are invalidated when
1245 bookmarks change
1245 bookmarks change
1246 $ cd ..
1246 $ cd ..
1247 $ cat >$TESTTMP/test_extension.py << EOF
1247 $ cat >$TESTTMP/test_extension.py << EOF
1248 > from __future__ import absolute_import, print_function
1248 > from __future__ import absolute_import, print_function
1249 > import weakref
1249 > import weakref
1250 > from mercurial import (
1250 > from mercurial import (
1251 > bookmarks,
1251 > bookmarks,
1252 > cmdutil,
1252 > cmdutil,
1253 > extensions,
1253 > extensions,
1254 > repoview,
1254 > repoview,
1255 > )
1255 > )
1256 > def _bookmarkchanged(orig, bkmstoreinst, *args, **kwargs):
1256 > def _bookmarkchanged(orig, bkmstoreinst, *args, **kwargs):
1257 > reporef = weakref.ref(bkmstoreinst._repo)
1257 > reporef = weakref.ref(bkmstoreinst._repo)
1258 > def trhook(tr):
1258 > def trhook(tr):
1259 > repo = reporef()
1259 > repo = reporef()
1260 > hidden1 = repoview.computehidden(repo)
1260 > hidden1 = repoview.computehidden(repo)
1261 > hidden = repoview.filterrevs(repo, 'visible')
1261 > hidden = repoview.filterrevs(repo, 'visible')
1262 > if sorted(hidden1) != sorted(hidden):
1262 > if sorted(hidden1) != sorted(hidden):
1263 > print("cache inconsistency")
1263 > print("cache inconsistency")
1264 > bkmstoreinst._repo.currenttransaction().addpostclose('test_extension', trhook)
1264 > bkmstoreinst._repo.currenttransaction().addpostclose('test_extension', trhook)
1265 > orig(bkmstoreinst, *args, **kwargs)
1265 > orig(bkmstoreinst, *args, **kwargs)
1266 > def extsetup(ui):
1266 > def extsetup(ui):
1267 > extensions.wrapfunction(bookmarks.bmstore, '_recordchange',
1267 > extensions.wrapfunction(bookmarks.bmstore, '_recordchange',
1268 > _bookmarkchanged)
1268 > _bookmarkchanged)
1269 > EOF
1269 > EOF
1270
1270
1271 $ hg init repo-cache-inconsistency
1271 $ hg init repo-cache-inconsistency
1272 $ cd repo-issue-nativerevs-pending-changes
1272 $ cd repo-issue-nativerevs-pending-changes
1273 $ mkcommit a
1273 $ mkcommit a
1274 a already tracked!
1274 a already tracked!
1275 $ mkcommit b
1275 $ mkcommit b
1276 $ hg id
1276 $ hg id
1277 13bedc178fce tip
1277 13bedc178fce tip
1278 $ echo "hello" > b
1278 $ echo "hello" > b
1279 $ hg commit --amend -m "message"
1279 $ hg commit --amend -m "message"
1280 $ hg book bookb -r 13bedc178fce --hidden
1280 $ hg book bookb -r 13bedc178fce --hidden
1281 $ hg log -r 13bedc178fce
1281 $ hg log -r 13bedc178fce
1282 4:13bedc178fce (draft *obsolete*) [ bookb] add b
1282 4:13bedc178fce (draft *obsolete*) [ bookb] add b [rewritten using amend as 5:a9b1f8652753 by test (at 1970-01-01 00:00 +0000)]
1283 $ hg book -d bookb
1283 $ hg book -d bookb
1284 $ hg log -r 13bedc178fce
1284 $ hg log -r 13bedc178fce
1285 abort: hidden revision '13bedc178fce'!
1285 abort: hidden revision '13bedc178fce'!
1286 (use --hidden to access hidden revisions)
1286 (use --hidden to access hidden revisions)
1287 [255]
1287 [255]
1288
1288
1289 Empty out the test extension, as it isn't compatible with later parts
1289 Empty out the test extension, as it isn't compatible with later parts
1290 of the test.
1290 of the test.
1291 $ echo > $TESTTMP/test_extension.py
1291 $ echo > $TESTTMP/test_extension.py
1292
1292
1293 Test ability to pull changeset with locally applying obsolescence markers
1293 Test ability to pull changeset with locally applying obsolescence markers
1294 (issue4945)
1294 (issue4945)
1295
1295
1296 $ cd ..
1296 $ cd ..
1297 $ hg init issue4845
1297 $ hg init issue4845
1298 $ cd issue4845
1298 $ cd issue4845
1299
1299
1300 $ echo foo > f0
1300 $ echo foo > f0
1301 $ hg add f0
1301 $ hg add f0
1302 $ hg ci -m '0'
1302 $ hg ci -m '0'
1303 $ echo foo > f1
1303 $ echo foo > f1
1304 $ hg add f1
1304 $ hg add f1
1305 $ hg ci -m '1'
1305 $ hg ci -m '1'
1306 $ echo foo > f2
1306 $ echo foo > f2
1307 $ hg add f2
1307 $ hg add f2
1308 $ hg ci -m '2'
1308 $ hg ci -m '2'
1309
1309
1310 $ echo bar > f2
1310 $ echo bar > f2
1311 $ hg commit --amend --config experimetnal.stabilization=createmarkers
1311 $ hg commit --amend --config experimetnal.stabilization=createmarkers
1312 $ hg log -G
1312 $ hg log -G
1313 @ 3:b0551702f918 (draft) [tip ] 2
1313 @ 3:b0551702f918 (draft) [tip ] 2
1314 |
1314 |
1315 o 1:e016b03fd86f (draft) [ ] 1
1315 o 1:e016b03fd86f (draft) [ ] 1
1316 |
1316 |
1317 o 0:a78f55e5508c (draft) [ ] 0
1317 o 0:a78f55e5508c (draft) [ ] 0
1318
1318
1319 $ hg log -G --hidden
1319 $ hg log -G --hidden
1320 @ 3:b0551702f918 (draft) [tip ] 2
1320 @ 3:b0551702f918 (draft) [tip ] 2
1321 |
1321 |
1322 | x 2:e008cf283490 (draft *obsolete*) [ ] 2
1322 | x 2:e008cf283490 (draft *obsolete*) [ ] 2 [rewritten using amend as 3:b0551702f918 by test (at 1970-01-01 00:00 +0000)]
1323 |/
1323 |/
1324 o 1:e016b03fd86f (draft) [ ] 1
1324 o 1:e016b03fd86f (draft) [ ] 1
1325 |
1325 |
1326 o 0:a78f55e5508c (draft) [ ] 0
1326 o 0:a78f55e5508c (draft) [ ] 0
1327
1327
1328
1328
1329 $ hg strip --hidden -r 2 --config extensions.strip= --config devel.strip-obsmarkers=no
1329 $ hg strip --hidden -r 2 --config extensions.strip= --config devel.strip-obsmarkers=no
1330 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e008cf283490-ede36964-backup.hg (glob)
1330 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e008cf283490-ede36964-backup.hg (glob)
1331 $ hg debugobsolete
1331 $ hg debugobsolete
1332 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1332 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1333 $ hg log -G
1333 $ hg log -G
1334 @ 2:b0551702f918 (draft) [tip ] 2
1334 @ 2:b0551702f918 (draft) [tip ] 2
1335 |
1335 |
1336 o 1:e016b03fd86f (draft) [ ] 1
1336 o 1:e016b03fd86f (draft) [ ] 1
1337 |
1337 |
1338 o 0:a78f55e5508c (draft) [ ] 0
1338 o 0:a78f55e5508c (draft) [ ] 0
1339
1339
1340 $ hg log -G --hidden
1340 $ hg log -G --hidden
1341 @ 2:b0551702f918 (draft) [tip ] 2
1341 @ 2:b0551702f918 (draft) [tip ] 2
1342 |
1342 |
1343 o 1:e016b03fd86f (draft) [ ] 1
1343 o 1:e016b03fd86f (draft) [ ] 1
1344 |
1344 |
1345 o 0:a78f55e5508c (draft) [ ] 0
1345 o 0:a78f55e5508c (draft) [ ] 0
1346
1346
1347 $ hg debugbundle .hg/strip-backup/e008cf283490-*-backup.hg
1347 $ hg debugbundle .hg/strip-backup/e008cf283490-*-backup.hg
1348 Stream params: {Compression: BZ}
1348 Stream params: {Compression: BZ}
1349 changegroup -- {nbchanges: 1, version: 02}
1349 changegroup -- {nbchanges: 1, version: 02}
1350 e008cf2834908e5d6b0f792a9d4b0e2272260fb8
1350 e008cf2834908e5d6b0f792a9d4b0e2272260fb8
1351 phase-heads -- {}
1351 phase-heads -- {}
1352 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 draft
1352 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 draft
1353
1353
1354 $ hg pull .hg/strip-backup/e008cf283490-*-backup.hg
1354 $ hg pull .hg/strip-backup/e008cf283490-*-backup.hg
1355 pulling from .hg/strip-backup/e008cf283490-ede36964-backup.hg
1355 pulling from .hg/strip-backup/e008cf283490-ede36964-backup.hg
1356 searching for changes
1356 searching for changes
1357 no changes found
1357 no changes found
1358 $ hg debugobsolete
1358 $ hg debugobsolete
1359 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1359 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1360 $ hg log -G
1360 $ hg log -G
1361 @ 2:b0551702f918 (draft) [tip ] 2
1361 @ 2:b0551702f918 (draft) [tip ] 2
1362 |
1362 |
1363 o 1:e016b03fd86f (draft) [ ] 1
1363 o 1:e016b03fd86f (draft) [ ] 1
1364 |
1364 |
1365 o 0:a78f55e5508c (draft) [ ] 0
1365 o 0:a78f55e5508c (draft) [ ] 0
1366
1366
1367 $ hg log -G --hidden
1367 $ hg log -G --hidden
1368 @ 2:b0551702f918 (draft) [tip ] 2
1368 @ 2:b0551702f918 (draft) [tip ] 2
1369 |
1369 |
1370 o 1:e016b03fd86f (draft) [ ] 1
1370 o 1:e016b03fd86f (draft) [ ] 1
1371 |
1371 |
1372 o 0:a78f55e5508c (draft) [ ] 0
1372 o 0:a78f55e5508c (draft) [ ] 0
1373
1373
1374
1374
1375 Testing that strip remove markers:
1375 Testing that strip remove markers:
1376
1376
1377 $ hg strip -r 1 --config extensions.strip=
1377 $ hg strip -r 1 --config extensions.strip=
1378 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1378 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1379 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e016b03fd86f-65ede734-backup.hg (glob)
1379 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e016b03fd86f-65ede734-backup.hg (glob)
1380 $ hg debugobsolete
1380 $ hg debugobsolete
1381 $ hg log -G
1381 $ hg log -G
1382 @ 0:a78f55e5508c (draft) [tip ] 0
1382 @ 0:a78f55e5508c (draft) [tip ] 0
1383
1383
1384 $ hg log -G --hidden
1384 $ hg log -G --hidden
1385 @ 0:a78f55e5508c (draft) [tip ] 0
1385 @ 0:a78f55e5508c (draft) [tip ] 0
1386
1386
1387 $ hg debugbundle .hg/strip-backup/e016b03fd86f-*-backup.hg
1387 $ hg debugbundle .hg/strip-backup/e016b03fd86f-*-backup.hg
1388 Stream params: {Compression: BZ}
1388 Stream params: {Compression: BZ}
1389 changegroup -- {nbchanges: 2, version: 02}
1389 changegroup -- {nbchanges: 2, version: 02}
1390 e016b03fd86fcccc54817d120b90b751aaf367d6
1390 e016b03fd86fcccc54817d120b90b751aaf367d6
1391 b0551702f918510f01ae838ab03a463054c67b46
1391 b0551702f918510f01ae838ab03a463054c67b46
1392 obsmarkers -- {}
1392 obsmarkers -- {}
1393 version: 1 (86 bytes)
1393 version: 1 (86 bytes)
1394 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1394 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1395 phase-heads -- {}
1395 phase-heads -- {}
1396 b0551702f918510f01ae838ab03a463054c67b46 draft
1396 b0551702f918510f01ae838ab03a463054c67b46 draft
1397
1397
1398 $ hg unbundle .hg/strip-backup/e016b03fd86f-*-backup.hg
1398 $ hg unbundle .hg/strip-backup/e016b03fd86f-*-backup.hg
1399 adding changesets
1399 adding changesets
1400 adding manifests
1400 adding manifests
1401 adding file changes
1401 adding file changes
1402 added 2 changesets with 2 changes to 2 files
1402 added 2 changesets with 2 changes to 2 files
1403 1 new obsolescence markers
1403 1 new obsolescence markers
1404 new changesets e016b03fd86f:b0551702f918
1404 new changesets e016b03fd86f:b0551702f918
1405 (run 'hg update' to get a working copy)
1405 (run 'hg update' to get a working copy)
1406 $ hg debugobsolete | sort
1406 $ hg debugobsolete | sort
1407 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1407 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1408 $ hg log -G
1408 $ hg log -G
1409 o 2:b0551702f918 (draft) [tip ] 2
1409 o 2:b0551702f918 (draft) [tip ] 2
1410 |
1410 |
1411 o 1:e016b03fd86f (draft) [ ] 1
1411 o 1:e016b03fd86f (draft) [ ] 1
1412 |
1412 |
1413 @ 0:a78f55e5508c (draft) [ ] 0
1413 @ 0:a78f55e5508c (draft) [ ] 0
1414
1414
1415 $ hg log -G --hidden
1415 $ hg log -G --hidden
1416 o 2:b0551702f918 (draft) [tip ] 2
1416 o 2:b0551702f918 (draft) [tip ] 2
1417 |
1417 |
1418 o 1:e016b03fd86f (draft) [ ] 1
1418 o 1:e016b03fd86f (draft) [ ] 1
1419 |
1419 |
1420 @ 0:a78f55e5508c (draft) [ ] 0
1420 @ 0:a78f55e5508c (draft) [ ] 0
1421
1421
1422 Test that 'hg debugobsolete --index --rev' can show indices of obsmarkers when
1422 Test that 'hg debugobsolete --index --rev' can show indices of obsmarkers when
1423 only a subset of those are displayed (because of --rev option)
1423 only a subset of those are displayed (because of --rev option)
1424 $ hg init doindexrev
1424 $ hg init doindexrev
1425 $ cd doindexrev
1425 $ cd doindexrev
1426 $ echo a > a
1426 $ echo a > a
1427 $ hg ci -Am a
1427 $ hg ci -Am a
1428 adding a
1428 adding a
1429 $ hg ci --amend -m aa
1429 $ hg ci --amend -m aa
1430 $ echo b > b
1430 $ echo b > b
1431 $ hg ci -Am b
1431 $ hg ci -Am b
1432 adding b
1432 adding b
1433 $ hg ci --amend -m bb
1433 $ hg ci --amend -m bb
1434 $ echo c > c
1434 $ echo c > c
1435 $ hg ci -Am c
1435 $ hg ci -Am c
1436 adding c
1436 adding c
1437 $ hg ci --amend -m cc
1437 $ hg ci --amend -m cc
1438 $ echo d > d
1438 $ echo d > d
1439 $ hg ci -Am d
1439 $ hg ci -Am d
1440 adding d
1440 adding d
1441 $ hg ci --amend -m dd --config experimental.stabilization.track-operation=1
1441 $ hg ci --amend -m dd --config experimental.stabilization.track-operation=1
1442 $ hg debugobsolete --index --rev "3+7"
1442 $ hg debugobsolete --index --rev "3+7"
1443 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1443 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1444 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 \(.*\) {'operation': 'amend', 'user': 'test'} (re)
1444 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 \(.*\) {'operation': 'amend', 'user': 'test'} (re)
1445 $ hg debugobsolete --index --rev "3+7" -Tjson
1445 $ hg debugobsolete --index --rev "3+7" -Tjson
1446 [
1446 [
1447 {
1447 {
1448 "date": [0.0, 0],
1448 "date": [0.0, 0],
1449 "flag": 0,
1449 "flag": 0,
1450 "index": 1,
1450 "index": 1,
1451 "metadata": {"operation": "amend", "user": "test"},
1451 "metadata": {"operation": "amend", "user": "test"},
1452 "prednode": "6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1",
1452 "prednode": "6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1",
1453 "succnodes": ["d27fb9b066076fd921277a4b9e8b9cb48c95bc6a"]
1453 "succnodes": ["d27fb9b066076fd921277a4b9e8b9cb48c95bc6a"]
1454 },
1454 },
1455 {
1455 {
1456 "date": [0.0, 0],
1456 "date": [0.0, 0],
1457 "flag": 0,
1457 "flag": 0,
1458 "index": 3,
1458 "index": 3,
1459 "metadata": {"operation": "amend", "user": "test"},
1459 "metadata": {"operation": "amend", "user": "test"},
1460 "prednode": "4715cf767440ed891755448016c2b8cf70760c30",
1460 "prednode": "4715cf767440ed891755448016c2b8cf70760c30",
1461 "succnodes": ["7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d"]
1461 "succnodes": ["7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d"]
1462 }
1462 }
1463 ]
1463 ]
1464
1464
1465 Test the --delete option of debugobsolete command
1465 Test the --delete option of debugobsolete command
1466 $ hg debugobsolete --index
1466 $ hg debugobsolete --index
1467 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1467 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1468 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1468 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1469 2 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1469 2 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1470 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1470 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1471 $ hg debugobsolete --delete 1 --delete 3
1471 $ hg debugobsolete --delete 1 --delete 3
1472 deleted 2 obsolescence markers
1472 deleted 2 obsolescence markers
1473 $ hg debugobsolete
1473 $ hg debugobsolete
1474 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1474 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1475 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1475 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'amend', 'user': 'test'}
1476
1476
1477 Test adding changeset after obsmarkers affecting it
1477 Test adding changeset after obsmarkers affecting it
1478 (eg: during pull, or unbundle)
1478 (eg: during pull, or unbundle)
1479
1479
1480 $ mkcommit e
1480 $ mkcommit e
1481 $ hg bundle -r . --base .~1 ../bundle-2.hg
1481 $ hg bundle -r . --base .~1 ../bundle-2.hg
1482 1 changesets found
1482 1 changesets found
1483 $ getid .
1483 $ getid .
1484 $ hg --config extensions.strip= strip -r .
1484 $ hg --config extensions.strip= strip -r .
1485 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1485 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1486 saved backup bundle to $TESTTMP/tmpe/issue4845/doindexrev/.hg/strip-backup/9bc153528424-ee80edd4-backup.hg (glob)
1486 saved backup bundle to $TESTTMP/tmpe/issue4845/doindexrev/.hg/strip-backup/9bc153528424-ee80edd4-backup.hg (glob)
1487 $ hg debugobsolete 9bc153528424ea266d13e57f9ff0d799dfe61e4b
1487 $ hg debugobsolete 9bc153528424ea266d13e57f9ff0d799dfe61e4b
1488 $ hg unbundle ../bundle-2.hg
1488 $ hg unbundle ../bundle-2.hg
1489 adding changesets
1489 adding changesets
1490 adding manifests
1490 adding manifests
1491 adding file changes
1491 adding file changes
1492 added 1 changesets with 1 changes to 1 files
1492 added 1 changesets with 1 changes to 1 files
1493 (run 'hg update' to get a working copy)
1493 (run 'hg update' to get a working copy)
1494 $ hg log -G
1494 $ hg log -G
1495 @ 7:7ae79c5d60f0 (draft) [tip ] dd
1495 @ 7:7ae79c5d60f0 (draft) [tip ] dd
1496 |
1496 |
1497 | o 6:4715cf767440 (draft) [ ] d
1497 | o 6:4715cf767440 (draft) [ ] d
1498 |/
1498 |/
1499 o 5:29346082e4a9 (draft) [ ] cc
1499 o 5:29346082e4a9 (draft) [ ] cc
1500 |
1500 |
1501 o 3:d27fb9b06607 (draft) [ ] bb
1501 o 3:d27fb9b06607 (draft) [ ] bb
1502 |
1502 |
1503 | o 2:6fdef60fcbab (draft) [ ] b
1503 | o 2:6fdef60fcbab (draft) [ ] b
1504 |/
1504 |/
1505 o 1:f9bd49731b0b (draft) [ ] aa
1505 o 1:f9bd49731b0b (draft) [ ] aa
1506
1506
1507
1507
1508 $ cd ..
1508 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now