##// END OF EJS Templates
obsolete: fix ValueError when stored note contains ':' char (issue5783)...
Zharaskhan Aman -
r40117:a4d62ff9 default
parent child Browse files
Show More
@@ -1,1058 +1,1058 b''
1 # obsolete.py - obsolete markers handling
1 # obsolete.py - obsolete markers handling
2 #
2 #
3 # Copyright 2012 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
3 # Copyright 2012 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
4 # Logilab SA <contact@logilab.fr>
4 # Logilab SA <contact@logilab.fr>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 """Obsolete marker handling
9 """Obsolete marker handling
10
10
11 An obsolete marker maps an old changeset to a list of new
11 An obsolete marker maps an old changeset to a list of new
12 changesets. If the list of new changesets is empty, the old changeset
12 changesets. If the list of new changesets is empty, the old changeset
13 is said to be "killed". Otherwise, the old changeset is being
13 is said to be "killed". Otherwise, the old changeset is being
14 "replaced" by the new changesets.
14 "replaced" by the new changesets.
15
15
16 Obsolete markers can be used to record and distribute changeset graph
16 Obsolete markers can be used to record and distribute changeset graph
17 transformations performed by history rewrite operations, and help
17 transformations performed by history rewrite operations, and help
18 building new tools to reconcile conflicting rewrite actions. To
18 building new tools to reconcile conflicting rewrite actions. To
19 facilitate conflict resolution, markers include various annotations
19 facilitate conflict resolution, markers include various annotations
20 besides old and news changeset identifiers, such as creation date or
20 besides old and news changeset identifiers, such as creation date or
21 author name.
21 author name.
22
22
23 The old obsoleted changeset is called a "predecessor" and possible
23 The old obsoleted changeset is called a "predecessor" and possible
24 replacements are called "successors". Markers that used changeset X as
24 replacements are called "successors". Markers that used changeset X as
25 a predecessor are called "successor markers of X" because they hold
25 a predecessor are called "successor markers of X" because they hold
26 information about the successors of X. Markers that use changeset Y as
26 information about the successors of X. Markers that use changeset Y as
27 a successors are call "predecessor markers of Y" because they hold
27 a successors are call "predecessor markers of Y" because they hold
28 information about the predecessors of Y.
28 information about the predecessors of Y.
29
29
30 Examples:
30 Examples:
31
31
32 - When changeset A is replaced by changeset A', one marker is stored:
32 - When changeset A is replaced by changeset A', one marker is stored:
33
33
34 (A, (A',))
34 (A, (A',))
35
35
36 - When changesets A and B are folded into a new changeset C, two markers are
36 - When changesets A and B are folded into a new changeset C, two markers are
37 stored:
37 stored:
38
38
39 (A, (C,)) and (B, (C,))
39 (A, (C,)) and (B, (C,))
40
40
41 - When changeset A is simply "pruned" from the graph, a marker is created:
41 - When changeset A is simply "pruned" from the graph, a marker is created:
42
42
43 (A, ())
43 (A, ())
44
44
45 - When changeset A is split into B and C, a single marker is used:
45 - When changeset A is split into B and C, a single marker is used:
46
46
47 (A, (B, C))
47 (A, (B, C))
48
48
49 We use a single marker to distinguish the "split" case from the "divergence"
49 We use a single marker to distinguish the "split" case from the "divergence"
50 case. If two independent operations rewrite the same changeset A in to A' and
50 case. If two independent operations rewrite the same changeset A in to A' and
51 A'', we have an error case: divergent rewriting. We can detect it because
51 A'', we have an error case: divergent rewriting. We can detect it because
52 two markers will be created independently:
52 two markers will be created independently:
53
53
54 (A, (B,)) and (A, (C,))
54 (A, (B,)) and (A, (C,))
55
55
56 Format
56 Format
57 ------
57 ------
58
58
59 Markers are stored in an append-only file stored in
59 Markers are stored in an append-only file stored in
60 '.hg/store/obsstore'.
60 '.hg/store/obsstore'.
61
61
62 The file starts with a version header:
62 The file starts with a version header:
63
63
64 - 1 unsigned byte: version number, starting at zero.
64 - 1 unsigned byte: version number, starting at zero.
65
65
66 The header is followed by the markers. Marker format depend of the version. See
66 The header is followed by the markers. Marker format depend of the version. See
67 comment associated with each format for details.
67 comment associated with each format for details.
68
68
69 """
69 """
70 from __future__ import absolute_import
70 from __future__ import absolute_import
71
71
72 import errno
72 import errno
73 import hashlib
73 import hashlib
74 import struct
74 import struct
75
75
76 from .i18n import _
76 from .i18n import _
77 from . import (
77 from . import (
78 encoding,
78 encoding,
79 error,
79 error,
80 node,
80 node,
81 obsutil,
81 obsutil,
82 phases,
82 phases,
83 policy,
83 policy,
84 pycompat,
84 pycompat,
85 util,
85 util,
86 )
86 )
87 from .utils import dateutil
87 from .utils import dateutil
88
88
89 parsers = policy.importmod(r'parsers')
89 parsers = policy.importmod(r'parsers')
90
90
91 _pack = struct.pack
91 _pack = struct.pack
92 _unpack = struct.unpack
92 _unpack = struct.unpack
93 _calcsize = struct.calcsize
93 _calcsize = struct.calcsize
94 propertycache = util.propertycache
94 propertycache = util.propertycache
95
95
96 # the obsolete feature is not mature enough to be enabled by default.
96 # the obsolete feature is not mature enough to be enabled by default.
97 # you have to rely on third party extension extension to enable this.
97 # you have to rely on third party extension extension to enable this.
98 _enabled = False
98 _enabled = False
99
99
100 # Options for obsolescence
100 # Options for obsolescence
101 createmarkersopt = 'createmarkers'
101 createmarkersopt = 'createmarkers'
102 allowunstableopt = 'allowunstable'
102 allowunstableopt = 'allowunstable'
103 exchangeopt = 'exchange'
103 exchangeopt = 'exchange'
104
104
105 def _getoptionvalue(repo, option):
105 def _getoptionvalue(repo, option):
106 """Returns True if the given repository has the given obsolete option
106 """Returns True if the given repository has the given obsolete option
107 enabled.
107 enabled.
108 """
108 """
109 configkey = 'evolution.%s' % option
109 configkey = 'evolution.%s' % option
110 newconfig = repo.ui.configbool('experimental', configkey)
110 newconfig = repo.ui.configbool('experimental', configkey)
111
111
112 # Return the value only if defined
112 # Return the value only if defined
113 if newconfig is not None:
113 if newconfig is not None:
114 return newconfig
114 return newconfig
115
115
116 # Fallback on generic option
116 # Fallback on generic option
117 try:
117 try:
118 return repo.ui.configbool('experimental', 'evolution')
118 return repo.ui.configbool('experimental', 'evolution')
119 except (error.ConfigError, AttributeError):
119 except (error.ConfigError, AttributeError):
120 # Fallback on old-fashion config
120 # Fallback on old-fashion config
121 # inconsistent config: experimental.evolution
121 # inconsistent config: experimental.evolution
122 result = set(repo.ui.configlist('experimental', 'evolution'))
122 result = set(repo.ui.configlist('experimental', 'evolution'))
123
123
124 if 'all' in result:
124 if 'all' in result:
125 return True
125 return True
126
126
127 # For migration purposes, temporarily return true if the config hasn't
127 # For migration purposes, temporarily return true if the config hasn't
128 # been set but _enabled is true.
128 # been set but _enabled is true.
129 if len(result) == 0 and _enabled:
129 if len(result) == 0 and _enabled:
130 return True
130 return True
131
131
132 # Temporary hack for next check
132 # Temporary hack for next check
133 newconfig = repo.ui.config('experimental', 'evolution.createmarkers')
133 newconfig = repo.ui.config('experimental', 'evolution.createmarkers')
134 if newconfig:
134 if newconfig:
135 result.add('createmarkers')
135 result.add('createmarkers')
136
136
137 return option in result
137 return option in result
138
138
139 def getoptions(repo):
139 def getoptions(repo):
140 """Returns dicts showing state of obsolescence features."""
140 """Returns dicts showing state of obsolescence features."""
141
141
142 createmarkersvalue = _getoptionvalue(repo, createmarkersopt)
142 createmarkersvalue = _getoptionvalue(repo, createmarkersopt)
143 unstablevalue = _getoptionvalue(repo, allowunstableopt)
143 unstablevalue = _getoptionvalue(repo, allowunstableopt)
144 exchangevalue = _getoptionvalue(repo, exchangeopt)
144 exchangevalue = _getoptionvalue(repo, exchangeopt)
145
145
146 # createmarkers must be enabled if other options are enabled
146 # createmarkers must be enabled if other options are enabled
147 if ((unstablevalue or exchangevalue) and not createmarkersvalue):
147 if ((unstablevalue or exchangevalue) and not createmarkersvalue):
148 raise error.Abort(_("'createmarkers' obsolete option must be enabled "
148 raise error.Abort(_("'createmarkers' obsolete option must be enabled "
149 "if other obsolete options are enabled"))
149 "if other obsolete options are enabled"))
150
150
151 return {
151 return {
152 createmarkersopt: createmarkersvalue,
152 createmarkersopt: createmarkersvalue,
153 allowunstableopt: unstablevalue,
153 allowunstableopt: unstablevalue,
154 exchangeopt: exchangevalue,
154 exchangeopt: exchangevalue,
155 }
155 }
156
156
157 def isenabled(repo, option):
157 def isenabled(repo, option):
158 """Returns True if the given repository has the given obsolete option
158 """Returns True if the given repository has the given obsolete option
159 enabled.
159 enabled.
160 """
160 """
161 return getoptions(repo)[option]
161 return getoptions(repo)[option]
162
162
163 # Creating aliases for marker flags because evolve extension looks for
163 # Creating aliases for marker flags because evolve extension looks for
164 # bumpedfix in obsolete.py
164 # bumpedfix in obsolete.py
165 bumpedfix = obsutil.bumpedfix
165 bumpedfix = obsutil.bumpedfix
166 usingsha256 = obsutil.usingsha256
166 usingsha256 = obsutil.usingsha256
167
167
168 ## Parsing and writing of version "0"
168 ## Parsing and writing of version "0"
169 #
169 #
170 # The header is followed by the markers. Each marker is made of:
170 # The header is followed by the markers. Each marker is made of:
171 #
171 #
172 # - 1 uint8 : number of new changesets "N", can be zero.
172 # - 1 uint8 : number of new changesets "N", can be zero.
173 #
173 #
174 # - 1 uint32: metadata size "M" in bytes.
174 # - 1 uint32: metadata size "M" in bytes.
175 #
175 #
176 # - 1 byte: a bit field. It is reserved for flags used in common
176 # - 1 byte: a bit field. It is reserved for flags used in common
177 # obsolete marker operations, to avoid repeated decoding of metadata
177 # obsolete marker operations, to avoid repeated decoding of metadata
178 # entries.
178 # entries.
179 #
179 #
180 # - 20 bytes: obsoleted changeset identifier.
180 # - 20 bytes: obsoleted changeset identifier.
181 #
181 #
182 # - N*20 bytes: new changesets identifiers.
182 # - N*20 bytes: new changesets identifiers.
183 #
183 #
184 # - M bytes: metadata as a sequence of nul-terminated strings. Each
184 # - M bytes: metadata as a sequence of nul-terminated strings. Each
185 # string contains a key and a value, separated by a colon ':', without
185 # string contains a key and a value, separated by a colon ':', without
186 # additional encoding. Keys cannot contain '\0' or ':' and values
186 # additional encoding. Keys cannot contain '\0' or ':' and values
187 # cannot contain '\0'.
187 # cannot contain '\0'.
188 _fm0version = 0
188 _fm0version = 0
189 _fm0fixed = '>BIB20s'
189 _fm0fixed = '>BIB20s'
190 _fm0node = '20s'
190 _fm0node = '20s'
191 _fm0fsize = _calcsize(_fm0fixed)
191 _fm0fsize = _calcsize(_fm0fixed)
192 _fm0fnodesize = _calcsize(_fm0node)
192 _fm0fnodesize = _calcsize(_fm0node)
193
193
194 def _fm0readmarkers(data, off, stop):
194 def _fm0readmarkers(data, off, stop):
195 # Loop on markers
195 # Loop on markers
196 while off < stop:
196 while off < stop:
197 # read fixed part
197 # read fixed part
198 cur = data[off:off + _fm0fsize]
198 cur = data[off:off + _fm0fsize]
199 off += _fm0fsize
199 off += _fm0fsize
200 numsuc, mdsize, flags, pre = _unpack(_fm0fixed, cur)
200 numsuc, mdsize, flags, pre = _unpack(_fm0fixed, cur)
201 # read replacement
201 # read replacement
202 sucs = ()
202 sucs = ()
203 if numsuc:
203 if numsuc:
204 s = (_fm0fnodesize * numsuc)
204 s = (_fm0fnodesize * numsuc)
205 cur = data[off:off + s]
205 cur = data[off:off + s]
206 sucs = _unpack(_fm0node * numsuc, cur)
206 sucs = _unpack(_fm0node * numsuc, cur)
207 off += s
207 off += s
208 # read metadata
208 # read metadata
209 # (metadata will be decoded on demand)
209 # (metadata will be decoded on demand)
210 metadata = data[off:off + mdsize]
210 metadata = data[off:off + mdsize]
211 if len(metadata) != mdsize:
211 if len(metadata) != mdsize:
212 raise error.Abort(_('parsing obsolete marker: metadata is too '
212 raise error.Abort(_('parsing obsolete marker: metadata is too '
213 'short, %d bytes expected, got %d')
213 'short, %d bytes expected, got %d')
214 % (mdsize, len(metadata)))
214 % (mdsize, len(metadata)))
215 off += mdsize
215 off += mdsize
216 metadata = _fm0decodemeta(metadata)
216 metadata = _fm0decodemeta(metadata)
217 try:
217 try:
218 when, offset = metadata.pop('date', '0 0').split(' ')
218 when, offset = metadata.pop('date', '0 0').split(' ')
219 date = float(when), int(offset)
219 date = float(when), int(offset)
220 except ValueError:
220 except ValueError:
221 date = (0., 0)
221 date = (0., 0)
222 parents = None
222 parents = None
223 if 'p2' in metadata:
223 if 'p2' in metadata:
224 parents = (metadata.pop('p1', None), metadata.pop('p2', None))
224 parents = (metadata.pop('p1', None), metadata.pop('p2', None))
225 elif 'p1' in metadata:
225 elif 'p1' in metadata:
226 parents = (metadata.pop('p1', None),)
226 parents = (metadata.pop('p1', None),)
227 elif 'p0' in metadata:
227 elif 'p0' in metadata:
228 parents = ()
228 parents = ()
229 if parents is not None:
229 if parents is not None:
230 try:
230 try:
231 parents = tuple(node.bin(p) for p in parents)
231 parents = tuple(node.bin(p) for p in parents)
232 # if parent content is not a nodeid, drop the data
232 # if parent content is not a nodeid, drop the data
233 for p in parents:
233 for p in parents:
234 if len(p) != 20:
234 if len(p) != 20:
235 parents = None
235 parents = None
236 break
236 break
237 except TypeError:
237 except TypeError:
238 # if content cannot be translated to nodeid drop the data.
238 # if content cannot be translated to nodeid drop the data.
239 parents = None
239 parents = None
240
240
241 metadata = tuple(sorted(metadata.iteritems()))
241 metadata = tuple(sorted(metadata.iteritems()))
242
242
243 yield (pre, sucs, flags, metadata, date, parents)
243 yield (pre, sucs, flags, metadata, date, parents)
244
244
245 def _fm0encodeonemarker(marker):
245 def _fm0encodeonemarker(marker):
246 pre, sucs, flags, metadata, date, parents = marker
246 pre, sucs, flags, metadata, date, parents = marker
247 if flags & usingsha256:
247 if flags & usingsha256:
248 raise error.Abort(_('cannot handle sha256 with old obsstore format'))
248 raise error.Abort(_('cannot handle sha256 with old obsstore format'))
249 metadata = dict(metadata)
249 metadata = dict(metadata)
250 time, tz = date
250 time, tz = date
251 metadata['date'] = '%r %i' % (time, tz)
251 metadata['date'] = '%r %i' % (time, tz)
252 if parents is not None:
252 if parents is not None:
253 if not parents:
253 if not parents:
254 # mark that we explicitly recorded no parents
254 # mark that we explicitly recorded no parents
255 metadata['p0'] = ''
255 metadata['p0'] = ''
256 for i, p in enumerate(parents, 1):
256 for i, p in enumerate(parents, 1):
257 metadata['p%i' % i] = node.hex(p)
257 metadata['p%i' % i] = node.hex(p)
258 metadata = _fm0encodemeta(metadata)
258 metadata = _fm0encodemeta(metadata)
259 numsuc = len(sucs)
259 numsuc = len(sucs)
260 format = _fm0fixed + (_fm0node * numsuc)
260 format = _fm0fixed + (_fm0node * numsuc)
261 data = [numsuc, len(metadata), flags, pre]
261 data = [numsuc, len(metadata), flags, pre]
262 data.extend(sucs)
262 data.extend(sucs)
263 return _pack(format, *data) + metadata
263 return _pack(format, *data) + metadata
264
264
265 def _fm0encodemeta(meta):
265 def _fm0encodemeta(meta):
266 """Return encoded metadata string to string mapping.
266 """Return encoded metadata string to string mapping.
267
267
268 Assume no ':' in key and no '\0' in both key and value."""
268 Assume no ':' in key and no '\0' in both key and value."""
269 for key, value in meta.iteritems():
269 for key, value in meta.iteritems():
270 if ':' in key or '\0' in key:
270 if ':' in key or '\0' in key:
271 raise ValueError("':' and '\0' are forbidden in metadata key'")
271 raise ValueError("':' and '\0' are forbidden in metadata key'")
272 if '\0' in value:
272 if '\0' in value:
273 raise ValueError("':' is forbidden in metadata value'")
273 raise ValueError("':' is forbidden in metadata value'")
274 return '\0'.join(['%s:%s' % (k, meta[k]) for k in sorted(meta)])
274 return '\0'.join(['%s:%s' % (k, meta[k]) for k in sorted(meta)])
275
275
276 def _fm0decodemeta(data):
276 def _fm0decodemeta(data):
277 """Return string to string dictionary from encoded version."""
277 """Return string to string dictionary from encoded version."""
278 d = {}
278 d = {}
279 for l in data.split('\0'):
279 for l in data.split('\0'):
280 if l:
280 if l:
281 key, value = l.split(':')
281 key, value = l.split(':', 1)
282 d[key] = value
282 d[key] = value
283 return d
283 return d
284
284
285 ## Parsing and writing of version "1"
285 ## Parsing and writing of version "1"
286 #
286 #
287 # The header is followed by the markers. Each marker is made of:
287 # The header is followed by the markers. Each marker is made of:
288 #
288 #
289 # - uint32: total size of the marker (including this field)
289 # - uint32: total size of the marker (including this field)
290 #
290 #
291 # - float64: date in seconds since epoch
291 # - float64: date in seconds since epoch
292 #
292 #
293 # - int16: timezone offset in minutes
293 # - int16: timezone offset in minutes
294 #
294 #
295 # - uint16: a bit field. It is reserved for flags used in common
295 # - uint16: a bit field. It is reserved for flags used in common
296 # obsolete marker operations, to avoid repeated decoding of metadata
296 # obsolete marker operations, to avoid repeated decoding of metadata
297 # entries.
297 # entries.
298 #
298 #
299 # - uint8: number of successors "N", can be zero.
299 # - uint8: number of successors "N", can be zero.
300 #
300 #
301 # - uint8: number of parents "P", can be zero.
301 # - uint8: number of parents "P", can be zero.
302 #
302 #
303 # 0: parents data stored but no parent,
303 # 0: parents data stored but no parent,
304 # 1: one parent stored,
304 # 1: one parent stored,
305 # 2: two parents stored,
305 # 2: two parents stored,
306 # 3: no parent data stored
306 # 3: no parent data stored
307 #
307 #
308 # - uint8: number of metadata entries M
308 # - uint8: number of metadata entries M
309 #
309 #
310 # - 20 or 32 bytes: predecessor changeset identifier.
310 # - 20 or 32 bytes: predecessor changeset identifier.
311 #
311 #
312 # - N*(20 or 32) bytes: successors changesets identifiers.
312 # - N*(20 or 32) bytes: successors changesets identifiers.
313 #
313 #
314 # - P*(20 or 32) bytes: parents of the predecessors changesets.
314 # - P*(20 or 32) bytes: parents of the predecessors changesets.
315 #
315 #
316 # - M*(uint8, uint8): size of all metadata entries (key and value)
316 # - M*(uint8, uint8): size of all metadata entries (key and value)
317 #
317 #
318 # - remaining bytes: the metadata, each (key, value) pair after the other.
318 # - remaining bytes: the metadata, each (key, value) pair after the other.
319 _fm1version = 1
319 _fm1version = 1
320 _fm1fixed = '>IdhHBBB20s'
320 _fm1fixed = '>IdhHBBB20s'
321 _fm1nodesha1 = '20s'
321 _fm1nodesha1 = '20s'
322 _fm1nodesha256 = '32s'
322 _fm1nodesha256 = '32s'
323 _fm1nodesha1size = _calcsize(_fm1nodesha1)
323 _fm1nodesha1size = _calcsize(_fm1nodesha1)
324 _fm1nodesha256size = _calcsize(_fm1nodesha256)
324 _fm1nodesha256size = _calcsize(_fm1nodesha256)
325 _fm1fsize = _calcsize(_fm1fixed)
325 _fm1fsize = _calcsize(_fm1fixed)
326 _fm1parentnone = 3
326 _fm1parentnone = 3
327 _fm1parentshift = 14
327 _fm1parentshift = 14
328 _fm1parentmask = (_fm1parentnone << _fm1parentshift)
328 _fm1parentmask = (_fm1parentnone << _fm1parentshift)
329 _fm1metapair = 'BB'
329 _fm1metapair = 'BB'
330 _fm1metapairsize = _calcsize(_fm1metapair)
330 _fm1metapairsize = _calcsize(_fm1metapair)
331
331
332 def _fm1purereadmarkers(data, off, stop):
332 def _fm1purereadmarkers(data, off, stop):
333 # make some global constants local for performance
333 # make some global constants local for performance
334 noneflag = _fm1parentnone
334 noneflag = _fm1parentnone
335 sha2flag = usingsha256
335 sha2flag = usingsha256
336 sha1size = _fm1nodesha1size
336 sha1size = _fm1nodesha1size
337 sha2size = _fm1nodesha256size
337 sha2size = _fm1nodesha256size
338 sha1fmt = _fm1nodesha1
338 sha1fmt = _fm1nodesha1
339 sha2fmt = _fm1nodesha256
339 sha2fmt = _fm1nodesha256
340 metasize = _fm1metapairsize
340 metasize = _fm1metapairsize
341 metafmt = _fm1metapair
341 metafmt = _fm1metapair
342 fsize = _fm1fsize
342 fsize = _fm1fsize
343 unpack = _unpack
343 unpack = _unpack
344
344
345 # Loop on markers
345 # Loop on markers
346 ufixed = struct.Struct(_fm1fixed).unpack
346 ufixed = struct.Struct(_fm1fixed).unpack
347
347
348 while off < stop:
348 while off < stop:
349 # read fixed part
349 # read fixed part
350 o1 = off + fsize
350 o1 = off + fsize
351 t, secs, tz, flags, numsuc, numpar, nummeta, prec = ufixed(data[off:o1])
351 t, secs, tz, flags, numsuc, numpar, nummeta, prec = ufixed(data[off:o1])
352
352
353 if flags & sha2flag:
353 if flags & sha2flag:
354 # FIXME: prec was read as a SHA1, needs to be amended
354 # FIXME: prec was read as a SHA1, needs to be amended
355
355
356 # read 0 or more successors
356 # read 0 or more successors
357 if numsuc == 1:
357 if numsuc == 1:
358 o2 = o1 + sha2size
358 o2 = o1 + sha2size
359 sucs = (data[o1:o2],)
359 sucs = (data[o1:o2],)
360 else:
360 else:
361 o2 = o1 + sha2size * numsuc
361 o2 = o1 + sha2size * numsuc
362 sucs = unpack(sha2fmt * numsuc, data[o1:o2])
362 sucs = unpack(sha2fmt * numsuc, data[o1:o2])
363
363
364 # read parents
364 # read parents
365 if numpar == noneflag:
365 if numpar == noneflag:
366 o3 = o2
366 o3 = o2
367 parents = None
367 parents = None
368 elif numpar == 1:
368 elif numpar == 1:
369 o3 = o2 + sha2size
369 o3 = o2 + sha2size
370 parents = (data[o2:o3],)
370 parents = (data[o2:o3],)
371 else:
371 else:
372 o3 = o2 + sha2size * numpar
372 o3 = o2 + sha2size * numpar
373 parents = unpack(sha2fmt * numpar, data[o2:o3])
373 parents = unpack(sha2fmt * numpar, data[o2:o3])
374 else:
374 else:
375 # read 0 or more successors
375 # read 0 or more successors
376 if numsuc == 1:
376 if numsuc == 1:
377 o2 = o1 + sha1size
377 o2 = o1 + sha1size
378 sucs = (data[o1:o2],)
378 sucs = (data[o1:o2],)
379 else:
379 else:
380 o2 = o1 + sha1size * numsuc
380 o2 = o1 + sha1size * numsuc
381 sucs = unpack(sha1fmt * numsuc, data[o1:o2])
381 sucs = unpack(sha1fmt * numsuc, data[o1:o2])
382
382
383 # read parents
383 # read parents
384 if numpar == noneflag:
384 if numpar == noneflag:
385 o3 = o2
385 o3 = o2
386 parents = None
386 parents = None
387 elif numpar == 1:
387 elif numpar == 1:
388 o3 = o2 + sha1size
388 o3 = o2 + sha1size
389 parents = (data[o2:o3],)
389 parents = (data[o2:o3],)
390 else:
390 else:
391 o3 = o2 + sha1size * numpar
391 o3 = o2 + sha1size * numpar
392 parents = unpack(sha1fmt * numpar, data[o2:o3])
392 parents = unpack(sha1fmt * numpar, data[o2:o3])
393
393
394 # read metadata
394 # read metadata
395 off = o3 + metasize * nummeta
395 off = o3 + metasize * nummeta
396 metapairsize = unpack('>' + (metafmt * nummeta), data[o3:off])
396 metapairsize = unpack('>' + (metafmt * nummeta), data[o3:off])
397 metadata = []
397 metadata = []
398 for idx in pycompat.xrange(0, len(metapairsize), 2):
398 for idx in pycompat.xrange(0, len(metapairsize), 2):
399 o1 = off + metapairsize[idx]
399 o1 = off + metapairsize[idx]
400 o2 = o1 + metapairsize[idx + 1]
400 o2 = o1 + metapairsize[idx + 1]
401 metadata.append((data[off:o1], data[o1:o2]))
401 metadata.append((data[off:o1], data[o1:o2]))
402 off = o2
402 off = o2
403
403
404 yield (prec, sucs, flags, tuple(metadata), (secs, tz * 60), parents)
404 yield (prec, sucs, flags, tuple(metadata), (secs, tz * 60), parents)
405
405
406 def _fm1encodeonemarker(marker):
406 def _fm1encodeonemarker(marker):
407 pre, sucs, flags, metadata, date, parents = marker
407 pre, sucs, flags, metadata, date, parents = marker
408 # determine node size
408 # determine node size
409 _fm1node = _fm1nodesha1
409 _fm1node = _fm1nodesha1
410 if flags & usingsha256:
410 if flags & usingsha256:
411 _fm1node = _fm1nodesha256
411 _fm1node = _fm1nodesha256
412 numsuc = len(sucs)
412 numsuc = len(sucs)
413 numextranodes = numsuc
413 numextranodes = numsuc
414 if parents is None:
414 if parents is None:
415 numpar = _fm1parentnone
415 numpar = _fm1parentnone
416 else:
416 else:
417 numpar = len(parents)
417 numpar = len(parents)
418 numextranodes += numpar
418 numextranodes += numpar
419 formatnodes = _fm1node * numextranodes
419 formatnodes = _fm1node * numextranodes
420 formatmeta = _fm1metapair * len(metadata)
420 formatmeta = _fm1metapair * len(metadata)
421 format = _fm1fixed + formatnodes + formatmeta
421 format = _fm1fixed + formatnodes + formatmeta
422 # tz is stored in minutes so we divide by 60
422 # tz is stored in minutes so we divide by 60
423 tz = date[1]//60
423 tz = date[1]//60
424 data = [None, date[0], tz, flags, numsuc, numpar, len(metadata), pre]
424 data = [None, date[0], tz, flags, numsuc, numpar, len(metadata), pre]
425 data.extend(sucs)
425 data.extend(sucs)
426 if parents is not None:
426 if parents is not None:
427 data.extend(parents)
427 data.extend(parents)
428 totalsize = _calcsize(format)
428 totalsize = _calcsize(format)
429 for key, value in metadata:
429 for key, value in metadata:
430 lk = len(key)
430 lk = len(key)
431 lv = len(value)
431 lv = len(value)
432 if lk > 255:
432 if lk > 255:
433 msg = ('obsstore metadata key cannot be longer than 255 bytes'
433 msg = ('obsstore metadata key cannot be longer than 255 bytes'
434 ' (key "%s" is %u bytes)') % (key, lk)
434 ' (key "%s" is %u bytes)') % (key, lk)
435 raise error.ProgrammingError(msg)
435 raise error.ProgrammingError(msg)
436 if lv > 255:
436 if lv > 255:
437 msg = ('obsstore metadata value cannot be longer than 255 bytes'
437 msg = ('obsstore metadata value cannot be longer than 255 bytes'
438 ' (value "%s" for key "%s" is %u bytes)') % (value, key, lv)
438 ' (value "%s" for key "%s" is %u bytes)') % (value, key, lv)
439 raise error.ProgrammingError(msg)
439 raise error.ProgrammingError(msg)
440 data.append(lk)
440 data.append(lk)
441 data.append(lv)
441 data.append(lv)
442 totalsize += lk + lv
442 totalsize += lk + lv
443 data[0] = totalsize
443 data[0] = totalsize
444 data = [_pack(format, *data)]
444 data = [_pack(format, *data)]
445 for key, value in metadata:
445 for key, value in metadata:
446 data.append(key)
446 data.append(key)
447 data.append(value)
447 data.append(value)
448 return ''.join(data)
448 return ''.join(data)
449
449
450 def _fm1readmarkers(data, off, stop):
450 def _fm1readmarkers(data, off, stop):
451 native = getattr(parsers, 'fm1readmarkers', None)
451 native = getattr(parsers, 'fm1readmarkers', None)
452 if not native:
452 if not native:
453 return _fm1purereadmarkers(data, off, stop)
453 return _fm1purereadmarkers(data, off, stop)
454 return native(data, off, stop)
454 return native(data, off, stop)
455
455
456 # mapping to read/write various marker formats
456 # mapping to read/write various marker formats
457 # <version> -> (decoder, encoder)
457 # <version> -> (decoder, encoder)
458 formats = {_fm0version: (_fm0readmarkers, _fm0encodeonemarker),
458 formats = {_fm0version: (_fm0readmarkers, _fm0encodeonemarker),
459 _fm1version: (_fm1readmarkers, _fm1encodeonemarker)}
459 _fm1version: (_fm1readmarkers, _fm1encodeonemarker)}
460
460
461 def _readmarkerversion(data):
461 def _readmarkerversion(data):
462 return _unpack('>B', data[0:1])[0]
462 return _unpack('>B', data[0:1])[0]
463
463
464 @util.nogc
464 @util.nogc
465 def _readmarkers(data, off=None, stop=None):
465 def _readmarkers(data, off=None, stop=None):
466 """Read and enumerate markers from raw data"""
466 """Read and enumerate markers from raw data"""
467 diskversion = _readmarkerversion(data)
467 diskversion = _readmarkerversion(data)
468 if not off:
468 if not off:
469 off = 1 # skip 1 byte version number
469 off = 1 # skip 1 byte version number
470 if stop is None:
470 if stop is None:
471 stop = len(data)
471 stop = len(data)
472 if diskversion not in formats:
472 if diskversion not in formats:
473 msg = _('parsing obsolete marker: unknown version %r') % diskversion
473 msg = _('parsing obsolete marker: unknown version %r') % diskversion
474 raise error.UnknownVersion(msg, version=diskversion)
474 raise error.UnknownVersion(msg, version=diskversion)
475 return diskversion, formats[diskversion][0](data, off, stop)
475 return diskversion, formats[diskversion][0](data, off, stop)
476
476
477 def encodeheader(version=_fm0version):
477 def encodeheader(version=_fm0version):
478 return _pack('>B', version)
478 return _pack('>B', version)
479
479
480 def encodemarkers(markers, addheader=False, version=_fm0version):
480 def encodemarkers(markers, addheader=False, version=_fm0version):
481 # Kept separate from flushmarkers(), it will be reused for
481 # Kept separate from flushmarkers(), it will be reused for
482 # markers exchange.
482 # markers exchange.
483 encodeone = formats[version][1]
483 encodeone = formats[version][1]
484 if addheader:
484 if addheader:
485 yield encodeheader(version)
485 yield encodeheader(version)
486 for marker in markers:
486 for marker in markers:
487 yield encodeone(marker)
487 yield encodeone(marker)
488
488
489 @util.nogc
489 @util.nogc
490 def _addsuccessors(successors, markers):
490 def _addsuccessors(successors, markers):
491 for mark in markers:
491 for mark in markers:
492 successors.setdefault(mark[0], set()).add(mark)
492 successors.setdefault(mark[0], set()).add(mark)
493
493
494 @util.nogc
494 @util.nogc
495 def _addpredecessors(predecessors, markers):
495 def _addpredecessors(predecessors, markers):
496 for mark in markers:
496 for mark in markers:
497 for suc in mark[1]:
497 for suc in mark[1]:
498 predecessors.setdefault(suc, set()).add(mark)
498 predecessors.setdefault(suc, set()).add(mark)
499
499
500 @util.nogc
500 @util.nogc
501 def _addchildren(children, markers):
501 def _addchildren(children, markers):
502 for mark in markers:
502 for mark in markers:
503 parents = mark[5]
503 parents = mark[5]
504 if parents is not None:
504 if parents is not None:
505 for p in parents:
505 for p in parents:
506 children.setdefault(p, set()).add(mark)
506 children.setdefault(p, set()).add(mark)
507
507
508 def _checkinvalidmarkers(markers):
508 def _checkinvalidmarkers(markers):
509 """search for marker with invalid data and raise error if needed
509 """search for marker with invalid data and raise error if needed
510
510
511 Exist as a separated function to allow the evolve extension for a more
511 Exist as a separated function to allow the evolve extension for a more
512 subtle handling.
512 subtle handling.
513 """
513 """
514 for mark in markers:
514 for mark in markers:
515 if node.nullid in mark[1]:
515 if node.nullid in mark[1]:
516 raise error.Abort(_('bad obsolescence marker detected: '
516 raise error.Abort(_('bad obsolescence marker detected: '
517 'invalid successors nullid'))
517 'invalid successors nullid'))
518
518
519 class obsstore(object):
519 class obsstore(object):
520 """Store obsolete markers
520 """Store obsolete markers
521
521
522 Markers can be accessed with two mappings:
522 Markers can be accessed with two mappings:
523 - predecessors[x] -> set(markers on predecessors edges of x)
523 - predecessors[x] -> set(markers on predecessors edges of x)
524 - successors[x] -> set(markers on successors edges of x)
524 - successors[x] -> set(markers on successors edges of x)
525 - children[x] -> set(markers on predecessors edges of children(x)
525 - children[x] -> set(markers on predecessors edges of children(x)
526 """
526 """
527
527
528 fields = ('prec', 'succs', 'flag', 'meta', 'date', 'parents')
528 fields = ('prec', 'succs', 'flag', 'meta', 'date', 'parents')
529 # prec: nodeid, predecessors changesets
529 # prec: nodeid, predecessors changesets
530 # succs: tuple of nodeid, successor changesets (0-N length)
530 # succs: tuple of nodeid, successor changesets (0-N length)
531 # flag: integer, flag field carrying modifier for the markers (see doc)
531 # flag: integer, flag field carrying modifier for the markers (see doc)
532 # meta: binary blob in UTF-8, encoded metadata dictionary
532 # meta: binary blob in UTF-8, encoded metadata dictionary
533 # date: (float, int) tuple, date of marker creation
533 # date: (float, int) tuple, date of marker creation
534 # parents: (tuple of nodeid) or None, parents of predecessors
534 # parents: (tuple of nodeid) or None, parents of predecessors
535 # None is used when no data has been recorded
535 # None is used when no data has been recorded
536
536
537 def __init__(self, svfs, defaultformat=_fm1version, readonly=False):
537 def __init__(self, svfs, defaultformat=_fm1version, readonly=False):
538 # caches for various obsolescence related cache
538 # caches for various obsolescence related cache
539 self.caches = {}
539 self.caches = {}
540 self.svfs = svfs
540 self.svfs = svfs
541 self._defaultformat = defaultformat
541 self._defaultformat = defaultformat
542 self._readonly = readonly
542 self._readonly = readonly
543
543
544 def __iter__(self):
544 def __iter__(self):
545 return iter(self._all)
545 return iter(self._all)
546
546
547 def __len__(self):
547 def __len__(self):
548 return len(self._all)
548 return len(self._all)
549
549
550 def __nonzero__(self):
550 def __nonzero__(self):
551 if not self._cached(r'_all'):
551 if not self._cached(r'_all'):
552 try:
552 try:
553 return self.svfs.stat('obsstore').st_size > 1
553 return self.svfs.stat('obsstore').st_size > 1
554 except OSError as inst:
554 except OSError as inst:
555 if inst.errno != errno.ENOENT:
555 if inst.errno != errno.ENOENT:
556 raise
556 raise
557 # just build an empty _all list if no obsstore exists, which
557 # just build an empty _all list if no obsstore exists, which
558 # avoids further stat() syscalls
558 # avoids further stat() syscalls
559 return bool(self._all)
559 return bool(self._all)
560
560
561 __bool__ = __nonzero__
561 __bool__ = __nonzero__
562
562
563 @property
563 @property
564 def readonly(self):
564 def readonly(self):
565 """True if marker creation is disabled
565 """True if marker creation is disabled
566
566
567 Remove me in the future when obsolete marker is always on."""
567 Remove me in the future when obsolete marker is always on."""
568 return self._readonly
568 return self._readonly
569
569
570 def create(self, transaction, prec, succs=(), flag=0, parents=None,
570 def create(self, transaction, prec, succs=(), flag=0, parents=None,
571 date=None, metadata=None, ui=None):
571 date=None, metadata=None, ui=None):
572 """obsolete: add a new obsolete marker
572 """obsolete: add a new obsolete marker
573
573
574 * ensuring it is hashable
574 * ensuring it is hashable
575 * check mandatory metadata
575 * check mandatory metadata
576 * encode metadata
576 * encode metadata
577
577
578 If you are a human writing code creating marker you want to use the
578 If you are a human writing code creating marker you want to use the
579 `createmarkers` function in this module instead.
579 `createmarkers` function in this module instead.
580
580
581 return True if a new marker have been added, False if the markers
581 return True if a new marker have been added, False if the markers
582 already existed (no op).
582 already existed (no op).
583 """
583 """
584 if metadata is None:
584 if metadata is None:
585 metadata = {}
585 metadata = {}
586 if date is None:
586 if date is None:
587 if 'date' in metadata:
587 if 'date' in metadata:
588 # as a courtesy for out-of-tree extensions
588 # as a courtesy for out-of-tree extensions
589 date = dateutil.parsedate(metadata.pop('date'))
589 date = dateutil.parsedate(metadata.pop('date'))
590 elif ui is not None:
590 elif ui is not None:
591 date = ui.configdate('devel', 'default-date')
591 date = ui.configdate('devel', 'default-date')
592 if date is None:
592 if date is None:
593 date = dateutil.makedate()
593 date = dateutil.makedate()
594 else:
594 else:
595 date = dateutil.makedate()
595 date = dateutil.makedate()
596 if len(prec) != 20:
596 if len(prec) != 20:
597 raise ValueError(prec)
597 raise ValueError(prec)
598 for succ in succs:
598 for succ in succs:
599 if len(succ) != 20:
599 if len(succ) != 20:
600 raise ValueError(succ)
600 raise ValueError(succ)
601 if prec in succs:
601 if prec in succs:
602 raise ValueError(_('in-marker cycle with %s') % node.hex(prec))
602 raise ValueError(_('in-marker cycle with %s') % node.hex(prec))
603
603
604 metadata = tuple(sorted(metadata.iteritems()))
604 metadata = tuple(sorted(metadata.iteritems()))
605 for k, v in metadata:
605 for k, v in metadata:
606 try:
606 try:
607 # might be better to reject non-ASCII keys
607 # might be better to reject non-ASCII keys
608 k.decode('utf-8')
608 k.decode('utf-8')
609 v.decode('utf-8')
609 v.decode('utf-8')
610 except UnicodeDecodeError:
610 except UnicodeDecodeError:
611 raise error.ProgrammingError(
611 raise error.ProgrammingError(
612 'obsstore metadata must be valid UTF-8 sequence '
612 'obsstore metadata must be valid UTF-8 sequence '
613 '(key = %r, value = %r)'
613 '(key = %r, value = %r)'
614 % (pycompat.bytestr(k), pycompat.bytestr(v)))
614 % (pycompat.bytestr(k), pycompat.bytestr(v)))
615
615
616 marker = (bytes(prec), tuple(succs), int(flag), metadata, date, parents)
616 marker = (bytes(prec), tuple(succs), int(flag), metadata, date, parents)
617 return bool(self.add(transaction, [marker]))
617 return bool(self.add(transaction, [marker]))
618
618
619 def add(self, transaction, markers):
619 def add(self, transaction, markers):
620 """Add new markers to the store
620 """Add new markers to the store
621
621
622 Take care of filtering duplicate.
622 Take care of filtering duplicate.
623 Return the number of new marker."""
623 Return the number of new marker."""
624 if self._readonly:
624 if self._readonly:
625 raise error.Abort(_('creating obsolete markers is not enabled on '
625 raise error.Abort(_('creating obsolete markers is not enabled on '
626 'this repo'))
626 'this repo'))
627 known = set()
627 known = set()
628 getsuccessors = self.successors.get
628 getsuccessors = self.successors.get
629 new = []
629 new = []
630 for m in markers:
630 for m in markers:
631 if m not in getsuccessors(m[0], ()) and m not in known:
631 if m not in getsuccessors(m[0], ()) and m not in known:
632 known.add(m)
632 known.add(m)
633 new.append(m)
633 new.append(m)
634 if new:
634 if new:
635 f = self.svfs('obsstore', 'ab')
635 f = self.svfs('obsstore', 'ab')
636 try:
636 try:
637 offset = f.tell()
637 offset = f.tell()
638 transaction.add('obsstore', offset)
638 transaction.add('obsstore', offset)
639 # offset == 0: new file - add the version header
639 # offset == 0: new file - add the version header
640 data = b''.join(encodemarkers(new, offset == 0, self._version))
640 data = b''.join(encodemarkers(new, offset == 0, self._version))
641 f.write(data)
641 f.write(data)
642 finally:
642 finally:
643 # XXX: f.close() == filecache invalidation == obsstore rebuilt.
643 # XXX: f.close() == filecache invalidation == obsstore rebuilt.
644 # call 'filecacheentry.refresh()' here
644 # call 'filecacheentry.refresh()' here
645 f.close()
645 f.close()
646 addedmarkers = transaction.changes.get('obsmarkers')
646 addedmarkers = transaction.changes.get('obsmarkers')
647 if addedmarkers is not None:
647 if addedmarkers is not None:
648 addedmarkers.update(new)
648 addedmarkers.update(new)
649 self._addmarkers(new, data)
649 self._addmarkers(new, data)
650 # new marker *may* have changed several set. invalidate the cache.
650 # new marker *may* have changed several set. invalidate the cache.
651 self.caches.clear()
651 self.caches.clear()
652 # records the number of new markers for the transaction hooks
652 # records the number of new markers for the transaction hooks
653 previous = int(transaction.hookargs.get('new_obsmarkers', '0'))
653 previous = int(transaction.hookargs.get('new_obsmarkers', '0'))
654 transaction.hookargs['new_obsmarkers'] = '%d' % (previous + len(new))
654 transaction.hookargs['new_obsmarkers'] = '%d' % (previous + len(new))
655 return len(new)
655 return len(new)
656
656
657 def mergemarkers(self, transaction, data):
657 def mergemarkers(self, transaction, data):
658 """merge a binary stream of markers inside the obsstore
658 """merge a binary stream of markers inside the obsstore
659
659
660 Returns the number of new markers added."""
660 Returns the number of new markers added."""
661 version, markers = _readmarkers(data)
661 version, markers = _readmarkers(data)
662 return self.add(transaction, markers)
662 return self.add(transaction, markers)
663
663
664 @propertycache
664 @propertycache
665 def _data(self):
665 def _data(self):
666 return self.svfs.tryread('obsstore')
666 return self.svfs.tryread('obsstore')
667
667
668 @propertycache
668 @propertycache
669 def _version(self):
669 def _version(self):
670 if len(self._data) >= 1:
670 if len(self._data) >= 1:
671 return _readmarkerversion(self._data)
671 return _readmarkerversion(self._data)
672 else:
672 else:
673 return self._defaultformat
673 return self._defaultformat
674
674
675 @propertycache
675 @propertycache
676 def _all(self):
676 def _all(self):
677 data = self._data
677 data = self._data
678 if not data:
678 if not data:
679 return []
679 return []
680 self._version, markers = _readmarkers(data)
680 self._version, markers = _readmarkers(data)
681 markers = list(markers)
681 markers = list(markers)
682 _checkinvalidmarkers(markers)
682 _checkinvalidmarkers(markers)
683 return markers
683 return markers
684
684
685 @propertycache
685 @propertycache
686 def successors(self):
686 def successors(self):
687 successors = {}
687 successors = {}
688 _addsuccessors(successors, self._all)
688 _addsuccessors(successors, self._all)
689 return successors
689 return successors
690
690
691 @propertycache
691 @propertycache
692 def predecessors(self):
692 def predecessors(self):
693 predecessors = {}
693 predecessors = {}
694 _addpredecessors(predecessors, self._all)
694 _addpredecessors(predecessors, self._all)
695 return predecessors
695 return predecessors
696
696
697 @propertycache
697 @propertycache
698 def children(self):
698 def children(self):
699 children = {}
699 children = {}
700 _addchildren(children, self._all)
700 _addchildren(children, self._all)
701 return children
701 return children
702
702
703 def _cached(self, attr):
703 def _cached(self, attr):
704 return attr in self.__dict__
704 return attr in self.__dict__
705
705
706 def _addmarkers(self, markers, rawdata):
706 def _addmarkers(self, markers, rawdata):
707 markers = list(markers) # to allow repeated iteration
707 markers = list(markers) # to allow repeated iteration
708 self._data = self._data + rawdata
708 self._data = self._data + rawdata
709 self._all.extend(markers)
709 self._all.extend(markers)
710 if self._cached(r'successors'):
710 if self._cached(r'successors'):
711 _addsuccessors(self.successors, markers)
711 _addsuccessors(self.successors, markers)
712 if self._cached(r'predecessors'):
712 if self._cached(r'predecessors'):
713 _addpredecessors(self.predecessors, markers)
713 _addpredecessors(self.predecessors, markers)
714 if self._cached(r'children'):
714 if self._cached(r'children'):
715 _addchildren(self.children, markers)
715 _addchildren(self.children, markers)
716 _checkinvalidmarkers(markers)
716 _checkinvalidmarkers(markers)
717
717
718 def relevantmarkers(self, nodes):
718 def relevantmarkers(self, nodes):
719 """return a set of all obsolescence markers relevant to a set of nodes.
719 """return a set of all obsolescence markers relevant to a set of nodes.
720
720
721 "relevant" to a set of nodes mean:
721 "relevant" to a set of nodes mean:
722
722
723 - marker that use this changeset as successor
723 - marker that use this changeset as successor
724 - prune marker of direct children on this changeset
724 - prune marker of direct children on this changeset
725 - recursive application of the two rules on predecessors of these
725 - recursive application of the two rules on predecessors of these
726 markers
726 markers
727
727
728 It is a set so you cannot rely on order."""
728 It is a set so you cannot rely on order."""
729
729
730 pendingnodes = set(nodes)
730 pendingnodes = set(nodes)
731 seenmarkers = set()
731 seenmarkers = set()
732 seennodes = set(pendingnodes)
732 seennodes = set(pendingnodes)
733 precursorsmarkers = self.predecessors
733 precursorsmarkers = self.predecessors
734 succsmarkers = self.successors
734 succsmarkers = self.successors
735 children = self.children
735 children = self.children
736 while pendingnodes:
736 while pendingnodes:
737 direct = set()
737 direct = set()
738 for current in pendingnodes:
738 for current in pendingnodes:
739 direct.update(precursorsmarkers.get(current, ()))
739 direct.update(precursorsmarkers.get(current, ()))
740 pruned = [m for m in children.get(current, ()) if not m[1]]
740 pruned = [m for m in children.get(current, ()) if not m[1]]
741 direct.update(pruned)
741 direct.update(pruned)
742 pruned = [m for m in succsmarkers.get(current, ()) if not m[1]]
742 pruned = [m for m in succsmarkers.get(current, ()) if not m[1]]
743 direct.update(pruned)
743 direct.update(pruned)
744 direct -= seenmarkers
744 direct -= seenmarkers
745 pendingnodes = set([m[0] for m in direct])
745 pendingnodes = set([m[0] for m in direct])
746 seenmarkers |= direct
746 seenmarkers |= direct
747 pendingnodes -= seennodes
747 pendingnodes -= seennodes
748 seennodes |= pendingnodes
748 seennodes |= pendingnodes
749 return seenmarkers
749 return seenmarkers
750
750
751 def makestore(ui, repo):
751 def makestore(ui, repo):
752 """Create an obsstore instance from a repo."""
752 """Create an obsstore instance from a repo."""
753 # read default format for new obsstore.
753 # read default format for new obsstore.
754 # developer config: format.obsstore-version
754 # developer config: format.obsstore-version
755 defaultformat = ui.configint('format', 'obsstore-version')
755 defaultformat = ui.configint('format', 'obsstore-version')
756 # rely on obsstore class default when possible.
756 # rely on obsstore class default when possible.
757 kwargs = {}
757 kwargs = {}
758 if defaultformat is not None:
758 if defaultformat is not None:
759 kwargs[r'defaultformat'] = defaultformat
759 kwargs[r'defaultformat'] = defaultformat
760 readonly = not isenabled(repo, createmarkersopt)
760 readonly = not isenabled(repo, createmarkersopt)
761 store = obsstore(repo.svfs, readonly=readonly, **kwargs)
761 store = obsstore(repo.svfs, readonly=readonly, **kwargs)
762 if store and readonly:
762 if store and readonly:
763 ui.warn(_('obsolete feature not enabled but %i markers found!\n')
763 ui.warn(_('obsolete feature not enabled but %i markers found!\n')
764 % len(list(store)))
764 % len(list(store)))
765 return store
765 return store
766
766
767 def commonversion(versions):
767 def commonversion(versions):
768 """Return the newest version listed in both versions and our local formats.
768 """Return the newest version listed in both versions and our local formats.
769
769
770 Returns None if no common version exists.
770 Returns None if no common version exists.
771 """
771 """
772 versions.sort(reverse=True)
772 versions.sort(reverse=True)
773 # search for highest version known on both side
773 # search for highest version known on both side
774 for v in versions:
774 for v in versions:
775 if v in formats:
775 if v in formats:
776 return v
776 return v
777 return None
777 return None
778
778
779 # arbitrary picked to fit into 8K limit from HTTP server
779 # arbitrary picked to fit into 8K limit from HTTP server
780 # you have to take in account:
780 # you have to take in account:
781 # - the version header
781 # - the version header
782 # - the base85 encoding
782 # - the base85 encoding
783 _maxpayload = 5300
783 _maxpayload = 5300
784
784
785 def _pushkeyescape(markers):
785 def _pushkeyescape(markers):
786 """encode markers into a dict suitable for pushkey exchange
786 """encode markers into a dict suitable for pushkey exchange
787
787
788 - binary data is base85 encoded
788 - binary data is base85 encoded
789 - split in chunks smaller than 5300 bytes"""
789 - split in chunks smaller than 5300 bytes"""
790 keys = {}
790 keys = {}
791 parts = []
791 parts = []
792 currentlen = _maxpayload * 2 # ensure we create a new part
792 currentlen = _maxpayload * 2 # ensure we create a new part
793 for marker in markers:
793 for marker in markers:
794 nextdata = _fm0encodeonemarker(marker)
794 nextdata = _fm0encodeonemarker(marker)
795 if (len(nextdata) + currentlen > _maxpayload):
795 if (len(nextdata) + currentlen > _maxpayload):
796 currentpart = []
796 currentpart = []
797 currentlen = 0
797 currentlen = 0
798 parts.append(currentpart)
798 parts.append(currentpart)
799 currentpart.append(nextdata)
799 currentpart.append(nextdata)
800 currentlen += len(nextdata)
800 currentlen += len(nextdata)
801 for idx, part in enumerate(reversed(parts)):
801 for idx, part in enumerate(reversed(parts)):
802 data = ''.join([_pack('>B', _fm0version)] + part)
802 data = ''.join([_pack('>B', _fm0version)] + part)
803 keys['dump%i' % idx] = util.b85encode(data)
803 keys['dump%i' % idx] = util.b85encode(data)
804 return keys
804 return keys
805
805
806 def listmarkers(repo):
806 def listmarkers(repo):
807 """List markers over pushkey"""
807 """List markers over pushkey"""
808 if not repo.obsstore:
808 if not repo.obsstore:
809 return {}
809 return {}
810 return _pushkeyescape(sorted(repo.obsstore))
810 return _pushkeyescape(sorted(repo.obsstore))
811
811
812 def pushmarker(repo, key, old, new):
812 def pushmarker(repo, key, old, new):
813 """Push markers over pushkey"""
813 """Push markers over pushkey"""
814 if not key.startswith('dump'):
814 if not key.startswith('dump'):
815 repo.ui.warn(_('unknown key: %r') % key)
815 repo.ui.warn(_('unknown key: %r') % key)
816 return False
816 return False
817 if old:
817 if old:
818 repo.ui.warn(_('unexpected old value for %r') % key)
818 repo.ui.warn(_('unexpected old value for %r') % key)
819 return False
819 return False
820 data = util.b85decode(new)
820 data = util.b85decode(new)
821 with repo.lock(), repo.transaction('pushkey: obsolete markers') as tr:
821 with repo.lock(), repo.transaction('pushkey: obsolete markers') as tr:
822 repo.obsstore.mergemarkers(tr, data)
822 repo.obsstore.mergemarkers(tr, data)
823 repo.invalidatevolatilesets()
823 repo.invalidatevolatilesets()
824 return True
824 return True
825
825
826 # mapping of 'set-name' -> <function to compute this set>
826 # mapping of 'set-name' -> <function to compute this set>
827 cachefuncs = {}
827 cachefuncs = {}
828 def cachefor(name):
828 def cachefor(name):
829 """Decorator to register a function as computing the cache for a set"""
829 """Decorator to register a function as computing the cache for a set"""
830 def decorator(func):
830 def decorator(func):
831 if name in cachefuncs:
831 if name in cachefuncs:
832 msg = "duplicated registration for volatileset '%s' (existing: %r)"
832 msg = "duplicated registration for volatileset '%s' (existing: %r)"
833 raise error.ProgrammingError(msg % (name, cachefuncs[name]))
833 raise error.ProgrammingError(msg % (name, cachefuncs[name]))
834 cachefuncs[name] = func
834 cachefuncs[name] = func
835 return func
835 return func
836 return decorator
836 return decorator
837
837
838 def getrevs(repo, name):
838 def getrevs(repo, name):
839 """Return the set of revision that belong to the <name> set
839 """Return the set of revision that belong to the <name> set
840
840
841 Such access may compute the set and cache it for future use"""
841 Such access may compute the set and cache it for future use"""
842 repo = repo.unfiltered()
842 repo = repo.unfiltered()
843 if not repo.obsstore:
843 if not repo.obsstore:
844 return frozenset()
844 return frozenset()
845 if name not in repo.obsstore.caches:
845 if name not in repo.obsstore.caches:
846 repo.obsstore.caches[name] = cachefuncs[name](repo)
846 repo.obsstore.caches[name] = cachefuncs[name](repo)
847 return repo.obsstore.caches[name]
847 return repo.obsstore.caches[name]
848
848
849 # To be simple we need to invalidate obsolescence cache when:
849 # To be simple we need to invalidate obsolescence cache when:
850 #
850 #
851 # - new changeset is added:
851 # - new changeset is added:
852 # - public phase is changed
852 # - public phase is changed
853 # - obsolescence marker are added
853 # - obsolescence marker are added
854 # - strip is used a repo
854 # - strip is used a repo
855 def clearobscaches(repo):
855 def clearobscaches(repo):
856 """Remove all obsolescence related cache from a repo
856 """Remove all obsolescence related cache from a repo
857
857
858 This remove all cache in obsstore is the obsstore already exist on the
858 This remove all cache in obsstore is the obsstore already exist on the
859 repo.
859 repo.
860
860
861 (We could be smarter here given the exact event that trigger the cache
861 (We could be smarter here given the exact event that trigger the cache
862 clearing)"""
862 clearing)"""
863 # only clear cache is there is obsstore data in this repo
863 # only clear cache is there is obsstore data in this repo
864 if 'obsstore' in repo._filecache:
864 if 'obsstore' in repo._filecache:
865 repo.obsstore.caches.clear()
865 repo.obsstore.caches.clear()
866
866
867 def _mutablerevs(repo):
867 def _mutablerevs(repo):
868 """the set of mutable revision in the repository"""
868 """the set of mutable revision in the repository"""
869 return repo._phasecache.getrevset(repo, phases.mutablephases)
869 return repo._phasecache.getrevset(repo, phases.mutablephases)
870
870
871 @cachefor('obsolete')
871 @cachefor('obsolete')
872 def _computeobsoleteset(repo):
872 def _computeobsoleteset(repo):
873 """the set of obsolete revisions"""
873 """the set of obsolete revisions"""
874 getnode = repo.changelog.node
874 getnode = repo.changelog.node
875 notpublic = _mutablerevs(repo)
875 notpublic = _mutablerevs(repo)
876 isobs = repo.obsstore.successors.__contains__
876 isobs = repo.obsstore.successors.__contains__
877 obs = set(r for r in notpublic if isobs(getnode(r)))
877 obs = set(r for r in notpublic if isobs(getnode(r)))
878 return obs
878 return obs
879
879
880 @cachefor('orphan')
880 @cachefor('orphan')
881 def _computeorphanset(repo):
881 def _computeorphanset(repo):
882 """the set of non obsolete revisions with obsolete parents"""
882 """the set of non obsolete revisions with obsolete parents"""
883 pfunc = repo.changelog.parentrevs
883 pfunc = repo.changelog.parentrevs
884 mutable = _mutablerevs(repo)
884 mutable = _mutablerevs(repo)
885 obsolete = getrevs(repo, 'obsolete')
885 obsolete = getrevs(repo, 'obsolete')
886 others = mutable - obsolete
886 others = mutable - obsolete
887 unstable = set()
887 unstable = set()
888 for r in sorted(others):
888 for r in sorted(others):
889 # A rev is unstable if one of its parent is obsolete or unstable
889 # A rev is unstable if one of its parent is obsolete or unstable
890 # this works since we traverse following growing rev order
890 # this works since we traverse following growing rev order
891 for p in pfunc(r):
891 for p in pfunc(r):
892 if p in obsolete or p in unstable:
892 if p in obsolete or p in unstable:
893 unstable.add(r)
893 unstable.add(r)
894 break
894 break
895 return unstable
895 return unstable
896
896
897 @cachefor('suspended')
897 @cachefor('suspended')
898 def _computesuspendedset(repo):
898 def _computesuspendedset(repo):
899 """the set of obsolete parents with non obsolete descendants"""
899 """the set of obsolete parents with non obsolete descendants"""
900 suspended = repo.changelog.ancestors(getrevs(repo, 'orphan'))
900 suspended = repo.changelog.ancestors(getrevs(repo, 'orphan'))
901 return set(r for r in getrevs(repo, 'obsolete') if r in suspended)
901 return set(r for r in getrevs(repo, 'obsolete') if r in suspended)
902
902
903 @cachefor('extinct')
903 @cachefor('extinct')
904 def _computeextinctset(repo):
904 def _computeextinctset(repo):
905 """the set of obsolete parents without non obsolete descendants"""
905 """the set of obsolete parents without non obsolete descendants"""
906 return getrevs(repo, 'obsolete') - getrevs(repo, 'suspended')
906 return getrevs(repo, 'obsolete') - getrevs(repo, 'suspended')
907
907
908 @cachefor('phasedivergent')
908 @cachefor('phasedivergent')
909 def _computephasedivergentset(repo):
909 def _computephasedivergentset(repo):
910 """the set of revs trying to obsolete public revisions"""
910 """the set of revs trying to obsolete public revisions"""
911 bumped = set()
911 bumped = set()
912 # util function (avoid attribute lookup in the loop)
912 # util function (avoid attribute lookup in the loop)
913 phase = repo._phasecache.phase # would be faster to grab the full list
913 phase = repo._phasecache.phase # would be faster to grab the full list
914 public = phases.public
914 public = phases.public
915 cl = repo.changelog
915 cl = repo.changelog
916 torev = cl.nodemap.get
916 torev = cl.nodemap.get
917 tonode = cl.node
917 tonode = cl.node
918 for rev in repo.revs('(not public()) and (not obsolete())'):
918 for rev in repo.revs('(not public()) and (not obsolete())'):
919 # We only evaluate mutable, non-obsolete revision
919 # We only evaluate mutable, non-obsolete revision
920 node = tonode(rev)
920 node = tonode(rev)
921 # (future) A cache of predecessors may worth if split is very common
921 # (future) A cache of predecessors may worth if split is very common
922 for pnode in obsutil.allpredecessors(repo.obsstore, [node],
922 for pnode in obsutil.allpredecessors(repo.obsstore, [node],
923 ignoreflags=bumpedfix):
923 ignoreflags=bumpedfix):
924 prev = torev(pnode) # unfiltered! but so is phasecache
924 prev = torev(pnode) # unfiltered! but so is phasecache
925 if (prev is not None) and (phase(repo, prev) <= public):
925 if (prev is not None) and (phase(repo, prev) <= public):
926 # we have a public predecessor
926 # we have a public predecessor
927 bumped.add(rev)
927 bumped.add(rev)
928 break # Next draft!
928 break # Next draft!
929 return bumped
929 return bumped
930
930
931 @cachefor('contentdivergent')
931 @cachefor('contentdivergent')
932 def _computecontentdivergentset(repo):
932 def _computecontentdivergentset(repo):
933 """the set of rev that compete to be the final successors of some revision.
933 """the set of rev that compete to be the final successors of some revision.
934 """
934 """
935 divergent = set()
935 divergent = set()
936 obsstore = repo.obsstore
936 obsstore = repo.obsstore
937 newermap = {}
937 newermap = {}
938 tonode = repo.changelog.node
938 tonode = repo.changelog.node
939 for rev in repo.revs('(not public()) - obsolete()'):
939 for rev in repo.revs('(not public()) - obsolete()'):
940 node = tonode(rev)
940 node = tonode(rev)
941 mark = obsstore.predecessors.get(node, ())
941 mark = obsstore.predecessors.get(node, ())
942 toprocess = set(mark)
942 toprocess = set(mark)
943 seen = set()
943 seen = set()
944 while toprocess:
944 while toprocess:
945 prec = toprocess.pop()[0]
945 prec = toprocess.pop()[0]
946 if prec in seen:
946 if prec in seen:
947 continue # emergency cycle hanging prevention
947 continue # emergency cycle hanging prevention
948 seen.add(prec)
948 seen.add(prec)
949 if prec not in newermap:
949 if prec not in newermap:
950 obsutil.successorssets(repo, prec, cache=newermap)
950 obsutil.successorssets(repo, prec, cache=newermap)
951 newer = [n for n in newermap[prec] if n]
951 newer = [n for n in newermap[prec] if n]
952 if len(newer) > 1:
952 if len(newer) > 1:
953 divergent.add(rev)
953 divergent.add(rev)
954 break
954 break
955 toprocess.update(obsstore.predecessors.get(prec, ()))
955 toprocess.update(obsstore.predecessors.get(prec, ()))
956 return divergent
956 return divergent
957
957
958 def makefoldid(relation, user):
958 def makefoldid(relation, user):
959
959
960 folddigest = hashlib.sha1(user)
960 folddigest = hashlib.sha1(user)
961 for p in relation[0] + relation[1]:
961 for p in relation[0] + relation[1]:
962 folddigest.update('%d' % p.rev())
962 folddigest.update('%d' % p.rev())
963 folddigest.update(p.node())
963 folddigest.update(p.node())
964 # Since fold only has to compete against fold for the same successors, it
964 # Since fold only has to compete against fold for the same successors, it
965 # seems fine to use a small ID. Smaller ID save space.
965 # seems fine to use a small ID. Smaller ID save space.
966 return node.hex(folddigest.digest())[:8]
966 return node.hex(folddigest.digest())[:8]
967
967
968 def createmarkers(repo, relations, flag=0, date=None, metadata=None,
968 def createmarkers(repo, relations, flag=0, date=None, metadata=None,
969 operation=None):
969 operation=None):
970 """Add obsolete markers between changesets in a repo
970 """Add obsolete markers between changesets in a repo
971
971
972 <relations> must be an iterable of ((<old>,...), (<new>, ...)[,{metadata}])
972 <relations> must be an iterable of ((<old>,...), (<new>, ...)[,{metadata}])
973 tuple. `old` and `news` are changectx. metadata is an optional dictionary
973 tuple. `old` and `news` are changectx. metadata is an optional dictionary
974 containing metadata for this marker only. It is merged with the global
974 containing metadata for this marker only. It is merged with the global
975 metadata specified through the `metadata` argument of this function.
975 metadata specified through the `metadata` argument of this function.
976 Any string values in metadata must be UTF-8 bytes.
976 Any string values in metadata must be UTF-8 bytes.
977
977
978 Trying to obsolete a public changeset will raise an exception.
978 Trying to obsolete a public changeset will raise an exception.
979
979
980 Current user and date are used except if specified otherwise in the
980 Current user and date are used except if specified otherwise in the
981 metadata attribute.
981 metadata attribute.
982
982
983 This function operates within a transaction of its own, but does
983 This function operates within a transaction of its own, but does
984 not take any lock on the repo.
984 not take any lock on the repo.
985 """
985 """
986 # prepare metadata
986 # prepare metadata
987 if metadata is None:
987 if metadata is None:
988 metadata = {}
988 metadata = {}
989 if 'user' not in metadata:
989 if 'user' not in metadata:
990 luser = repo.ui.config('devel', 'user.obsmarker') or repo.ui.username()
990 luser = repo.ui.config('devel', 'user.obsmarker') or repo.ui.username()
991 metadata['user'] = encoding.fromlocal(luser)
991 metadata['user'] = encoding.fromlocal(luser)
992
992
993 # Operation metadata handling
993 # Operation metadata handling
994 useoperation = repo.ui.configbool('experimental',
994 useoperation = repo.ui.configbool('experimental',
995 'evolution.track-operation')
995 'evolution.track-operation')
996 if useoperation and operation:
996 if useoperation and operation:
997 metadata['operation'] = operation
997 metadata['operation'] = operation
998
998
999 # Effect flag metadata handling
999 # Effect flag metadata handling
1000 saveeffectflag = repo.ui.configbool('experimental',
1000 saveeffectflag = repo.ui.configbool('experimental',
1001 'evolution.effect-flags')
1001 'evolution.effect-flags')
1002
1002
1003 with repo.transaction('add-obsolescence-marker') as tr:
1003 with repo.transaction('add-obsolescence-marker') as tr:
1004 markerargs = []
1004 markerargs = []
1005 for rel in relations:
1005 for rel in relations:
1006 predecessors = rel[0]
1006 predecessors = rel[0]
1007 if not isinstance(predecessors, tuple):
1007 if not isinstance(predecessors, tuple):
1008 # preserve compat with old API until all caller are migrated
1008 # preserve compat with old API until all caller are migrated
1009 predecessors = (predecessors,)
1009 predecessors = (predecessors,)
1010 if len(predecessors) > 1 and len(rel[1]) != 1:
1010 if len(predecessors) > 1 and len(rel[1]) != 1:
1011 msg = 'Fold markers can only have 1 successors, not %d'
1011 msg = 'Fold markers can only have 1 successors, not %d'
1012 raise error.ProgrammingError(msg % len(rel[1]))
1012 raise error.ProgrammingError(msg % len(rel[1]))
1013 foldid = None
1013 foldid = None
1014 foldsize = len(predecessors)
1014 foldsize = len(predecessors)
1015 if 1 < foldsize:
1015 if 1 < foldsize:
1016 foldid = makefoldid(rel, metadata['user'])
1016 foldid = makefoldid(rel, metadata['user'])
1017 for foldidx, prec in enumerate(predecessors, 1):
1017 for foldidx, prec in enumerate(predecessors, 1):
1018 sucs = rel[1]
1018 sucs = rel[1]
1019 localmetadata = metadata.copy()
1019 localmetadata = metadata.copy()
1020 if len(rel) > 2:
1020 if len(rel) > 2:
1021 localmetadata.update(rel[2])
1021 localmetadata.update(rel[2])
1022 if foldid is not None:
1022 if foldid is not None:
1023 localmetadata['fold-id'] = foldid
1023 localmetadata['fold-id'] = foldid
1024 localmetadata['fold-idx'] = '%d' % foldidx
1024 localmetadata['fold-idx'] = '%d' % foldidx
1025 localmetadata['fold-size'] = '%d' % foldsize
1025 localmetadata['fold-size'] = '%d' % foldsize
1026
1026
1027 if not prec.mutable():
1027 if not prec.mutable():
1028 raise error.Abort(_("cannot obsolete public changeset: %s")
1028 raise error.Abort(_("cannot obsolete public changeset: %s")
1029 % prec,
1029 % prec,
1030 hint="see 'hg help phases' for details")
1030 hint="see 'hg help phases' for details")
1031 nprec = prec.node()
1031 nprec = prec.node()
1032 nsucs = tuple(s.node() for s in sucs)
1032 nsucs = tuple(s.node() for s in sucs)
1033 npare = None
1033 npare = None
1034 if not nsucs:
1034 if not nsucs:
1035 npare = tuple(p.node() for p in prec.parents())
1035 npare = tuple(p.node() for p in prec.parents())
1036 if nprec in nsucs:
1036 if nprec in nsucs:
1037 raise error.Abort(_("changeset %s cannot obsolete itself")
1037 raise error.Abort(_("changeset %s cannot obsolete itself")
1038 % prec)
1038 % prec)
1039
1039
1040 # Effect flag can be different by relation
1040 # Effect flag can be different by relation
1041 if saveeffectflag:
1041 if saveeffectflag:
1042 # The effect flag is saved in a versioned field name for
1042 # The effect flag is saved in a versioned field name for
1043 # future evolution
1043 # future evolution
1044 effectflag = obsutil.geteffectflag(prec, sucs)
1044 effectflag = obsutil.geteffectflag(prec, sucs)
1045 localmetadata[obsutil.EFFECTFLAGFIELD] = "%d" % effectflag
1045 localmetadata[obsutil.EFFECTFLAGFIELD] = "%d" % effectflag
1046
1046
1047 # Creating the marker causes the hidden cache to become
1047 # Creating the marker causes the hidden cache to become
1048 # invalid, which causes recomputation when we ask for
1048 # invalid, which causes recomputation when we ask for
1049 # prec.parents() above. Resulting in n^2 behavior. So let's
1049 # prec.parents() above. Resulting in n^2 behavior. So let's
1050 # prepare all of the args first, then create the markers.
1050 # prepare all of the args first, then create the markers.
1051 markerargs.append((nprec, nsucs, npare, localmetadata))
1051 markerargs.append((nprec, nsucs, npare, localmetadata))
1052
1052
1053 for args in markerargs:
1053 for args in markerargs:
1054 nprec, nsucs, npare, localmetadata = args
1054 nprec, nsucs, npare, localmetadata = args
1055 repo.obsstore.create(tr, nprec, nsucs, flag, parents=npare,
1055 repo.obsstore.create(tr, nprec, nsucs, flag, parents=npare,
1056 date=date, metadata=localmetadata,
1056 date=date, metadata=localmetadata,
1057 ui=repo.ui)
1057 ui=repo.ui)
1058 repo.filteredrevcache.clear()
1058 repo.filteredrevcache.clear()
@@ -1,1622 +1,1641 b''
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}{if(obsfate, " [{join(obsfate, "; ")}]")}\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(b'listkeys %s\n' % (namespace,))
21 > ui.write(b'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 > evolution=exchange
42 > evolution=exchange
43 > evolution.createmarkers=True
43 > evolution.createmarkers=True
44 > EOF
44 > EOF
45
45
46 Killing a single changeset without replacement
46 Killing a single changeset without replacement
47
47
48 $ hg debugobsolete 0
48 $ hg debugobsolete 0
49 abort: changeset references must be full hexadecimal node identifiers
49 abort: changeset references must be full hexadecimal node identifiers
50 [255]
50 [255]
51 $ hg debugobsolete '00'
51 $ hg debugobsolete '00'
52 abort: changeset references must be full hexadecimal node identifiers
52 abort: changeset references must be full hexadecimal node identifiers
53 [255]
53 [255]
54 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
54 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
55 obsoleted 1 changesets
55 obsoleted 1 changesets
56 $ hg debugobsolete
56 $ hg debugobsolete
57 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'babar'}
57 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'babar'}
58
58
59 (test that mercurial is not confused)
59 (test that mercurial is not confused)
60
60
61 $ hg up null --quiet # having 0 as parent prevents it to be hidden
61 $ hg up null --quiet # having 0 as parent prevents it to be hidden
62 $ hg tip
62 $ hg tip
63 -1:000000000000 (public) [tip ]
63 -1:000000000000 (public) [tip ]
64 $ hg up --hidden tip --quiet
64 $ hg up --hidden tip --quiet
65 updated to hidden changeset 97b7c2d76b18
65 updated to hidden changeset 97b7c2d76b18
66 (hidden revision '97b7c2d76b18' is pruned)
66 (hidden revision '97b7c2d76b18' is pruned)
67
67
68 Killing a single changeset with itself should fail
68 Killing a single changeset with itself should fail
69 (simple local safeguard)
69 (simple local safeguard)
70
70
71 $ hg debugobsolete `getid kill_me` `getid kill_me`
71 $ hg debugobsolete `getid kill_me` `getid kill_me`
72 abort: bad obsmarker input: in-marker cycle with 97b7c2d76b1845ed3eb988cd612611e72406cef0
72 abort: bad obsmarker input: in-marker cycle with 97b7c2d76b1845ed3eb988cd612611e72406cef0
73 [255]
73 [255]
74
74
75 $ cd ..
75 $ cd ..
76
76
77 Killing a single changeset with replacement
77 Killing a single changeset with replacement
78 (and testing the format option)
78 (and testing the format option)
79
79
80 $ hg init tmpb
80 $ hg init tmpb
81 $ cd tmpb
81 $ cd tmpb
82 $ mkcommit a
82 $ mkcommit a
83 $ mkcommit b
83 $ mkcommit b
84 $ mkcommit original_c
84 $ mkcommit original_c
85 $ hg up "desc('b')"
85 $ hg up "desc('b')"
86 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
86 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
87 $ mkcommit new_c
87 $ mkcommit new_c
88 created new head
88 created new head
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 $ hg debugobsolete --config format.obsstore-version=0 --flag 12 `getid original_c` `getid new_c` -d '121 120'
90 $ hg debugobsolete --config format.obsstore-version=0 --flag 12 `getid original_c` `getid new_c` -d '121 120'
91 obsoleted 1 changesets
91 obsoleted 1 changesets
92 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
92 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
93 2:245bde4270cd add original_c
93 2:245bde4270cd add original_c
94 $ hg debugrevlog -cd
94 $ hg debugrevlog -cd
95 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
95 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
96 0 -1 -1 0 59 0 0 0 0 58 58 0 1 0
96 0 -1 -1 0 59 0 0 0 0 58 58 0 1 0
97 1 0 -1 59 118 59 59 0 0 58 116 0 1 0
97 1 0 -1 59 118 59 59 0 0 58 116 0 1 0
98 2 1 -1 118 193 118 118 59 0 76 192 0 1 0
98 2 1 -1 118 193 118 118 59 0 76 192 0 1 0
99 3 1 -1 193 260 193 193 59 0 66 258 0 2 0
99 3 1 -1 193 260 193 193 59 0 66 258 0 2 0
100 $ hg debugobsolete
100 $ hg debugobsolete
101 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
101 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
102
102
103 (check for version number of the obsstore)
103 (check for version number of the obsstore)
104
104
105 $ dd bs=1 count=1 if=.hg/store/obsstore 2>/dev/null
105 $ dd bs=1 count=1 if=.hg/store/obsstore 2>/dev/null
106 \x00 (no-eol) (esc)
106 \x00 (no-eol) (esc)
107
107
108 do it again (it read the obsstore before adding new changeset)
108 do it again (it read the obsstore before adding new changeset)
109
109
110 $ hg up '.^'
110 $ hg up '.^'
111 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
111 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
112 $ mkcommit new_2_c
112 $ mkcommit new_2_c
113 created new head
113 created new head
114 $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
114 $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
115 obsoleted 1 changesets
115 obsoleted 1 changesets
116 $ hg debugobsolete
116 $ hg debugobsolete
117 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
117 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
118 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
118 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
119
119
120 Register two markers with a missing node
120 Register two markers with a missing node
121
121
122 $ hg up '.^'
122 $ hg up '.^'
123 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
123 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
124 $ mkcommit new_3_c
124 $ mkcommit new_3_c
125 created new head
125 created new head
126 $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
126 $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
127 obsoleted 1 changesets
127 obsoleted 1 changesets
128 $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
128 $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
129 $ hg debugobsolete
129 $ hg debugobsolete
130 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
130 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
131 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
131 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
132 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
132 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
133 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
133 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
134
134
135 Test the --index option of debugobsolete command
135 Test the --index option of debugobsolete command
136 $ hg debugobsolete --index
136 $ hg debugobsolete --index
137 0 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
137 0 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
138 1 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
138 1 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
139 2 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
139 2 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
140 3 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
140 3 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
141
141
142 Refuse pathological nullid successors
142 Refuse pathological nullid successors
143 $ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
143 $ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
144 transaction abort!
144 transaction abort!
145 rollback completed
145 rollback completed
146 abort: bad obsolescence marker detected: invalid successors nullid
146 abort: bad obsolescence marker detected: invalid successors nullid
147 [255]
147 [255]
148
148
149 Check that graphlog detect that a changeset is obsolete:
149 Check that graphlog detect that a changeset is obsolete:
150
150
151 $ hg log -G
151 $ hg log -G
152 @ 5:5601fb93a350 (draft) [tip ] add new_3_c
152 @ 5:5601fb93a350 (draft) [tip ] add new_3_c
153 |
153 |
154 o 1:7c3bad9141dc (draft) [ ] add b
154 o 1:7c3bad9141dc (draft) [ ] add b
155 |
155 |
156 o 0:1f0dee641bb7 (draft) [ ] add a
156 o 0:1f0dee641bb7 (draft) [ ] add a
157
157
158
158
159 check that heads does not report them
159 check that heads does not report them
160
160
161 $ hg heads
161 $ hg heads
162 5:5601fb93a350 (draft) [tip ] add new_3_c
162 5:5601fb93a350 (draft) [tip ] add new_3_c
163 $ hg heads --hidden
163 $ hg heads --hidden
164 5:5601fb93a350 (draft) [tip ] add new_3_c
164 5:5601fb93a350 (draft) [tip ] add new_3_c
165 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350]
165 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350]
166 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9]
166 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9]
167 2:245bde4270cd (draft *obsolete*) [ ] add original_c [rewritten as 3:cdbce2fbb163]
167 2:245bde4270cd (draft *obsolete*) [ ] add original_c [rewritten as 3:cdbce2fbb163]
168
168
169
169
170 check that summary does not report them
170 check that summary does not report them
171
171
172 $ hg init ../sink
172 $ hg init ../sink
173 $ echo '[paths]' >> .hg/hgrc
173 $ echo '[paths]' >> .hg/hgrc
174 $ echo 'default=../sink' >> .hg/hgrc
174 $ echo 'default=../sink' >> .hg/hgrc
175 $ hg summary --remote
175 $ hg summary --remote
176 parent: 5:5601fb93a350 tip
176 parent: 5:5601fb93a350 tip
177 add new_3_c
177 add new_3_c
178 branch: default
178 branch: default
179 commit: (clean)
179 commit: (clean)
180 update: (current)
180 update: (current)
181 phases: 3 draft
181 phases: 3 draft
182 remote: 3 outgoing
182 remote: 3 outgoing
183
183
184 $ hg summary --remote --hidden
184 $ hg summary --remote --hidden
185 parent: 5:5601fb93a350 tip
185 parent: 5:5601fb93a350 tip
186 add new_3_c
186 add new_3_c
187 branch: default
187 branch: default
188 commit: (clean)
188 commit: (clean)
189 update: 3 new changesets, 4 branch heads (merge)
189 update: 3 new changesets, 4 branch heads (merge)
190 phases: 6 draft
190 phases: 6 draft
191 remote: 3 outgoing
191 remote: 3 outgoing
192
192
193 check that various commands work well with filtering
193 check that various commands work well with filtering
194
194
195 $ hg tip
195 $ hg tip
196 5:5601fb93a350 (draft) [tip ] add new_3_c
196 5:5601fb93a350 (draft) [tip ] add new_3_c
197 $ hg log -r 6
197 $ hg log -r 6
198 abort: unknown revision '6'!
198 abort: unknown revision '6'!
199 [255]
199 [255]
200 $ hg log -r 4
200 $ hg log -r 4
201 abort: hidden revision '4' was rewritten as: 5601fb93a350!
201 abort: hidden revision '4' was rewritten as: 5601fb93a350!
202 (use --hidden to access hidden revisions)
202 (use --hidden to access hidden revisions)
203 [255]
203 [255]
204 $ hg debugrevspec 'rev(6)'
204 $ hg debugrevspec 'rev(6)'
205 $ hg debugrevspec 'rev(4)'
205 $ hg debugrevspec 'rev(4)'
206 $ hg debugrevspec 'null'
206 $ hg debugrevspec 'null'
207 -1
207 -1
208
208
209 Check that public changeset are not accounted as obsolete:
209 Check that public changeset are not accounted as obsolete:
210
210
211 $ hg --hidden phase --public 2
211 $ hg --hidden phase --public 2
212 1 new phase-divergent changesets
212 1 new phase-divergent changesets
213 $ hg log -G
213 $ hg log -G
214 @ 5:5601fb93a350 (draft phase-divergent) [tip ] add new_3_c
214 @ 5:5601fb93a350 (draft phase-divergent) [tip ] add new_3_c
215 |
215 |
216 | o 2:245bde4270cd (public) [ ] add original_c
216 | o 2:245bde4270cd (public) [ ] add original_c
217 |/
217 |/
218 o 1:7c3bad9141dc (public) [ ] add b
218 o 1:7c3bad9141dc (public) [ ] add b
219 |
219 |
220 o 0:1f0dee641bb7 (public) [ ] add a
220 o 0:1f0dee641bb7 (public) [ ] add a
221
221
222
222
223 And that bumped changeset are detected
223 And that bumped changeset are detected
224 --------------------------------------
224 --------------------------------------
225
225
226 If we didn't filtered obsolete changesets out, 3 and 4 would show up too. Also
226 If we didn't filtered obsolete changesets out, 3 and 4 would show up too. Also
227 note that the bumped changeset (5:5601fb93a350) is not a direct successor of
227 note that the bumped changeset (5:5601fb93a350) is not a direct successor of
228 the public changeset
228 the public changeset
229
229
230 $ hg log --hidden -r 'phasedivergent()'
230 $ hg log --hidden -r 'phasedivergent()'
231 5:5601fb93a350 (draft phase-divergent) [tip ] add new_3_c
231 5:5601fb93a350 (draft phase-divergent) [tip ] add new_3_c
232
232
233 And that we can't push bumped changeset
233 And that we can't push bumped changeset
234
234
235 $ hg push ../tmpa -r 0 --force #(make repo related)
235 $ hg push ../tmpa -r 0 --force #(make repo related)
236 pushing to ../tmpa
236 pushing to ../tmpa
237 searching for changes
237 searching for changes
238 warning: repository is unrelated
238 warning: repository is unrelated
239 adding changesets
239 adding changesets
240 adding manifests
240 adding manifests
241 adding file changes
241 adding file changes
242 added 1 changesets with 1 changes to 1 files (+1 heads)
242 added 1 changesets with 1 changes to 1 files (+1 heads)
243 $ hg push ../tmpa
243 $ hg push ../tmpa
244 pushing to ../tmpa
244 pushing to ../tmpa
245 searching for changes
245 searching for changes
246 abort: push includes phase-divergent changeset: 5601fb93a350!
246 abort: push includes phase-divergent changeset: 5601fb93a350!
247 [255]
247 [255]
248
248
249 Fixing "bumped" situation
249 Fixing "bumped" situation
250 We need to create a clone of 5 and add a special marker with a flag
250 We need to create a clone of 5 and add a special marker with a flag
251
251
252 $ hg summary
252 $ hg summary
253 parent: 5:5601fb93a350 tip (phase-divergent)
253 parent: 5:5601fb93a350 tip (phase-divergent)
254 add new_3_c
254 add new_3_c
255 branch: default
255 branch: default
256 commit: (clean)
256 commit: (clean)
257 update: 1 new changesets, 2 branch heads (merge)
257 update: 1 new changesets, 2 branch heads (merge)
258 phases: 1 draft
258 phases: 1 draft
259 phase-divergent: 1 changesets
259 phase-divergent: 1 changesets
260 $ hg up '5^'
260 $ hg up '5^'
261 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
261 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
262 $ hg revert -ar 5
262 $ hg revert -ar 5
263 adding new_3_c
263 adding new_3_c
264 $ hg ci -m 'add n3w_3_c'
264 $ hg ci -m 'add n3w_3_c'
265 created new head
265 created new head
266 $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c`
266 $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c`
267 obsoleted 1 changesets
267 obsoleted 1 changesets
268 $ hg log -r 'phasedivergent()'
268 $ hg log -r 'phasedivergent()'
269 $ hg log -G
269 $ hg log -G
270 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
270 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
271 |
271 |
272 | o 2:245bde4270cd (public) [ ] add original_c
272 | o 2:245bde4270cd (public) [ ] add original_c
273 |/
273 |/
274 o 1:7c3bad9141dc (public) [ ] add b
274 o 1:7c3bad9141dc (public) [ ] add b
275 |
275 |
276 o 0:1f0dee641bb7 (public) [ ] add a
276 o 0:1f0dee641bb7 (public) [ ] add a
277
277
278
278
279 Basic exclusive testing
279 Basic exclusive testing
280
280
281 $ hg log -G --hidden
281 $ hg log -G --hidden
282 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
282 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
283 |
283 |
284 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c [rewritten as 6:6f9641995072]
284 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c [rewritten as 6:6f9641995072]
285 |/
285 |/
286 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350]
286 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350]
287 |/
287 |/
288 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9]
288 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9]
289 |/
289 |/
290 | o 2:245bde4270cd (public) [ ] add original_c
290 | o 2:245bde4270cd (public) [ ] add original_c
291 |/
291 |/
292 o 1:7c3bad9141dc (public) [ ] add b
292 o 1:7c3bad9141dc (public) [ ] add b
293 |
293 |
294 o 0:1f0dee641bb7 (public) [ ] add a
294 o 0:1f0dee641bb7 (public) [ ] add a
295
295
296 $ hg debugobsolete --rev 6f9641995072
296 $ hg debugobsolete --rev 6f9641995072
297 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
297 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
298 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
298 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
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 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
300 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
301 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
301 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
302 $ hg debugobsolete --rev 6f9641995072 --exclusive
302 $ hg debugobsolete --rev 6f9641995072 --exclusive
303 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
303 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
304 $ hg debugobsolete --rev 5601fb93a350 --hidden
304 $ hg debugobsolete --rev 5601fb93a350 --hidden
305 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
305 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
306 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
306 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
307 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
307 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
308 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
308 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
309 $ hg debugobsolete --rev 5601fb93a350 --hidden --exclusive
309 $ hg debugobsolete --rev 5601fb93a350 --hidden --exclusive
310 $ hg debugobsolete --rev 5601fb93a350+6f9641995072 --hidden --exclusive
310 $ hg debugobsolete --rev 5601fb93a350+6f9641995072 --hidden --exclusive
311 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
311 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
312 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
312 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
313 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
313 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
314
314
315 $ cd ..
315 $ cd ..
316
316
317 Revision 0 is hidden
317 Revision 0 is hidden
318 --------------------
318 --------------------
319
319
320 $ hg init rev0hidden
320 $ hg init rev0hidden
321 $ cd rev0hidden
321 $ cd rev0hidden
322
322
323 $ mkcommit kill0
323 $ mkcommit kill0
324 $ hg up -q null
324 $ hg up -q null
325 $ hg debugobsolete `getid kill0`
325 $ hg debugobsolete `getid kill0`
326 obsoleted 1 changesets
326 obsoleted 1 changesets
327 $ mkcommit a
327 $ mkcommit a
328 $ mkcommit b
328 $ mkcommit b
329
329
330 Should pick the first visible revision as "repo" node
330 Should pick the first visible revision as "repo" node
331
331
332 $ hg archive ../archive-null
332 $ hg archive ../archive-null
333 $ cat ../archive-null/.hg_archival.txt
333 $ cat ../archive-null/.hg_archival.txt
334 repo: 1f0dee641bb7258c56bd60e93edfa2405381c41e
334 repo: 1f0dee641bb7258c56bd60e93edfa2405381c41e
335 node: 7c3bad9141dcb46ff89abf5f61856facd56e476c
335 node: 7c3bad9141dcb46ff89abf5f61856facd56e476c
336 branch: default
336 branch: default
337 latesttag: null
337 latesttag: null
338 latesttagdistance: 2
338 latesttagdistance: 2
339 changessincelatesttag: 2
339 changessincelatesttag: 2
340
340
341
341
342 $ cd ..
342 $ cd ..
343
343
344 Can disable transaction summary report
344 Can disable transaction summary report
345
345
346 $ hg init transaction-summary
346 $ hg init transaction-summary
347 $ cd transaction-summary
347 $ cd transaction-summary
348 $ mkcommit a
348 $ mkcommit a
349 $ mkcommit b
349 $ mkcommit b
350 $ hg up -q null
350 $ hg up -q null
351 $ hg --config experimental.evolution.report-instabilities=false debugobsolete `getid a`
351 $ hg --config experimental.evolution.report-instabilities=false debugobsolete `getid a`
352 obsoleted 1 changesets
352 obsoleted 1 changesets
353 $ cd ..
353 $ cd ..
354
354
355 Exchange Test
355 Exchange Test
356 ============================
356 ============================
357
357
358 Destination repo does not have any data
358 Destination repo does not have any data
359 ---------------------------------------
359 ---------------------------------------
360
360
361 Simple incoming test
361 Simple incoming test
362
362
363 $ hg init tmpc
363 $ hg init tmpc
364 $ cd tmpc
364 $ cd tmpc
365 $ hg incoming ../tmpb
365 $ hg incoming ../tmpb
366 comparing with ../tmpb
366 comparing with ../tmpb
367 0:1f0dee641bb7 (public) [ ] add a
367 0:1f0dee641bb7 (public) [ ] add a
368 1:7c3bad9141dc (public) [ ] add b
368 1:7c3bad9141dc (public) [ ] add b
369 2:245bde4270cd (public) [ ] add original_c
369 2:245bde4270cd (public) [ ] add original_c
370 6:6f9641995072 (draft) [tip ] add n3w_3_c
370 6:6f9641995072 (draft) [tip ] add n3w_3_c
371
371
372 Try to pull markers
372 Try to pull markers
373 (extinct changeset are excluded but marker are pushed)
373 (extinct changeset are excluded but marker are pushed)
374
374
375 $ hg pull ../tmpb
375 $ hg pull ../tmpb
376 pulling from ../tmpb
376 pulling from ../tmpb
377 requesting all changes
377 requesting all changes
378 adding changesets
378 adding changesets
379 adding manifests
379 adding manifests
380 adding file changes
380 adding file changes
381 added 4 changesets with 4 changes to 4 files (+1 heads)
381 added 4 changesets with 4 changes to 4 files (+1 heads)
382 5 new obsolescence markers
382 5 new obsolescence markers
383 new changesets 1f0dee641bb7:6f9641995072 (1 drafts)
383 new changesets 1f0dee641bb7:6f9641995072 (1 drafts)
384 (run 'hg heads' to see heads, 'hg merge' to merge)
384 (run 'hg heads' to see heads, 'hg merge' to merge)
385 $ hg debugobsolete
385 $ hg debugobsolete
386 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
386 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
387 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
387 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
388 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
388 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
389 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
389 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
390 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
390 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
391
391
392 Rollback//Transaction support
392 Rollback//Transaction support
393
393
394 $ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
394 $ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
395 $ hg debugobsolete
395 $ hg debugobsolete
396 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
396 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
397 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
397 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
398 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
398 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
399 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
399 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
400 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
400 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
401 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:22:20 1970 +0000) {'user': 'test'}
401 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:22:20 1970 +0000) {'user': 'test'}
402 $ hg rollback -n
402 $ hg rollback -n
403 repository tip rolled back to revision 3 (undo debugobsolete)
403 repository tip rolled back to revision 3 (undo debugobsolete)
404 $ hg rollback
404 $ hg rollback
405 repository tip rolled back to revision 3 (undo debugobsolete)
405 repository tip rolled back to revision 3 (undo debugobsolete)
406 $ hg debugobsolete
406 $ hg debugobsolete
407 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
407 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
408 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
408 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
409 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
409 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
410 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
410 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
411 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
411 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
412
412
413 $ cd ..
413 $ cd ..
414
414
415 Try to push markers
415 Try to push markers
416
416
417 $ hg init tmpd
417 $ hg init tmpd
418 $ hg -R tmpb push tmpd
418 $ hg -R tmpb push tmpd
419 pushing to tmpd
419 pushing to tmpd
420 searching for changes
420 searching for changes
421 adding changesets
421 adding changesets
422 adding manifests
422 adding manifests
423 adding file changes
423 adding file changes
424 added 4 changesets with 4 changes to 4 files (+1 heads)
424 added 4 changesets with 4 changes to 4 files (+1 heads)
425 5 new obsolescence markers
425 5 new obsolescence markers
426 $ hg -R tmpd debugobsolete | sort
426 $ hg -R tmpd debugobsolete | sort
427 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
427 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
428 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
428 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
429 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
429 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
430 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
430 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
431 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
431 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
432
432
433 Check obsolete keys are exchanged only if source has an obsolete store
433 Check obsolete keys are exchanged only if source has an obsolete store
434
434
435 $ hg init empty
435 $ hg init empty
436 $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
436 $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
437 pushing to tmpd
437 pushing to tmpd
438 listkeys phases
438 listkeys phases
439 listkeys bookmarks
439 listkeys bookmarks
440 no changes found
440 no changes found
441 listkeys phases
441 listkeys phases
442 [1]
442 [1]
443
443
444 clone support
444 clone support
445 (markers are copied and extinct changesets are included to allow hardlinks)
445 (markers are copied and extinct changesets are included to allow hardlinks)
446
446
447 $ hg clone tmpb clone-dest
447 $ hg clone tmpb clone-dest
448 updating to branch default
448 updating to branch default
449 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
449 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
450 $ hg -R clone-dest log -G --hidden
450 $ hg -R clone-dest log -G --hidden
451 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
451 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
452 |
452 |
453 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c [rewritten as 6:6f9641995072]
453 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c [rewritten as 6:6f9641995072]
454 |/
454 |/
455 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350]
455 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350]
456 |/
456 |/
457 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9]
457 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9]
458 |/
458 |/
459 | o 2:245bde4270cd (public) [ ] add original_c
459 | o 2:245bde4270cd (public) [ ] add original_c
460 |/
460 |/
461 o 1:7c3bad9141dc (public) [ ] add b
461 o 1:7c3bad9141dc (public) [ ] add b
462 |
462 |
463 o 0:1f0dee641bb7 (public) [ ] add a
463 o 0:1f0dee641bb7 (public) [ ] add a
464
464
465 $ hg -R clone-dest debugobsolete
465 $ hg -R clone-dest debugobsolete
466 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
466 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
467 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
467 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
468 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
468 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
469 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
469 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
470 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
470 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
471
471
472
472
473 Destination repo have existing data
473 Destination repo have existing data
474 ---------------------------------------
474 ---------------------------------------
475
475
476 On pull
476 On pull
477
477
478 $ hg init tmpe
478 $ hg init tmpe
479 $ cd tmpe
479 $ cd tmpe
480 $ hg debugobsolete -d '1339 0' 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00
480 $ hg debugobsolete -d '1339 0' 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00
481 $ hg pull ../tmpb
481 $ hg pull ../tmpb
482 pulling from ../tmpb
482 pulling from ../tmpb
483 requesting all changes
483 requesting all changes
484 adding changesets
484 adding changesets
485 adding manifests
485 adding manifests
486 adding file changes
486 adding file changes
487 added 4 changesets with 4 changes to 4 files (+1 heads)
487 added 4 changesets with 4 changes to 4 files (+1 heads)
488 5 new obsolescence markers
488 5 new obsolescence markers
489 new changesets 1f0dee641bb7:6f9641995072 (1 drafts)
489 new changesets 1f0dee641bb7:6f9641995072 (1 drafts)
490 (run 'hg heads' to see heads, 'hg merge' to merge)
490 (run 'hg heads' to see heads, 'hg merge' to merge)
491 $ hg debugobsolete
491 $ hg debugobsolete
492 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
492 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
493 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
493 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
494 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
494 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
495 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
495 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
496 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
496 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
497 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
497 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
498
498
499
499
500 On push
500 On push
501
501
502 $ hg push ../tmpc
502 $ hg push ../tmpc
503 pushing to ../tmpc
503 pushing to ../tmpc
504 searching for changes
504 searching for changes
505 no changes found
505 no changes found
506 1 new obsolescence markers
506 1 new obsolescence markers
507 [1]
507 [1]
508 $ hg -R ../tmpc debugobsolete
508 $ hg -R ../tmpc debugobsolete
509 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
509 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
510 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
510 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
511 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
511 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
512 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
512 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
513 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
513 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
514 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
514 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
515
515
516 detect outgoing obsolete and unstable
516 detect outgoing obsolete and unstable
517 ---------------------------------------
517 ---------------------------------------
518
518
519
519
520 $ hg log -G
520 $ hg log -G
521 o 3:6f9641995072 (draft) [tip ] add n3w_3_c
521 o 3:6f9641995072 (draft) [tip ] add n3w_3_c
522 |
522 |
523 | o 2:245bde4270cd (public) [ ] add original_c
523 | o 2:245bde4270cd (public) [ ] add original_c
524 |/
524 |/
525 o 1:7c3bad9141dc (public) [ ] add b
525 o 1:7c3bad9141dc (public) [ ] add b
526 |
526 |
527 o 0:1f0dee641bb7 (public) [ ] add a
527 o 0:1f0dee641bb7 (public) [ ] add a
528
528
529 $ hg up 'desc("n3w_3_c")'
529 $ hg up 'desc("n3w_3_c")'
530 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
530 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
531 $ mkcommit original_d
531 $ mkcommit original_d
532 $ mkcommit original_e
532 $ mkcommit original_e
533 $ hg debugobsolete --record-parents `getid original_d` -d '0 0'
533 $ hg debugobsolete --record-parents `getid original_d` -d '0 0'
534 obsoleted 1 changesets
534 obsoleted 1 changesets
535 1 new orphan changesets
535 1 new orphan changesets
536 $ hg debugobsolete | grep `getid original_d`
536 $ hg debugobsolete | grep `getid original_d`
537 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
537 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
538 $ hg log -r 'obsolete()'
538 $ hg log -r 'obsolete()'
539 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
539 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
540 $ hg summary
540 $ hg summary
541 parent: 5:cda648ca50f5 tip (orphan)
541 parent: 5:cda648ca50f5 tip (orphan)
542 add original_e
542 add original_e
543 branch: default
543 branch: default
544 commit: (clean)
544 commit: (clean)
545 update: 1 new changesets, 2 branch heads (merge)
545 update: 1 new changesets, 2 branch heads (merge)
546 phases: 3 draft
546 phases: 3 draft
547 orphan: 1 changesets
547 orphan: 1 changesets
548 $ hg log -G -r '::orphan()'
548 $ hg log -G -r '::orphan()'
549 @ 5:cda648ca50f5 (draft orphan) [tip ] add original_e
549 @ 5:cda648ca50f5 (draft orphan) [tip ] add original_e
550 |
550 |
551 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
551 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
552 |
552 |
553 o 3:6f9641995072 (draft) [ ] add n3w_3_c
553 o 3:6f9641995072 (draft) [ ] add n3w_3_c
554 |
554 |
555 o 1:7c3bad9141dc (public) [ ] add b
555 o 1:7c3bad9141dc (public) [ ] add b
556 |
556 |
557 o 0:1f0dee641bb7 (public) [ ] add a
557 o 0:1f0dee641bb7 (public) [ ] add a
558
558
559
559
560 refuse to push obsolete changeset
560 refuse to push obsolete changeset
561
561
562 $ hg push ../tmpc/ -r 'desc("original_d")'
562 $ hg push ../tmpc/ -r 'desc("original_d")'
563 pushing to ../tmpc/
563 pushing to ../tmpc/
564 searching for changes
564 searching for changes
565 abort: push includes obsolete changeset: 94b33453f93b!
565 abort: push includes obsolete changeset: 94b33453f93b!
566 [255]
566 [255]
567
567
568 refuse to push unstable changeset
568 refuse to push unstable changeset
569
569
570 $ hg push ../tmpc/
570 $ hg push ../tmpc/
571 pushing to ../tmpc/
571 pushing to ../tmpc/
572 searching for changes
572 searching for changes
573 abort: push includes orphan changeset: cda648ca50f5!
573 abort: push includes orphan changeset: cda648ca50f5!
574 [255]
574 [255]
575
575
576 Test that extinct changeset are properly detected
576 Test that extinct changeset are properly detected
577
577
578 $ hg log -r 'extinct()'
578 $ hg log -r 'extinct()'
579
579
580 Don't try to push extinct changeset
580 Don't try to push extinct changeset
581
581
582 $ hg init ../tmpf
582 $ hg init ../tmpf
583 $ hg out ../tmpf
583 $ hg out ../tmpf
584 comparing with ../tmpf
584 comparing with ../tmpf
585 searching for changes
585 searching for changes
586 0:1f0dee641bb7 (public) [ ] add a
586 0:1f0dee641bb7 (public) [ ] add a
587 1:7c3bad9141dc (public) [ ] add b
587 1:7c3bad9141dc (public) [ ] add b
588 2:245bde4270cd (public) [ ] add original_c
588 2:245bde4270cd (public) [ ] add original_c
589 3:6f9641995072 (draft) [ ] add n3w_3_c
589 3:6f9641995072 (draft) [ ] add n3w_3_c
590 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
590 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
591 5:cda648ca50f5 (draft orphan) [tip ] add original_e
591 5:cda648ca50f5 (draft orphan) [tip ] add original_e
592 $ hg push ../tmpf -f # -f because be push unstable too
592 $ hg push ../tmpf -f # -f because be push unstable too
593 pushing to ../tmpf
593 pushing to ../tmpf
594 searching for changes
594 searching for changes
595 adding changesets
595 adding changesets
596 adding manifests
596 adding manifests
597 adding file changes
597 adding file changes
598 added 6 changesets with 6 changes to 6 files (+1 heads)
598 added 6 changesets with 6 changes to 6 files (+1 heads)
599 7 new obsolescence markers
599 7 new obsolescence markers
600 1 new orphan changesets
600 1 new orphan changesets
601
601
602 no warning displayed
602 no warning displayed
603
603
604 $ hg push ../tmpf
604 $ hg push ../tmpf
605 pushing to ../tmpf
605 pushing to ../tmpf
606 searching for changes
606 searching for changes
607 no changes found
607 no changes found
608 [1]
608 [1]
609
609
610 Do not warn about new head when the new head is a successors of a remote one
610 Do not warn about new head when the new head is a successors of a remote one
611
611
612 $ hg log -G
612 $ hg log -G
613 @ 5:cda648ca50f5 (draft orphan) [tip ] add original_e
613 @ 5:cda648ca50f5 (draft orphan) [tip ] add original_e
614 |
614 |
615 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
615 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
616 |
616 |
617 o 3:6f9641995072 (draft) [ ] add n3w_3_c
617 o 3:6f9641995072 (draft) [ ] add n3w_3_c
618 |
618 |
619 | o 2:245bde4270cd (public) [ ] add original_c
619 | o 2:245bde4270cd (public) [ ] add original_c
620 |/
620 |/
621 o 1:7c3bad9141dc (public) [ ] add b
621 o 1:7c3bad9141dc (public) [ ] add b
622 |
622 |
623 o 0:1f0dee641bb7 (public) [ ] add a
623 o 0:1f0dee641bb7 (public) [ ] add a
624
624
625 $ hg up -q 'desc(n3w_3_c)'
625 $ hg up -q 'desc(n3w_3_c)'
626 $ mkcommit obsolete_e
626 $ mkcommit obsolete_e
627 created new head
627 created new head
628 $ hg debugobsolete `getid 'original_e'` `getid 'obsolete_e'` \
628 $ hg debugobsolete `getid 'original_e'` `getid 'obsolete_e'` \
629 > -u 'test <test@example.net>'
629 > -u 'test <test@example.net>'
630 obsoleted 1 changesets
630 obsoleted 1 changesets
631 $ hg outgoing ../tmpf # parasite hg outgoing testin
631 $ hg outgoing ../tmpf # parasite hg outgoing testin
632 comparing with ../tmpf
632 comparing with ../tmpf
633 searching for changes
633 searching for changes
634 6:3de5eca88c00 (draft) [tip ] add obsolete_e
634 6:3de5eca88c00 (draft) [tip ] add obsolete_e
635 $ hg push ../tmpf
635 $ hg push ../tmpf
636 pushing to ../tmpf
636 pushing to ../tmpf
637 searching for changes
637 searching for changes
638 adding changesets
638 adding changesets
639 adding manifests
639 adding manifests
640 adding file changes
640 adding file changes
641 added 1 changesets with 1 changes to 1 files (+1 heads)
641 added 1 changesets with 1 changes to 1 files (+1 heads)
642 1 new obsolescence markers
642 1 new obsolescence markers
643 obsoleted 1 changesets
643 obsoleted 1 changesets
644
644
645 test relevance computation
645 test relevance computation
646 ---------------------------------------
646 ---------------------------------------
647
647
648 Checking simple case of "marker relevance".
648 Checking simple case of "marker relevance".
649
649
650
650
651 Reminder of the repo situation
651 Reminder of the repo situation
652
652
653 $ hg log --hidden --graph
653 $ hg log --hidden --graph
654 @ 6:3de5eca88c00 (draft) [tip ] add obsolete_e
654 @ 6:3de5eca88c00 (draft) [tip ] add obsolete_e
655 |
655 |
656 | x 5:cda648ca50f5 (draft *obsolete*) [ ] add original_e [rewritten as 6:3de5eca88c00 by test <test@example.net>]
656 | x 5:cda648ca50f5 (draft *obsolete*) [ ] add original_e [rewritten as 6:3de5eca88c00 by test <test@example.net>]
657 | |
657 | |
658 | x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
658 | x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
659 |/
659 |/
660 o 3:6f9641995072 (draft) [ ] add n3w_3_c
660 o 3:6f9641995072 (draft) [ ] add n3w_3_c
661 |
661 |
662 | o 2:245bde4270cd (public) [ ] add original_c
662 | o 2:245bde4270cd (public) [ ] add original_c
663 |/
663 |/
664 o 1:7c3bad9141dc (public) [ ] add b
664 o 1:7c3bad9141dc (public) [ ] add b
665 |
665 |
666 o 0:1f0dee641bb7 (public) [ ] add a
666 o 0:1f0dee641bb7 (public) [ ] add a
667
667
668
668
669 List of all markers
669 List of all markers
670
670
671 $ hg debugobsolete
671 $ hg debugobsolete
672 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
672 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
673 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
673 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
674 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
674 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
675 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
675 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
676 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
676 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
677 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
677 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
678 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
678 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
679 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
679 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
680
680
681 List of changesets with no chain
681 List of changesets with no chain
682
682
683 $ hg debugobsolete --hidden --rev ::2
683 $ hg debugobsolete --hidden --rev ::2
684
684
685 List of changesets that are included on marker chain
685 List of changesets that are included on marker chain
686
686
687 $ hg debugobsolete --hidden --rev 6
687 $ hg debugobsolete --hidden --rev 6
688 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
688 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
689
689
690 List of changesets with a longer chain, (including a pruned children)
690 List of changesets with a longer chain, (including a pruned children)
691
691
692 $ hg debugobsolete --hidden --rev 3
692 $ hg debugobsolete --hidden --rev 3
693 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
693 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
694 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
694 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
695 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
695 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
696 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
696 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
697 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
697 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
698 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
698 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
699 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
699 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
700
700
701 List of both
701 List of both
702
702
703 $ hg debugobsolete --hidden --rev 3::6
703 $ hg debugobsolete --hidden --rev 3::6
704 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
704 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
705 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
705 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
706 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
706 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
707 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
707 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
708 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
708 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
709 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
709 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
710 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
710 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
711 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
711 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
712
712
713 List of all markers in JSON
713 List of all markers in JSON
714
714
715 $ hg debugobsolete -Tjson
715 $ hg debugobsolete -Tjson
716 [
716 [
717 {
717 {
718 "date": [1339, 0],
718 "date": [1339, 0],
719 "flag": 0,
719 "flag": 0,
720 "metadata": {"user": "test"},
720 "metadata": {"user": "test"},
721 "prednode": "1339133913391339133913391339133913391339",
721 "prednode": "1339133913391339133913391339133913391339",
722 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
722 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
723 },
723 },
724 {
724 {
725 "date": [1339, 0],
725 "date": [1339, 0],
726 "flag": 0,
726 "flag": 0,
727 "metadata": {"user": "test"},
727 "metadata": {"user": "test"},
728 "prednode": "1337133713371337133713371337133713371337",
728 "prednode": "1337133713371337133713371337133713371337",
729 "succnodes": ["5601fb93a350734d935195fee37f4054c529ff39"]
729 "succnodes": ["5601fb93a350734d935195fee37f4054c529ff39"]
730 },
730 },
731 {
731 {
732 "date": [121, 120],
732 "date": [121, 120],
733 "flag": 12,
733 "flag": 12,
734 "metadata": {"user": "test"},
734 "metadata": {"user": "test"},
735 "prednode": "245bde4270cd1072a27757984f9cda8ba26f08ca",
735 "prednode": "245bde4270cd1072a27757984f9cda8ba26f08ca",
736 "succnodes": ["cdbce2fbb16313928851e97e0d85413f3f7eb77f"]
736 "succnodes": ["cdbce2fbb16313928851e97e0d85413f3f7eb77f"]
737 },
737 },
738 {
738 {
739 "date": [1338, 0],
739 "date": [1338, 0],
740 "flag": 1,
740 "flag": 1,
741 "metadata": {"user": "test"},
741 "metadata": {"user": "test"},
742 "prednode": "5601fb93a350734d935195fee37f4054c529ff39",
742 "prednode": "5601fb93a350734d935195fee37f4054c529ff39",
743 "succnodes": ["6f96419950729f3671185b847352890f074f7557"]
743 "succnodes": ["6f96419950729f3671185b847352890f074f7557"]
744 },
744 },
745 {
745 {
746 "date": [1338, 0],
746 "date": [1338, 0],
747 "flag": 0,
747 "flag": 0,
748 "metadata": {"user": "test"},
748 "metadata": {"user": "test"},
749 "prednode": "ca819180edb99ed25ceafb3e9584ac287e240b00",
749 "prednode": "ca819180edb99ed25ceafb3e9584ac287e240b00",
750 "succnodes": ["1337133713371337133713371337133713371337"]
750 "succnodes": ["1337133713371337133713371337133713371337"]
751 },
751 },
752 {
752 {
753 "date": [1337, 0],
753 "date": [1337, 0],
754 "flag": 0,
754 "flag": 0,
755 "metadata": {"user": "test"},
755 "metadata": {"user": "test"},
756 "prednode": "cdbce2fbb16313928851e97e0d85413f3f7eb77f",
756 "prednode": "cdbce2fbb16313928851e97e0d85413f3f7eb77f",
757 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
757 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
758 },
758 },
759 {
759 {
760 "date": [0, 0],
760 "date": [0, 0],
761 "flag": 0,
761 "flag": 0,
762 "metadata": {"user": "test"},
762 "metadata": {"user": "test"},
763 "parentnodes": ["6f96419950729f3671185b847352890f074f7557"],
763 "parentnodes": ["6f96419950729f3671185b847352890f074f7557"],
764 "prednode": "94b33453f93bdb8d457ef9b770851a618bf413e1",
764 "prednode": "94b33453f93bdb8d457ef9b770851a618bf413e1",
765 "succnodes": []
765 "succnodes": []
766 },
766 },
767 {
767 {
768 "date": *, (glob)
768 "date": *, (glob)
769 "flag": 0,
769 "flag": 0,
770 "metadata": {"user": "test <test@example.net>"},
770 "metadata": {"user": "test <test@example.net>"},
771 "prednode": "cda648ca50f50482b7055c0b0c4c117bba6733d9",
771 "prednode": "cda648ca50f50482b7055c0b0c4c117bba6733d9",
772 "succnodes": ["3de5eca88c00aa039da7399a220f4a5221faa585"]
772 "succnodes": ["3de5eca88c00aa039da7399a220f4a5221faa585"]
773 }
773 }
774 ]
774 ]
775
775
776 Template keywords
776 Template keywords
777
777
778 $ hg debugobsolete -r6 -T '{succnodes % "{node|short}"} {date|shortdate}\n'
778 $ hg debugobsolete -r6 -T '{succnodes % "{node|short}"} {date|shortdate}\n'
779 3de5eca88c00 ????-??-?? (glob)
779 3de5eca88c00 ????-??-?? (glob)
780 $ hg debugobsolete -r6 -T '{join(metadata % "{key}={value}", " ")}\n'
780 $ hg debugobsolete -r6 -T '{join(metadata % "{key}={value}", " ")}\n'
781 user=test <test@example.net>
781 user=test <test@example.net>
782 $ hg debugobsolete -r6 -T '{metadata}\n{metadata}\n'
782 $ hg debugobsolete -r6 -T '{metadata}\n{metadata}\n'
783 'user': 'test <test@example.net>'
783 'user': 'test <test@example.net>'
784 'user': 'test <test@example.net>'
784 'user': 'test <test@example.net>'
785 $ hg debugobsolete -r6 -T '{succnodes}\n{succnodes}\n'
785 $ hg debugobsolete -r6 -T '{succnodes}\n{succnodes}\n'
786 3de5eca88c00aa039da7399a220f4a5221faa585
786 3de5eca88c00aa039da7399a220f4a5221faa585
787 3de5eca88c00aa039da7399a220f4a5221faa585
787 3de5eca88c00aa039da7399a220f4a5221faa585
788 $ hg debugobsolete -r6 -T '{flag} {get(metadata, "user")}\n'
788 $ hg debugobsolete -r6 -T '{flag} {get(metadata, "user")}\n'
789 0 test <test@example.net>
789 0 test <test@example.net>
790
790
791 Test the debug output for exchange
791 Test the debug output for exchange
792 ----------------------------------
792 ----------------------------------
793
793
794 $ hg pull ../tmpb --config 'experimental.obsmarkers-exchange-debug=True' # bundle2
794 $ hg pull ../tmpb --config 'experimental.obsmarkers-exchange-debug=True' # bundle2
795 pulling from ../tmpb
795 pulling from ../tmpb
796 searching for changes
796 searching for changes
797 no changes found
797 no changes found
798 obsmarker-exchange: 346 bytes received
798 obsmarker-exchange: 346 bytes received
799
799
800 check hgweb does not explode
800 check hgweb does not explode
801 ====================================
801 ====================================
802
802
803 $ hg unbundle $TESTDIR/bundles/hgweb+obs.hg
803 $ hg unbundle $TESTDIR/bundles/hgweb+obs.hg
804 adding changesets
804 adding changesets
805 adding manifests
805 adding manifests
806 adding file changes
806 adding file changes
807 added 62 changesets with 63 changes to 9 files (+60 heads)
807 added 62 changesets with 63 changes to 9 files (+60 heads)
808 new changesets 50c51b361e60:c15e9edfca13 (62 drafts)
808 new changesets 50c51b361e60:c15e9edfca13 (62 drafts)
809 (2 other changesets obsolete on arrival)
809 (2 other changesets obsolete on arrival)
810 (run 'hg heads .' to see heads, 'hg merge' to merge)
810 (run 'hg heads .' to see heads, 'hg merge' to merge)
811 $ for node in `hg log -r 'desc(babar_)' --template '{node}\n'`;
811 $ for node in `hg log -r 'desc(babar_)' --template '{node}\n'`;
812 > do
812 > do
813 > hg debugobsolete $node
813 > hg debugobsolete $node
814 > done
814 > done
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 obsoleted 1 changesets
857 obsoleted 1 changesets
858 obsoleted 1 changesets
858 obsoleted 1 changesets
859 obsoleted 1 changesets
859 obsoleted 1 changesets
860 obsoleted 1 changesets
860 obsoleted 1 changesets
861 obsoleted 1 changesets
861 obsoleted 1 changesets
862 obsoleted 1 changesets
862 obsoleted 1 changesets
863 obsoleted 1 changesets
863 obsoleted 1 changesets
864 obsoleted 1 changesets
864 obsoleted 1 changesets
865 obsoleted 1 changesets
865 obsoleted 1 changesets
866 obsoleted 1 changesets
866 obsoleted 1 changesets
867 obsoleted 1 changesets
867 obsoleted 1 changesets
868 obsoleted 1 changesets
868 obsoleted 1 changesets
869 obsoleted 1 changesets
869 obsoleted 1 changesets
870 obsoleted 1 changesets
870 obsoleted 1 changesets
871 obsoleted 1 changesets
871 obsoleted 1 changesets
872 obsoleted 1 changesets
872 obsoleted 1 changesets
873 obsoleted 1 changesets
873 obsoleted 1 changesets
874 obsoleted 1 changesets
874 obsoleted 1 changesets
875 $ hg up tip
875 $ hg up tip
876 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
876 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
877
877
878 #if serve
878 #if serve
879
879
880 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
880 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
881 $ cat hg.pid >> $DAEMON_PIDS
881 $ cat hg.pid >> $DAEMON_PIDS
882
882
883 check changelog view
883 check changelog view
884
884
885 $ get-with-headers.py --headeronly localhost:$HGPORT 'shortlog/'
885 $ get-with-headers.py --headeronly localhost:$HGPORT 'shortlog/'
886 200 Script output follows
886 200 Script output follows
887
887
888 check graph view
888 check graph view
889
889
890 $ get-with-headers.py --headeronly localhost:$HGPORT 'graph'
890 $ get-with-headers.py --headeronly localhost:$HGPORT 'graph'
891 200 Script output follows
891 200 Script output follows
892
892
893 check filelog view
893 check filelog view
894
894
895 $ get-with-headers.py --headeronly localhost:$HGPORT 'log/'`hg log -r . -T "{node}"`/'babar'
895 $ get-with-headers.py --headeronly localhost:$HGPORT 'log/'`hg log -r . -T "{node}"`/'babar'
896 200 Script output follows
896 200 Script output follows
897
897
898 check filelog view for hidden commits (obsolete ones are hidden here)
898 check filelog view for hidden commits (obsolete ones are hidden here)
899
899
900 $ get-with-headers.py localhost:$HGPORT 'log/'`hg log -r . -T "{node}"`/'babar' | grep obsolete
900 $ get-with-headers.py localhost:$HGPORT 'log/'`hg log -r . -T "{node}"`/'babar' | grep obsolete
901 [1]
901 [1]
902
902
903 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/68'
903 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/68'
904 200 Script output follows
904 200 Script output follows
905 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
905 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
906 404 Not Found
906 404 Not Found
907 [1]
907 [1]
908
908
909 check that web.view config option:
909 check that web.view config option:
910
910
911 $ killdaemons.py hg.pid
911 $ killdaemons.py hg.pid
912 $ cat >> .hg/hgrc << EOF
912 $ cat >> .hg/hgrc << EOF
913 > [web]
913 > [web]
914 > view=all
914 > view=all
915 > EOF
915 > EOF
916 $ wait
916 $ wait
917 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
917 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
918 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
918 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
919 200 Script output follows
919 200 Script output follows
920 $ killdaemons.py hg.pid
920 $ killdaemons.py hg.pid
921
921
922 Checking _enable=False warning if obsolete marker exists
922 Checking _enable=False warning if obsolete marker exists
923
923
924 $ echo '[experimental]' >> $HGRCPATH
924 $ echo '[experimental]' >> $HGRCPATH
925 $ echo "evolution=" >> $HGRCPATH
925 $ echo "evolution=" >> $HGRCPATH
926 $ hg log -r tip
926 $ hg log -r tip
927 68:c15e9edfca13 (draft) [tip ] add celestine
927 68:c15e9edfca13 (draft) [tip ] add celestine
928
928
929 reenable for later test
929 reenable for later test
930
930
931 $ echo '[experimental]' >> $HGRCPATH
931 $ echo '[experimental]' >> $HGRCPATH
932 $ echo "evolution.exchange=True" >> $HGRCPATH
932 $ echo "evolution.exchange=True" >> $HGRCPATH
933 $ echo "evolution.createmarkers=True" >> $HGRCPATH
933 $ echo "evolution.createmarkers=True" >> $HGRCPATH
934
934
935 $ rm access.log errors.log
935 $ rm access.log errors.log
936 #endif
936 #endif
937
937
938 Several troubles on the same changeset (create an unstable and bumped changeset)
938 Several troubles on the same changeset (create an unstable and bumped changeset)
939
939
940 $ hg debugobsolete `getid obsolete_e`
940 $ hg debugobsolete `getid obsolete_e`
941 obsoleted 1 changesets
941 obsoleted 1 changesets
942 2 new orphan changesets
942 2 new orphan changesets
943 $ hg debugobsolete `getid original_c` `getid babar`
943 $ hg debugobsolete `getid original_c` `getid babar`
944 1 new phase-divergent changesets
944 1 new phase-divergent changesets
945 $ hg log --config ui.logtemplate= -r 'phasedivergent() and orphan()'
945 $ hg log --config ui.logtemplate= -r 'phasedivergent() and orphan()'
946 changeset: 7:50c51b361e60
946 changeset: 7:50c51b361e60
947 user: test
947 user: test
948 date: Thu Jan 01 00:00:00 1970 +0000
948 date: Thu Jan 01 00:00:00 1970 +0000
949 instability: orphan, phase-divergent
949 instability: orphan, phase-divergent
950 summary: add babar
950 summary: add babar
951
951
952
952
953 test the "obsolete" templatekw
953 test the "obsolete" templatekw
954
954
955 $ hg log -r 'obsolete()'
955 $ hg log -r 'obsolete()'
956 6:3de5eca88c00 (draft *obsolete*) [ ] add obsolete_e [pruned]
956 6:3de5eca88c00 (draft *obsolete*) [ ] add obsolete_e [pruned]
957
957
958 test the "troubles" templatekw
958 test the "troubles" templatekw
959
959
960 $ hg log -r 'phasedivergent() and orphan()'
960 $ hg log -r 'phasedivergent() and orphan()'
961 7:50c51b361e60 (draft orphan phase-divergent) [ ] add babar
961 7:50c51b361e60 (draft orphan phase-divergent) [ ] add babar
962
962
963 test the default cmdline template
963 test the default cmdline template
964
964
965 $ hg log -T default -r 'phasedivergent()'
965 $ hg log -T default -r 'phasedivergent()'
966 changeset: 7:50c51b361e60
966 changeset: 7:50c51b361e60
967 user: test
967 user: test
968 date: Thu Jan 01 00:00:00 1970 +0000
968 date: Thu Jan 01 00:00:00 1970 +0000
969 instability: orphan, phase-divergent
969 instability: orphan, phase-divergent
970 summary: add babar
970 summary: add babar
971
971
972 $ hg log -T default -r 'obsolete()'
972 $ hg log -T default -r 'obsolete()'
973 changeset: 6:3de5eca88c00
973 changeset: 6:3de5eca88c00
974 parent: 3:6f9641995072
974 parent: 3:6f9641995072
975 user: test
975 user: test
976 date: Thu Jan 01 00:00:00 1970 +0000
976 date: Thu Jan 01 00:00:00 1970 +0000
977 obsolete: pruned
977 obsolete: pruned
978 summary: add obsolete_e
978 summary: add obsolete_e
979
979
980
980
981 test the obsolete labels
981 test the obsolete labels
982
982
983 $ hg log --config ui.logtemplate= --color=debug -r 'phasedivergent()'
983 $ hg log --config ui.logtemplate= --color=debug -r 'phasedivergent()'
984 [log.changeset changeset.draft changeset.unstable instability.orphan instability.phase-divergent|changeset: 7:50c51b361e60]
984 [log.changeset changeset.draft changeset.unstable instability.orphan instability.phase-divergent|changeset: 7:50c51b361e60]
985 [log.user|user: test]
985 [log.user|user: test]
986 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
986 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
987 [log.instability|instability: orphan, phase-divergent]
987 [log.instability|instability: orphan, phase-divergent]
988 [log.summary|summary: add babar]
988 [log.summary|summary: add babar]
989
989
990
990
991 $ hg log -T default -r 'phasedivergent()' --color=debug
991 $ hg log -T default -r 'phasedivergent()' --color=debug
992 [log.changeset changeset.draft changeset.unstable instability.orphan instability.phase-divergent|changeset: 7:50c51b361e60]
992 [log.changeset changeset.draft changeset.unstable instability.orphan instability.phase-divergent|changeset: 7:50c51b361e60]
993 [log.user|user: test]
993 [log.user|user: test]
994 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
994 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
995 [log.instability|instability: orphan, phase-divergent]
995 [log.instability|instability: orphan, phase-divergent]
996 [log.summary|summary: add babar]
996 [log.summary|summary: add babar]
997
997
998
998
999 $ hg log --config ui.logtemplate= --color=debug -r "obsolete()"
999 $ hg log --config ui.logtemplate= --color=debug -r "obsolete()"
1000 [log.changeset changeset.draft changeset.obsolete|changeset: 6:3de5eca88c00]
1000 [log.changeset changeset.draft changeset.obsolete|changeset: 6:3de5eca88c00]
1001 [log.parent changeset.draft|parent: 3:6f9641995072]
1001 [log.parent changeset.draft|parent: 3:6f9641995072]
1002 [log.user|user: test]
1002 [log.user|user: test]
1003 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1003 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1004 [log.obsfate|obsolete: pruned]
1004 [log.obsfate|obsolete: pruned]
1005 [log.summary|summary: add obsolete_e]
1005 [log.summary|summary: add obsolete_e]
1006
1006
1007
1007
1008 $ hg log -T default -r 'obsolete()' --color=debug
1008 $ hg log -T default -r 'obsolete()' --color=debug
1009 [log.changeset changeset.draft changeset.obsolete|changeset: 6:3de5eca88c00]
1009 [log.changeset changeset.draft changeset.obsolete|changeset: 6:3de5eca88c00]
1010 [log.parent changeset.draft|parent: 3:6f9641995072]
1010 [log.parent changeset.draft|parent: 3:6f9641995072]
1011 [log.user|user: test]
1011 [log.user|user: test]
1012 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1012 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1013 [log.obsfate|obsolete: pruned]
1013 [log.obsfate|obsolete: pruned]
1014 [log.summary|summary: add obsolete_e]
1014 [log.summary|summary: add obsolete_e]
1015
1015
1016
1016
1017 test summary output
1017 test summary output
1018
1018
1019 $ hg up -r 'phasedivergent() and orphan()'
1019 $ hg up -r 'phasedivergent() and orphan()'
1020 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1020 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1021 $ hg summary
1021 $ hg summary
1022 parent: 7:50c51b361e60 (orphan, phase-divergent)
1022 parent: 7:50c51b361e60 (orphan, phase-divergent)
1023 add babar
1023 add babar
1024 branch: default
1024 branch: default
1025 commit: (clean)
1025 commit: (clean)
1026 update: 2 new changesets (update)
1026 update: 2 new changesets (update)
1027 phases: 4 draft
1027 phases: 4 draft
1028 orphan: 2 changesets
1028 orphan: 2 changesets
1029 phase-divergent: 1 changesets
1029 phase-divergent: 1 changesets
1030 $ hg up -r 'obsolete()'
1030 $ hg up -r 'obsolete()'
1031 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1031 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1032 $ hg summary
1032 $ hg summary
1033 parent: 6:3de5eca88c00 (obsolete)
1033 parent: 6:3de5eca88c00 (obsolete)
1034 add obsolete_e
1034 add obsolete_e
1035 branch: default
1035 branch: default
1036 commit: (clean)
1036 commit: (clean)
1037 update: 3 new changesets (update)
1037 update: 3 new changesets (update)
1038 phases: 4 draft
1038 phases: 4 draft
1039 orphan: 2 changesets
1039 orphan: 2 changesets
1040 phase-divergent: 1 changesets
1040 phase-divergent: 1 changesets
1041
1041
1042 test debugwhyunstable output
1042 test debugwhyunstable output
1043
1043
1044 $ hg debugwhyunstable 50c51b361e60
1044 $ hg debugwhyunstable 50c51b361e60
1045 orphan: obsolete parent 3de5eca88c00aa039da7399a220f4a5221faa585
1045 orphan: obsolete parent 3de5eca88c00aa039da7399a220f4a5221faa585
1046 phase-divergent: immutable predecessor 245bde4270cd1072a27757984f9cda8ba26f08ca
1046 phase-divergent: immutable predecessor 245bde4270cd1072a27757984f9cda8ba26f08ca
1047
1047
1048 test whyunstable template keyword
1048 test whyunstable template keyword
1049
1049
1050 $ hg log -r 50c51b361e60 -T '{whyunstable}\n'
1050 $ hg log -r 50c51b361e60 -T '{whyunstable}\n'
1051 orphan: obsolete parent 3de5eca88c00
1051 orphan: obsolete parent 3de5eca88c00
1052 phase-divergent: immutable predecessor 245bde4270cd
1052 phase-divergent: immutable predecessor 245bde4270cd
1053 $ hg log -r 50c51b361e60 -T '{whyunstable % "{instability}: {reason} {node|shortest}\n"}'
1053 $ hg log -r 50c51b361e60 -T '{whyunstable % "{instability}: {reason} {node|shortest}\n"}'
1054 orphan: obsolete parent 3de5
1054 orphan: obsolete parent 3de5
1055 phase-divergent: immutable predecessor 245b
1055 phase-divergent: immutable predecessor 245b
1056
1056
1057 #if serve
1057 #if serve
1058
1058
1059 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1059 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1060 $ cat hg.pid >> $DAEMON_PIDS
1060 $ cat hg.pid >> $DAEMON_PIDS
1061
1061
1062 check obsolete changeset
1062 check obsolete changeset
1063
1063
1064 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=paper' | grep '<span class="obsolete">'
1064 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=paper' | grep '<span class="obsolete">'
1065 <span class="phase">draft</span> <span class="obsolete">obsolete</span>
1065 <span class="phase">draft</span> <span class="obsolete">obsolete</span>
1066 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=coal' | grep '<span class="obsolete">'
1066 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=coal' | grep '<span class="obsolete">'
1067 <span class="phase">draft</span> <span class="obsolete">obsolete</span>
1067 <span class="phase">draft</span> <span class="obsolete">obsolete</span>
1068 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=gitweb' | grep '<span class="logtags">'
1068 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=gitweb' | grep '<span class="logtags">'
1069 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="obsoletetag" title="obsolete">obsolete</span> </span>
1069 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="obsoletetag" title="obsolete">obsolete</span> </span>
1070 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=monoblue' | grep '<span class="logtags">'
1070 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=monoblue' | grep '<span class="logtags">'
1071 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="obsoletetag" title="obsolete">obsolete</span> </span>
1071 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="obsoletetag" title="obsolete">obsolete</span> </span>
1072 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=spartan' | grep 'class="obsolete"'
1072 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=spartan' | grep 'class="obsolete"'
1073 <th class="obsolete">obsolete:</th>
1073 <th class="obsolete">obsolete:</th>
1074 <td class="obsolete">pruned by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
1074 <td class="obsolete">pruned by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
1075
1075
1076 check changeset with instabilities
1076 check changeset with instabilities
1077
1077
1078 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=paper' | grep '<span class="instability">'
1078 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=paper' | grep '<span class="instability">'
1079 <span class="phase">draft</span> <span class="instability">orphan</span> <span class="instability">phase-divergent</span>
1079 <span class="phase">draft</span> <span class="instability">orphan</span> <span class="instability">phase-divergent</span>
1080 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=coal' | grep '<span class="instability">'
1080 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=coal' | grep '<span class="instability">'
1081 <span class="phase">draft</span> <span class="instability">orphan</span> <span class="instability">phase-divergent</span>
1081 <span class="phase">draft</span> <span class="instability">orphan</span> <span class="instability">phase-divergent</span>
1082 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=gitweb' | grep '<span class="logtags">'
1082 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=gitweb' | grep '<span class="logtags">'
1083 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="instabilitytag" title="orphan">orphan</span> <span class="instabilitytag" title="phase-divergent">phase-divergent</span> </span>
1083 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="instabilitytag" title="orphan">orphan</span> <span class="instabilitytag" title="phase-divergent">phase-divergent</span> </span>
1084 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=monoblue' | grep '<span class="logtags">'
1084 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=monoblue' | grep '<span class="logtags">'
1085 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="instabilitytag" title="orphan">orphan</span> <span class="instabilitytag" title="phase-divergent">phase-divergent</span> </span>
1085 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="instabilitytag" title="orphan">orphan</span> <span class="instabilitytag" title="phase-divergent">phase-divergent</span> </span>
1086 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=spartan' | grep 'class="unstable"'
1086 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=spartan' | grep 'class="unstable"'
1087 <th class="unstable">unstable:</th>
1087 <th class="unstable">unstable:</th>
1088 <td class="unstable">orphan: obsolete parent <a href="/rev/3de5eca88c00?style=spartan">3de5eca88c00</a></td>
1088 <td class="unstable">orphan: obsolete parent <a href="/rev/3de5eca88c00?style=spartan">3de5eca88c00</a></td>
1089 <th class="unstable">unstable:</th>
1089 <th class="unstable">unstable:</th>
1090 <td class="unstable">phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=spartan">245bde4270cd</a></td>
1090 <td class="unstable">phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=spartan">245bde4270cd</a></td>
1091
1091
1092 check explanation for an orphan and phase-divergent changeset
1092 check explanation for an orphan and phase-divergent changeset
1093
1093
1094 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=paper' | egrep '(orphan|phase-divergent):'
1094 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=paper' | egrep '(orphan|phase-divergent):'
1095 <td>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=paper">3de5eca88c00</a><br>
1095 <td>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=paper">3de5eca88c00</a><br>
1096 phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=paper">245bde4270cd</a></td>
1096 phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=paper">245bde4270cd</a></td>
1097 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=coal' | egrep '(orphan|phase-divergent):'
1097 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=coal' | egrep '(orphan|phase-divergent):'
1098 <td>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=coal">3de5eca88c00</a><br>
1098 <td>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=coal">3de5eca88c00</a><br>
1099 phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=coal">245bde4270cd</a></td>
1099 phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=coal">245bde4270cd</a></td>
1100 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=gitweb' | egrep '(orphan|phase-divergent):'
1100 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=gitweb' | egrep '(orphan|phase-divergent):'
1101 <td>orphan: obsolete parent <a class="list" href="/rev/3de5eca88c00?style=gitweb">3de5eca88c00</a></td>
1101 <td>orphan: obsolete parent <a class="list" href="/rev/3de5eca88c00?style=gitweb">3de5eca88c00</a></td>
1102 <td>phase-divergent: immutable predecessor <a class="list" href="/rev/245bde4270cd?style=gitweb">245bde4270cd</a></td>
1102 <td>phase-divergent: immutable predecessor <a class="list" href="/rev/245bde4270cd?style=gitweb">245bde4270cd</a></td>
1103 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=monoblue' | egrep '(orphan|phase-divergent):'
1103 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=monoblue' | egrep '(orphan|phase-divergent):'
1104 <dd>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=monoblue">3de5eca88c00</a></dd>
1104 <dd>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=monoblue">3de5eca88c00</a></dd>
1105 <dd>phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=monoblue">245bde4270cd</a></dd>
1105 <dd>phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=monoblue">245bde4270cd</a></dd>
1106 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=spartan' | egrep '(orphan|phase-divergent):'
1106 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=spartan' | egrep '(orphan|phase-divergent):'
1107 <td class="unstable">orphan: obsolete parent <a href="/rev/3de5eca88c00?style=spartan">3de5eca88c00</a></td>
1107 <td class="unstable">orphan: obsolete parent <a href="/rev/3de5eca88c00?style=spartan">3de5eca88c00</a></td>
1108 <td class="unstable">phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=spartan">245bde4270cd</a></td>
1108 <td class="unstable">phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=spartan">245bde4270cd</a></td>
1109
1109
1110 $ killdaemons.py
1110 $ killdaemons.py
1111
1111
1112 $ rm hg.pid access.log errors.log
1112 $ rm hg.pid access.log errors.log
1113
1113
1114 #endif
1114 #endif
1115
1115
1116 Test incoming/outcoming with changesets obsoleted remotely, known locally
1116 Test incoming/outcoming with changesets obsoleted remotely, known locally
1117 ===============================================================================
1117 ===============================================================================
1118
1118
1119 This test issue 3805
1119 This test issue 3805
1120
1120
1121 $ hg init repo-issue3805
1121 $ hg init repo-issue3805
1122 $ cd repo-issue3805
1122 $ cd repo-issue3805
1123 $ echo "base" > base
1123 $ echo "base" > base
1124 $ hg ci -Am "base"
1124 $ hg ci -Am "base"
1125 adding base
1125 adding base
1126 $ echo "foo" > foo
1126 $ echo "foo" > foo
1127 $ hg ci -Am "A"
1127 $ hg ci -Am "A"
1128 adding foo
1128 adding foo
1129 $ hg clone . ../other-issue3805
1129 $ hg clone . ../other-issue3805
1130 updating to branch default
1130 updating to branch default
1131 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1131 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1132 $ echo "bar" >> foo
1132 $ echo "bar" >> foo
1133 $ hg ci --amend
1133 $ hg ci --amend
1134 $ cd ../other-issue3805
1134 $ cd ../other-issue3805
1135 $ hg log -G
1135 $ hg log -G
1136 @ 1:29f0c6921ddd (draft) [tip ] A
1136 @ 1:29f0c6921ddd (draft) [tip ] A
1137 |
1137 |
1138 o 0:d20a80d4def3 (draft) [ ] base
1138 o 0:d20a80d4def3 (draft) [ ] base
1139
1139
1140 $ hg log -G -R ../repo-issue3805
1140 $ hg log -G -R ../repo-issue3805
1141 @ 2:323a9c3ddd91 (draft) [tip ] A
1141 @ 2:323a9c3ddd91 (draft) [tip ] A
1142 |
1142 |
1143 o 0:d20a80d4def3 (draft) [ ] base
1143 o 0:d20a80d4def3 (draft) [ ] base
1144
1144
1145 $ hg incoming
1145 $ hg incoming
1146 comparing with $TESTTMP/tmpe/repo-issue3805
1146 comparing with $TESTTMP/tmpe/repo-issue3805
1147 searching for changes
1147 searching for changes
1148 2:323a9c3ddd91 (draft) [tip ] A
1148 2:323a9c3ddd91 (draft) [tip ] A
1149 $ hg incoming --bundle ../issue3805.hg
1149 $ hg incoming --bundle ../issue3805.hg
1150 comparing with $TESTTMP/tmpe/repo-issue3805
1150 comparing with $TESTTMP/tmpe/repo-issue3805
1151 searching for changes
1151 searching for changes
1152 2:323a9c3ddd91 (draft) [tip ] A
1152 2:323a9c3ddd91 (draft) [tip ] A
1153 $ hg outgoing
1153 $ hg outgoing
1154 comparing with $TESTTMP/tmpe/repo-issue3805
1154 comparing with $TESTTMP/tmpe/repo-issue3805
1155 searching for changes
1155 searching for changes
1156 1:29f0c6921ddd (draft) [tip ] A
1156 1:29f0c6921ddd (draft) [tip ] A
1157
1157
1158 #if serve
1158 #if serve
1159
1159
1160 $ hg serve -R ../repo-issue3805 -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1160 $ hg serve -R ../repo-issue3805 -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1161 $ cat hg.pid >> $DAEMON_PIDS
1161 $ cat hg.pid >> $DAEMON_PIDS
1162
1162
1163 $ hg incoming http://localhost:$HGPORT
1163 $ hg incoming http://localhost:$HGPORT
1164 comparing with http://localhost:$HGPORT/
1164 comparing with http://localhost:$HGPORT/
1165 searching for changes
1165 searching for changes
1166 2:323a9c3ddd91 (draft) [tip ] A
1166 2:323a9c3ddd91 (draft) [tip ] A
1167 $ hg outgoing http://localhost:$HGPORT
1167 $ hg outgoing http://localhost:$HGPORT
1168 comparing with http://localhost:$HGPORT/
1168 comparing with http://localhost:$HGPORT/
1169 searching for changes
1169 searching for changes
1170 1:29f0c6921ddd (draft) [tip ] A
1170 1:29f0c6921ddd (draft) [tip ] A
1171
1171
1172 $ killdaemons.py
1172 $ killdaemons.py
1173
1173
1174 #endif
1174 #endif
1175
1175
1176 This test issue 3814
1176 This test issue 3814
1177
1177
1178 (nothing to push but locally hidden changeset)
1178 (nothing to push but locally hidden changeset)
1179
1179
1180 $ cd ..
1180 $ cd ..
1181 $ hg init repo-issue3814
1181 $ hg init repo-issue3814
1182 $ cd repo-issue3805
1182 $ cd repo-issue3805
1183 $ hg push -r 323a9c3ddd91 ../repo-issue3814
1183 $ hg push -r 323a9c3ddd91 ../repo-issue3814
1184 pushing to ../repo-issue3814
1184 pushing to ../repo-issue3814
1185 searching for changes
1185 searching for changes
1186 adding changesets
1186 adding changesets
1187 adding manifests
1187 adding manifests
1188 adding file changes
1188 adding file changes
1189 added 2 changesets with 2 changes to 2 files
1189 added 2 changesets with 2 changes to 2 files
1190 1 new obsolescence markers
1190 1 new obsolescence markers
1191 $ hg out ../repo-issue3814
1191 $ hg out ../repo-issue3814
1192 comparing with ../repo-issue3814
1192 comparing with ../repo-issue3814
1193 searching for changes
1193 searching for changes
1194 no changes found
1194 no changes found
1195 [1]
1195 [1]
1196
1196
1197 Test that a local tag blocks a changeset from being hidden
1197 Test that a local tag blocks a changeset from being hidden
1198
1198
1199 $ hg tag -l visible -r 1 --hidden
1199 $ hg tag -l visible -r 1 --hidden
1200 $ hg log -G
1200 $ hg log -G
1201 @ 2:323a9c3ddd91 (draft) [tip ] A
1201 @ 2:323a9c3ddd91 (draft) [tip ] A
1202 |
1202 |
1203 | x 1:29f0c6921ddd (draft *obsolete*) [visible ] A [rewritten using amend as 2:323a9c3ddd91]
1203 | x 1:29f0c6921ddd (draft *obsolete*) [visible ] A [rewritten using amend as 2:323a9c3ddd91]
1204 |/
1204 |/
1205 o 0:d20a80d4def3 (draft) [ ] base
1205 o 0:d20a80d4def3 (draft) [ ] base
1206
1206
1207 Test that removing a local tag does not cause some commands to fail
1207 Test that removing a local tag does not cause some commands to fail
1208
1208
1209 $ hg tag -l -r tip tiptag
1209 $ hg tag -l -r tip tiptag
1210 $ hg tags
1210 $ hg tags
1211 tiptag 2:323a9c3ddd91
1211 tiptag 2:323a9c3ddd91
1212 tip 2:323a9c3ddd91
1212 tip 2:323a9c3ddd91
1213 visible 1:29f0c6921ddd
1213 visible 1:29f0c6921ddd
1214 $ hg --config extensions.strip= strip -r tip --no-backup
1214 $ hg --config extensions.strip= strip -r tip --no-backup
1215 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1215 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1216 $ hg tags
1216 $ hg tags
1217 visible 1:29f0c6921ddd
1217 visible 1:29f0c6921ddd
1218 tip 1:29f0c6921ddd
1218 tip 1:29f0c6921ddd
1219
1219
1220 Test bundle overlay onto hidden revision
1220 Test bundle overlay onto hidden revision
1221
1221
1222 $ cd ..
1222 $ cd ..
1223 $ hg init repo-bundleoverlay
1223 $ hg init repo-bundleoverlay
1224 $ cd repo-bundleoverlay
1224 $ cd repo-bundleoverlay
1225 $ echo "A" > foo
1225 $ echo "A" > foo
1226 $ hg ci -Am "A"
1226 $ hg ci -Am "A"
1227 adding foo
1227 adding foo
1228 $ echo "B" >> foo
1228 $ echo "B" >> foo
1229 $ hg ci -m "B"
1229 $ hg ci -m "B"
1230 $ hg up 0
1230 $ hg up 0
1231 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1231 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1232 $ echo "C" >> foo
1232 $ echo "C" >> foo
1233 $ hg ci -m "C"
1233 $ hg ci -m "C"
1234 created new head
1234 created new head
1235 $ hg log -G
1235 $ hg log -G
1236 @ 2:c186d7714947 (draft) [tip ] C
1236 @ 2:c186d7714947 (draft) [tip ] C
1237 |
1237 |
1238 | o 1:44526ebb0f98 (draft) [ ] B
1238 | o 1:44526ebb0f98 (draft) [ ] B
1239 |/
1239 |/
1240 o 0:4b34ecfb0d56 (draft) [ ] A
1240 o 0:4b34ecfb0d56 (draft) [ ] A
1241
1241
1242
1242
1243 $ hg clone -r1 . ../other-bundleoverlay
1243 $ hg clone -r1 . ../other-bundleoverlay
1244 adding changesets
1244 adding changesets
1245 adding manifests
1245 adding manifests
1246 adding file changes
1246 adding file changes
1247 added 2 changesets with 2 changes to 1 files
1247 added 2 changesets with 2 changes to 1 files
1248 new changesets 4b34ecfb0d56:44526ebb0f98 (2 drafts)
1248 new changesets 4b34ecfb0d56:44526ebb0f98 (2 drafts)
1249 updating to branch default
1249 updating to branch default
1250 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1250 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1251 $ cd ../other-bundleoverlay
1251 $ cd ../other-bundleoverlay
1252 $ echo "B+" >> foo
1252 $ echo "B+" >> foo
1253 $ hg ci --amend -m "B+"
1253 $ hg ci --amend -m "B+"
1254 $ hg log -G --hidden
1254 $ hg log -G --hidden
1255 @ 2:b7d587542d40 (draft) [tip ] B+
1255 @ 2:b7d587542d40 (draft) [tip ] B+
1256 |
1256 |
1257 | x 1:44526ebb0f98 (draft *obsolete*) [ ] B [rewritten using amend as 2:b7d587542d40]
1257 | x 1:44526ebb0f98 (draft *obsolete*) [ ] B [rewritten using amend as 2:b7d587542d40]
1258 |/
1258 |/
1259 o 0:4b34ecfb0d56 (draft) [ ] A
1259 o 0:4b34ecfb0d56 (draft) [ ] A
1260
1260
1261
1261
1262 #if repobundlerepo
1262 #if repobundlerepo
1263 $ hg incoming ../repo-bundleoverlay --bundle ../bundleoverlay.hg
1263 $ hg incoming ../repo-bundleoverlay --bundle ../bundleoverlay.hg
1264 comparing with ../repo-bundleoverlay
1264 comparing with ../repo-bundleoverlay
1265 searching for changes
1265 searching for changes
1266 1:44526ebb0f98 (draft) [ ] B
1266 1:44526ebb0f98 (draft) [ ] B
1267 2:c186d7714947 (draft) [tip ] C
1267 2:c186d7714947 (draft) [tip ] C
1268 $ hg log -G -R ../bundleoverlay.hg
1268 $ hg log -G -R ../bundleoverlay.hg
1269 o 3:c186d7714947 (draft) [tip ] C
1269 o 3:c186d7714947 (draft) [tip ] C
1270 |
1270 |
1271 | @ 2:b7d587542d40 (draft) [ ] B+
1271 | @ 2:b7d587542d40 (draft) [ ] B+
1272 |/
1272 |/
1273 o 0:4b34ecfb0d56 (draft) [ ] A
1273 o 0:4b34ecfb0d56 (draft) [ ] A
1274
1274
1275 #endif
1275 #endif
1276
1276
1277 #if serve
1277 #if serve
1278
1278
1279 Test issue 4506
1279 Test issue 4506
1280
1280
1281 $ cd ..
1281 $ cd ..
1282 $ hg init repo-issue4506
1282 $ hg init repo-issue4506
1283 $ cd repo-issue4506
1283 $ cd repo-issue4506
1284 $ echo "0" > foo
1284 $ echo "0" > foo
1285 $ hg add foo
1285 $ hg add foo
1286 $ hg ci -m "content-0"
1286 $ hg ci -m "content-0"
1287
1287
1288 $ hg up null
1288 $ hg up null
1289 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1289 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1290 $ echo "1" > bar
1290 $ echo "1" > bar
1291 $ hg add bar
1291 $ hg add bar
1292 $ hg ci -m "content-1"
1292 $ hg ci -m "content-1"
1293 created new head
1293 created new head
1294 $ hg up 0
1294 $ hg up 0
1295 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1295 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1296 $ hg graft 1
1296 $ hg graft 1
1297 grafting 1:1c9eddb02162 "content-1" (tip)
1297 grafting 1:1c9eddb02162 "content-1" (tip)
1298
1298
1299 $ hg debugobsolete `hg log -r1 -T'{node}'` `hg log -r2 -T'{node}'`
1299 $ hg debugobsolete `hg log -r1 -T'{node}'` `hg log -r2 -T'{node}'`
1300 obsoleted 1 changesets
1300 obsoleted 1 changesets
1301
1301
1302 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1302 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1303 $ cat hg.pid >> $DAEMON_PIDS
1303 $ cat hg.pid >> $DAEMON_PIDS
1304
1304
1305 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/1'
1305 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/1'
1306 404 Not Found
1306 404 Not Found
1307 [1]
1307 [1]
1308 $ get-with-headers.py --headeronly localhost:$HGPORT 'file/tip/bar'
1308 $ get-with-headers.py --headeronly localhost:$HGPORT 'file/tip/bar'
1309 200 Script output follows
1309 200 Script output follows
1310 $ get-with-headers.py --headeronly localhost:$HGPORT 'annotate/tip/bar'
1310 $ get-with-headers.py --headeronly localhost:$HGPORT 'annotate/tip/bar'
1311 200 Script output follows
1311 200 Script output follows
1312
1312
1313 $ killdaemons.py
1313 $ killdaemons.py
1314
1314
1315 #endif
1315 #endif
1316
1316
1317 Test heads computation on pending index changes with obsolescence markers
1317 Test heads computation on pending index changes with obsolescence markers
1318 $ cd ..
1318 $ cd ..
1319 $ cat >$TESTTMP/test_extension.py << EOF
1319 $ cat >$TESTTMP/test_extension.py << EOF
1320 > from __future__ import absolute_import
1320 > from __future__ import absolute_import
1321 > from mercurial.i18n import _
1321 > from mercurial.i18n import _
1322 > from mercurial import cmdutil, pycompat, registrar
1322 > from mercurial import cmdutil, pycompat, registrar
1323 > from mercurial.utils import stringutil
1323 > from mercurial.utils import stringutil
1324 >
1324 >
1325 > cmdtable = {}
1325 > cmdtable = {}
1326 > command = registrar.command(cmdtable)
1326 > command = registrar.command(cmdtable)
1327 > @command(b"amendtransient",[], _(b'hg amendtransient [rev]'))
1327 > @command(b"amendtransient",[], _(b'hg amendtransient [rev]'))
1328 > def amend(ui, repo, *pats, **opts):
1328 > def amend(ui, repo, *pats, **opts):
1329 > opts = pycompat.byteskwargs(opts)
1329 > opts = pycompat.byteskwargs(opts)
1330 > opts[b'message'] = b'Test'
1330 > opts[b'message'] = b'Test'
1331 > opts[b'logfile'] = None
1331 > opts[b'logfile'] = None
1332 > cmdutil.amend(ui, repo, repo[b'.'], {}, pats, opts)
1332 > cmdutil.amend(ui, repo, repo[b'.'], {}, pats, opts)
1333 > ui.write(b'%s\n' % stringutil.pprint(repo.changelog.headrevs()))
1333 > ui.write(b'%s\n' % stringutil.pprint(repo.changelog.headrevs()))
1334 > EOF
1334 > EOF
1335 $ cat >> $HGRCPATH << EOF
1335 $ cat >> $HGRCPATH << EOF
1336 > [extensions]
1336 > [extensions]
1337 > testextension=$TESTTMP/test_extension.py
1337 > testextension=$TESTTMP/test_extension.py
1338 > EOF
1338 > EOF
1339 $ hg init repo-issue-nativerevs-pending-changes
1339 $ hg init repo-issue-nativerevs-pending-changes
1340 $ cd repo-issue-nativerevs-pending-changes
1340 $ cd repo-issue-nativerevs-pending-changes
1341 $ mkcommit a
1341 $ mkcommit a
1342 $ mkcommit b
1342 $ mkcommit b
1343 $ hg up ".^"
1343 $ hg up ".^"
1344 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1344 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1345 $ echo aa > a
1345 $ echo aa > a
1346 $ hg amendtransient
1346 $ hg amendtransient
1347 1 new orphan changesets
1347 1 new orphan changesets
1348 [1, 2]
1348 [1, 2]
1349
1349
1350 Test cache consistency for the visible filter
1350 Test cache consistency for the visible filter
1351 1) We want to make sure that the cached filtered revs are invalidated when
1351 1) We want to make sure that the cached filtered revs are invalidated when
1352 bookmarks change
1352 bookmarks change
1353 $ cd ..
1353 $ cd ..
1354 $ cat >$TESTTMP/test_extension.py << EOF
1354 $ cat >$TESTTMP/test_extension.py << EOF
1355 > from __future__ import absolute_import, print_function
1355 > from __future__ import absolute_import, print_function
1356 > import weakref
1356 > import weakref
1357 > from mercurial import (
1357 > from mercurial import (
1358 > bookmarks,
1358 > bookmarks,
1359 > cmdutil,
1359 > cmdutil,
1360 > extensions,
1360 > extensions,
1361 > repoview,
1361 > repoview,
1362 > )
1362 > )
1363 > def _bookmarkchanged(orig, bkmstoreinst, *args, **kwargs):
1363 > def _bookmarkchanged(orig, bkmstoreinst, *args, **kwargs):
1364 > reporef = weakref.ref(bkmstoreinst._repo)
1364 > reporef = weakref.ref(bkmstoreinst._repo)
1365 > def trhook(tr):
1365 > def trhook(tr):
1366 > repo = reporef()
1366 > repo = reporef()
1367 > hidden1 = repoview.computehidden(repo)
1367 > hidden1 = repoview.computehidden(repo)
1368 > hidden = repoview.filterrevs(repo, b'visible')
1368 > hidden = repoview.filterrevs(repo, b'visible')
1369 > if sorted(hidden1) != sorted(hidden):
1369 > if sorted(hidden1) != sorted(hidden):
1370 > print("cache inconsistency")
1370 > print("cache inconsistency")
1371 > bkmstoreinst._repo.currenttransaction().addpostclose(b'test_extension', trhook)
1371 > bkmstoreinst._repo.currenttransaction().addpostclose(b'test_extension', trhook)
1372 > orig(bkmstoreinst, *args, **kwargs)
1372 > orig(bkmstoreinst, *args, **kwargs)
1373 > def extsetup(ui):
1373 > def extsetup(ui):
1374 > extensions.wrapfunction(bookmarks.bmstore, '_recordchange',
1374 > extensions.wrapfunction(bookmarks.bmstore, '_recordchange',
1375 > _bookmarkchanged)
1375 > _bookmarkchanged)
1376 > EOF
1376 > EOF
1377
1377
1378 $ hg init repo-cache-inconsistency
1378 $ hg init repo-cache-inconsistency
1379 $ cd repo-issue-nativerevs-pending-changes
1379 $ cd repo-issue-nativerevs-pending-changes
1380 $ mkcommit a
1380 $ mkcommit a
1381 a already tracked!
1381 a already tracked!
1382 $ mkcommit b
1382 $ mkcommit b
1383 $ hg id
1383 $ hg id
1384 13bedc178fce tip
1384 13bedc178fce tip
1385 $ echo "hello" > b
1385 $ echo "hello" > b
1386 $ hg commit --amend -m "message"
1386 $ hg commit --amend -m "message"
1387 $ hg book bookb -r 13bedc178fce --hidden
1387 $ hg book bookb -r 13bedc178fce --hidden
1388 bookmarking hidden changeset 13bedc178fce
1388 bookmarking hidden changeset 13bedc178fce
1389 (hidden revision '13bedc178fce' was rewritten as: a9b1f8652753)
1389 (hidden revision '13bedc178fce' was rewritten as: a9b1f8652753)
1390 $ hg log -r 13bedc178fce
1390 $ hg log -r 13bedc178fce
1391 4:13bedc178fce (draft *obsolete*) [ bookb] add b [rewritten using amend as 5:a9b1f8652753]
1391 4:13bedc178fce (draft *obsolete*) [ bookb] add b [rewritten using amend as 5:a9b1f8652753]
1392 $ hg book -d bookb
1392 $ hg book -d bookb
1393 $ hg log -r 13bedc178fce
1393 $ hg log -r 13bedc178fce
1394 abort: hidden revision '13bedc178fce' was rewritten as: a9b1f8652753!
1394 abort: hidden revision '13bedc178fce' was rewritten as: a9b1f8652753!
1395 (use --hidden to access hidden revisions)
1395 (use --hidden to access hidden revisions)
1396 [255]
1396 [255]
1397
1397
1398 Empty out the test extension, as it isn't compatible with later parts
1398 Empty out the test extension, as it isn't compatible with later parts
1399 of the test.
1399 of the test.
1400 $ echo > $TESTTMP/test_extension.py
1400 $ echo > $TESTTMP/test_extension.py
1401
1401
1402 Test ability to pull changeset with locally applying obsolescence markers
1402 Test ability to pull changeset with locally applying obsolescence markers
1403 (issue4945)
1403 (issue4945)
1404
1404
1405 $ cd ..
1405 $ cd ..
1406 $ hg init issue4845
1406 $ hg init issue4845
1407 $ cd issue4845
1407 $ cd issue4845
1408
1408
1409 $ echo foo > f0
1409 $ echo foo > f0
1410 $ hg add f0
1410 $ hg add f0
1411 $ hg ci -m '0'
1411 $ hg ci -m '0'
1412 $ echo foo > f1
1412 $ echo foo > f1
1413 $ hg add f1
1413 $ hg add f1
1414 $ hg ci -m '1'
1414 $ hg ci -m '1'
1415 $ echo foo > f2
1415 $ echo foo > f2
1416 $ hg add f2
1416 $ hg add f2
1417 $ hg ci -m '2'
1417 $ hg ci -m '2'
1418
1418
1419 $ echo bar > f2
1419 $ echo bar > f2
1420 $ hg commit --amend --config experimental.evolution.createmarkers=True
1420 $ hg commit --amend --config experimental.evolution.createmarkers=True
1421 $ hg log -G
1421 $ hg log -G
1422 @ 3:b0551702f918 (draft) [tip ] 2
1422 @ 3:b0551702f918 (draft) [tip ] 2
1423 |
1423 |
1424 o 1:e016b03fd86f (draft) [ ] 1
1424 o 1:e016b03fd86f (draft) [ ] 1
1425 |
1425 |
1426 o 0:a78f55e5508c (draft) [ ] 0
1426 o 0:a78f55e5508c (draft) [ ] 0
1427
1427
1428 $ hg log -G --hidden
1428 $ hg log -G --hidden
1429 @ 3:b0551702f918 (draft) [tip ] 2
1429 @ 3:b0551702f918 (draft) [tip ] 2
1430 |
1430 |
1431 | x 2:e008cf283490 (draft *obsolete*) [ ] 2 [rewritten using amend as 3:b0551702f918]
1431 | x 2:e008cf283490 (draft *obsolete*) [ ] 2 [rewritten using amend as 3:b0551702f918]
1432 |/
1432 |/
1433 o 1:e016b03fd86f (draft) [ ] 1
1433 o 1:e016b03fd86f (draft) [ ] 1
1434 |
1434 |
1435 o 0:a78f55e5508c (draft) [ ] 0
1435 o 0:a78f55e5508c (draft) [ ] 0
1436
1436
1437
1437
1438 $ hg strip --hidden -r 2 --config extensions.strip= --config devel.strip-obsmarkers=no
1438 $ hg strip --hidden -r 2 --config extensions.strip= --config devel.strip-obsmarkers=no
1439 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e008cf283490-ede36964-backup.hg
1439 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e008cf283490-ede36964-backup.hg
1440 $ hg debugobsolete
1440 $ hg debugobsolete
1441 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1441 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1442 $ hg log -G
1442 $ hg log -G
1443 @ 2:b0551702f918 (draft) [tip ] 2
1443 @ 2:b0551702f918 (draft) [tip ] 2
1444 |
1444 |
1445 o 1:e016b03fd86f (draft) [ ] 1
1445 o 1:e016b03fd86f (draft) [ ] 1
1446 |
1446 |
1447 o 0:a78f55e5508c (draft) [ ] 0
1447 o 0:a78f55e5508c (draft) [ ] 0
1448
1448
1449 $ hg log -G --hidden
1449 $ hg log -G --hidden
1450 @ 2:b0551702f918 (draft) [tip ] 2
1450 @ 2:b0551702f918 (draft) [tip ] 2
1451 |
1451 |
1452 o 1:e016b03fd86f (draft) [ ] 1
1452 o 1:e016b03fd86f (draft) [ ] 1
1453 |
1453 |
1454 o 0:a78f55e5508c (draft) [ ] 0
1454 o 0:a78f55e5508c (draft) [ ] 0
1455
1455
1456 $ hg debugbundle .hg/strip-backup/e008cf283490-*-backup.hg
1456 $ hg debugbundle .hg/strip-backup/e008cf283490-*-backup.hg
1457 Stream params: {Compression: BZ}
1457 Stream params: {Compression: BZ}
1458 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
1458 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
1459 e008cf2834908e5d6b0f792a9d4b0e2272260fb8
1459 e008cf2834908e5d6b0f792a9d4b0e2272260fb8
1460 cache:rev-branch-cache -- {} (mandatory: False)
1460 cache:rev-branch-cache -- {} (mandatory: False)
1461 phase-heads -- {} (mandatory: True)
1461 phase-heads -- {} (mandatory: True)
1462 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 draft
1462 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 draft
1463
1463
1464 #if repobundlerepo
1464 #if repobundlerepo
1465 $ hg pull .hg/strip-backup/e008cf283490-*-backup.hg
1465 $ hg pull .hg/strip-backup/e008cf283490-*-backup.hg
1466 pulling from .hg/strip-backup/e008cf283490-ede36964-backup.hg
1466 pulling from .hg/strip-backup/e008cf283490-ede36964-backup.hg
1467 searching for changes
1467 searching for changes
1468 no changes found
1468 no changes found
1469 #endif
1469 #endif
1470 $ hg debugobsolete
1470 $ hg debugobsolete
1471 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1471 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1472 $ hg log -G
1472 $ hg log -G
1473 @ 2:b0551702f918 (draft) [tip ] 2
1473 @ 2:b0551702f918 (draft) [tip ] 2
1474 |
1474 |
1475 o 1:e016b03fd86f (draft) [ ] 1
1475 o 1:e016b03fd86f (draft) [ ] 1
1476 |
1476 |
1477 o 0:a78f55e5508c (draft) [ ] 0
1477 o 0:a78f55e5508c (draft) [ ] 0
1478
1478
1479 $ hg log -G --hidden
1479 $ hg log -G --hidden
1480 @ 2:b0551702f918 (draft) [tip ] 2
1480 @ 2:b0551702f918 (draft) [tip ] 2
1481 |
1481 |
1482 o 1:e016b03fd86f (draft) [ ] 1
1482 o 1:e016b03fd86f (draft) [ ] 1
1483 |
1483 |
1484 o 0:a78f55e5508c (draft) [ ] 0
1484 o 0:a78f55e5508c (draft) [ ] 0
1485
1485
1486
1486
1487 Testing that strip remove markers:
1487 Testing that strip remove markers:
1488
1488
1489 $ hg strip -r 1 --config extensions.strip=
1489 $ hg strip -r 1 --config extensions.strip=
1490 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1490 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1491 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e016b03fd86f-65ede734-backup.hg
1491 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e016b03fd86f-65ede734-backup.hg
1492 $ hg debugobsolete
1492 $ hg debugobsolete
1493 $ hg log -G
1493 $ hg log -G
1494 @ 0:a78f55e5508c (draft) [tip ] 0
1494 @ 0:a78f55e5508c (draft) [tip ] 0
1495
1495
1496 $ hg log -G --hidden
1496 $ hg log -G --hidden
1497 @ 0:a78f55e5508c (draft) [tip ] 0
1497 @ 0:a78f55e5508c (draft) [tip ] 0
1498
1498
1499 $ hg debugbundle .hg/strip-backup/e016b03fd86f-*-backup.hg
1499 $ hg debugbundle .hg/strip-backup/e016b03fd86f-*-backup.hg
1500 Stream params: {Compression: BZ}
1500 Stream params: {Compression: BZ}
1501 changegroup -- {nbchanges: 2, version: 02} (mandatory: True)
1501 changegroup -- {nbchanges: 2, version: 02} (mandatory: True)
1502 e016b03fd86fcccc54817d120b90b751aaf367d6
1502 e016b03fd86fcccc54817d120b90b751aaf367d6
1503 b0551702f918510f01ae838ab03a463054c67b46
1503 b0551702f918510f01ae838ab03a463054c67b46
1504 cache:rev-branch-cache -- {} (mandatory: False)
1504 cache:rev-branch-cache -- {} (mandatory: False)
1505 obsmarkers -- {} (mandatory: True)
1505 obsmarkers -- {} (mandatory: True)
1506 version: 1 (92 bytes)
1506 version: 1 (92 bytes)
1507 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1507 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1508 phase-heads -- {} (mandatory: True)
1508 phase-heads -- {} (mandatory: True)
1509 b0551702f918510f01ae838ab03a463054c67b46 draft
1509 b0551702f918510f01ae838ab03a463054c67b46 draft
1510
1510
1511 $ hg unbundle .hg/strip-backup/e016b03fd86f-*-backup.hg
1511 $ hg unbundle .hg/strip-backup/e016b03fd86f-*-backup.hg
1512 adding changesets
1512 adding changesets
1513 adding manifests
1513 adding manifests
1514 adding file changes
1514 adding file changes
1515 added 2 changesets with 2 changes to 2 files
1515 added 2 changesets with 2 changes to 2 files
1516 1 new obsolescence markers
1516 1 new obsolescence markers
1517 new changesets e016b03fd86f:b0551702f918 (2 drafts)
1517 new changesets e016b03fd86f:b0551702f918 (2 drafts)
1518 (run 'hg update' to get a working copy)
1518 (run 'hg update' to get a working copy)
1519 $ hg debugobsolete | sort
1519 $ hg debugobsolete | sort
1520 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1520 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1521 $ hg log -G
1521 $ hg log -G
1522 o 2:b0551702f918 (draft) [tip ] 2
1522 o 2:b0551702f918 (draft) [tip ] 2
1523 |
1523 |
1524 o 1:e016b03fd86f (draft) [ ] 1
1524 o 1:e016b03fd86f (draft) [ ] 1
1525 |
1525 |
1526 @ 0:a78f55e5508c (draft) [ ] 0
1526 @ 0:a78f55e5508c (draft) [ ] 0
1527
1527
1528 $ hg log -G --hidden
1528 $ hg log -G --hidden
1529 o 2:b0551702f918 (draft) [tip ] 2
1529 o 2:b0551702f918 (draft) [tip ] 2
1530 |
1530 |
1531 o 1:e016b03fd86f (draft) [ ] 1
1531 o 1:e016b03fd86f (draft) [ ] 1
1532 |
1532 |
1533 @ 0:a78f55e5508c (draft) [ ] 0
1533 @ 0:a78f55e5508c (draft) [ ] 0
1534
1534
1535 Test that 'hg debugobsolete --index --rev' can show indices of obsmarkers when
1535 Test that 'hg debugobsolete --index --rev' can show indices of obsmarkers when
1536 only a subset of those are displayed (because of --rev option)
1536 only a subset of those are displayed (because of --rev option)
1537 $ hg init doindexrev
1537 $ hg init doindexrev
1538 $ cd doindexrev
1538 $ cd doindexrev
1539 $ echo a > a
1539 $ echo a > a
1540 $ hg ci -Am a
1540 $ hg ci -Am a
1541 adding a
1541 adding a
1542 $ hg ci --amend -m aa
1542 $ hg ci --amend -m aa
1543 $ echo b > b
1543 $ echo b > b
1544 $ hg ci -Am b
1544 $ hg ci -Am b
1545 adding b
1545 adding b
1546 $ hg ci --amend -m bb
1546 $ hg ci --amend -m bb
1547 $ echo c > c
1547 $ echo c > c
1548 $ hg ci -Am c
1548 $ hg ci -Am c
1549 adding c
1549 adding c
1550 $ hg ci --amend -m cc
1550 $ hg ci --amend -m cc
1551 $ echo d > d
1551 $ echo d > d
1552 $ hg ci -Am d
1552 $ hg ci -Am d
1553 adding d
1553 adding d
1554 $ hg ci --amend -m dd --config experimental.evolution.track-operation=1
1554 $ hg ci --amend -m dd --config experimental.evolution.track-operation=1
1555 $ hg debugobsolete --index --rev "3+7"
1555 $ hg debugobsolete --index --rev "3+7"
1556 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1556 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1557 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1557 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1558 $ hg debugobsolete --index --rev "3+7" -Tjson
1558 $ hg debugobsolete --index --rev "3+7" -Tjson
1559 [
1559 [
1560 {
1560 {
1561 "date": [0, 0],
1561 "date": [0, 0],
1562 "flag": 0,
1562 "flag": 0,
1563 "index": 1,
1563 "index": 1,
1564 "metadata": {"ef1": "1", "operation": "amend", "user": "test"},
1564 "metadata": {"ef1": "1", "operation": "amend", "user": "test"},
1565 "prednode": "6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1",
1565 "prednode": "6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1",
1566 "succnodes": ["d27fb9b066076fd921277a4b9e8b9cb48c95bc6a"]
1566 "succnodes": ["d27fb9b066076fd921277a4b9e8b9cb48c95bc6a"]
1567 },
1567 },
1568 {
1568 {
1569 "date": [0, 0],
1569 "date": [0, 0],
1570 "flag": 0,
1570 "flag": 0,
1571 "index": 3,
1571 "index": 3,
1572 "metadata": {"ef1": "1", "operation": "amend", "user": "test"},
1572 "metadata": {"ef1": "1", "operation": "amend", "user": "test"},
1573 "prednode": "4715cf767440ed891755448016c2b8cf70760c30",
1573 "prednode": "4715cf767440ed891755448016c2b8cf70760c30",
1574 "succnodes": ["7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d"]
1574 "succnodes": ["7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d"]
1575 }
1575 }
1576 ]
1576 ]
1577
1577
1578 Test the --delete option of debugobsolete command
1578 Test the --delete option of debugobsolete command
1579 $ hg debugobsolete --index
1579 $ hg debugobsolete --index
1580 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1580 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1581 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1581 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1582 2 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1582 2 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1583 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1583 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1584 $ hg debugobsolete --delete 1 --delete 3
1584 $ hg debugobsolete --delete 1 --delete 3
1585 deleted 2 obsolescence markers
1585 deleted 2 obsolescence markers
1586 $ hg debugobsolete
1586 $ hg debugobsolete
1587 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1587 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1588 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1588 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1589
1589
1590 Test adding changeset after obsmarkers affecting it
1590 Test adding changeset after obsmarkers affecting it
1591 (eg: during pull, or unbundle)
1591 (eg: during pull, or unbundle)
1592
1592
1593 $ mkcommit e
1593 $ mkcommit e
1594 $ hg bundle -r . --base .~1 ../bundle-2.hg
1594 $ hg bundle -r . --base .~1 ../bundle-2.hg
1595 1 changesets found
1595 1 changesets found
1596 $ getid .
1596 $ getid .
1597 $ hg --config extensions.strip= strip -r .
1597 $ hg --config extensions.strip= strip -r .
1598 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1598 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1599 saved backup bundle to $TESTTMP/tmpe/issue4845/doindexrev/.hg/strip-backup/9bc153528424-ee80edd4-backup.hg
1599 saved backup bundle to $TESTTMP/tmpe/issue4845/doindexrev/.hg/strip-backup/9bc153528424-ee80edd4-backup.hg
1600 $ hg debugobsolete 9bc153528424ea266d13e57f9ff0d799dfe61e4b
1600 $ hg debugobsolete 9bc153528424ea266d13e57f9ff0d799dfe61e4b
1601 $ hg unbundle ../bundle-2.hg
1601 $ hg unbundle ../bundle-2.hg
1602 adding changesets
1602 adding changesets
1603 adding manifests
1603 adding manifests
1604 adding file changes
1604 adding file changes
1605 added 1 changesets with 1 changes to 1 files
1605 added 1 changesets with 1 changes to 1 files
1606 (1 other changesets obsolete on arrival)
1606 (1 other changesets obsolete on arrival)
1607 (run 'hg update' to get a working copy)
1607 (run 'hg update' to get a working copy)
1608 $ hg log -G
1608 $ hg log -G
1609 @ 7:7ae79c5d60f0 (draft) [tip ] dd
1609 @ 7:7ae79c5d60f0 (draft) [tip ] dd
1610 |
1610 |
1611 | o 6:4715cf767440 (draft) [ ] d
1611 | o 6:4715cf767440 (draft) [ ] d
1612 |/
1612 |/
1613 o 5:29346082e4a9 (draft) [ ] cc
1613 o 5:29346082e4a9 (draft) [ ] cc
1614 |
1614 |
1615 o 3:d27fb9b06607 (draft) [ ] bb
1615 o 3:d27fb9b06607 (draft) [ ] bb
1616 |
1616 |
1617 | o 2:6fdef60fcbab (draft) [ ] b
1617 | o 2:6fdef60fcbab (draft) [ ] b
1618 |/
1618 |/
1619 o 1:f9bd49731b0b (draft) [ ] aa
1619 o 1:f9bd49731b0b (draft) [ ] aa
1620
1620
1621
1621
1622 $ cd ..
1622 $ cd ..
1623
1624 Test issue 5783
1625
1626 $ hg init issue-5783 --config format.obsstore-version=0
1627 $ cd issue-5783
1628 $ touch a.cpp
1629 $ hg add a.cpp
1630 $ hg commit -m 'Add a.cpp'
1631 $ echo 'Hello' > a.cpp
1632 $ hg amend -n 'Testing::Obsstore' --config format.obsstore-version=0 --config extensions.amend=
1633 $ touch b.cpp
1634 $ hg add b.cpp
1635 $ hg commit -m 'Add b.cpp'
1636 $ echo 'Hello' > b.cpp
1637 $ hg amend -n 'Testing::Obsstore2' --config extensions.amend=
1638 $ hg debugobsolete
1639 d1b09fe3ad2b2a03e23a72f0c582e29a49570145 1a1a11184d2588af24e767e5335d5d9d07e8c550 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'note': 'Testing::Obsstore', 'operation': 'amend', 'user': 'test'}
1640 1bfd8e3868f641e048b6667cd672c68932f26d00 79959ca316d5b27ac6be1dd0cfd0843a5b5412eb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'note': 'Testing::Obsstore2', 'operation': 'amend', 'user': 'test'}
1641 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now