##// END OF EJS Templates
obsmarker: add an experimental flag controlling "operation" recording...
marmoute -
r32354:f432897a default
parent child Browse files
Show More
@@ -1,1287 +1,1290 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 "precursor" and possible
23 The old obsoleted changeset is called a "precursor" 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 precursor are called "successor markers of X" because they hold
25 a precursor 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 "precursor markers of Y" because they hold
27 a successors are call "precursor markers of Y" because they hold
28 information about the precursors of Y.
28 information about the precursors 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 struct
73 import struct
74
74
75 from .i18n import _
75 from .i18n import _
76 from . import (
76 from . import (
77 error,
77 error,
78 node,
78 node,
79 parsers,
79 parsers,
80 phases,
80 phases,
81 util,
81 util,
82 )
82 )
83
83
84 _pack = struct.pack
84 _pack = struct.pack
85 _unpack = struct.unpack
85 _unpack = struct.unpack
86 _calcsize = struct.calcsize
86 _calcsize = struct.calcsize
87 propertycache = util.propertycache
87 propertycache = util.propertycache
88
88
89 # the obsolete feature is not mature enough to be enabled by default.
89 # the obsolete feature is not mature enough to be enabled by default.
90 # you have to rely on third party extension extension to enable this.
90 # you have to rely on third party extension extension to enable this.
91 _enabled = False
91 _enabled = False
92
92
93 # Options for obsolescence
93 # Options for obsolescence
94 createmarkersopt = 'createmarkers'
94 createmarkersopt = 'createmarkers'
95 allowunstableopt = 'allowunstable'
95 allowunstableopt = 'allowunstable'
96 exchangeopt = 'exchange'
96 exchangeopt = 'exchange'
97
97
98 def isenabled(repo, option):
98 def isenabled(repo, option):
99 """Returns True if the given repository has the given obsolete option
99 """Returns True if the given repository has the given obsolete option
100 enabled.
100 enabled.
101 """
101 """
102 result = set(repo.ui.configlist('experimental', 'evolution'))
102 result = set(repo.ui.configlist('experimental', 'evolution'))
103 if 'all' in result:
103 if 'all' in result:
104 return True
104 return True
105
105
106 # For migration purposes, temporarily return true if the config hasn't been
106 # For migration purposes, temporarily return true if the config hasn't been
107 # set but _enabled is true.
107 # set but _enabled is true.
108 if len(result) == 0 and _enabled:
108 if len(result) == 0 and _enabled:
109 return True
109 return True
110
110
111 # createmarkers must be enabled if other options are enabled
111 # createmarkers must be enabled if other options are enabled
112 if ((allowunstableopt in result or exchangeopt in result) and
112 if ((allowunstableopt in result or exchangeopt in result) and
113 not createmarkersopt in result):
113 not createmarkersopt in result):
114 raise error.Abort(_("'createmarkers' obsolete option must be enabled "
114 raise error.Abort(_("'createmarkers' obsolete option must be enabled "
115 "if other obsolete options are enabled"))
115 "if other obsolete options are enabled"))
116
116
117 return option in result
117 return option in result
118
118
119 ### obsolescence marker flag
119 ### obsolescence marker flag
120
120
121 ## bumpedfix flag
121 ## bumpedfix flag
122 #
122 #
123 # When a changeset A' succeed to a changeset A which became public, we call A'
123 # When a changeset A' succeed to a changeset A which became public, we call A'
124 # "bumped" because it's a successors of a public changesets
124 # "bumped" because it's a successors of a public changesets
125 #
125 #
126 # o A' (bumped)
126 # o A' (bumped)
127 # |`:
127 # |`:
128 # | o A
128 # | o A
129 # |/
129 # |/
130 # o Z
130 # o Z
131 #
131 #
132 # The way to solve this situation is to create a new changeset Ad as children
132 # The way to solve this situation is to create a new changeset Ad as children
133 # of A. This changeset have the same content than A'. So the diff from A to A'
133 # of A. This changeset have the same content than A'. So the diff from A to A'
134 # is the same than the diff from A to Ad. Ad is marked as a successors of A'
134 # is the same than the diff from A to Ad. Ad is marked as a successors of A'
135 #
135 #
136 # o Ad
136 # o Ad
137 # |`:
137 # |`:
138 # | x A'
138 # | x A'
139 # |'|
139 # |'|
140 # o | A
140 # o | A
141 # |/
141 # |/
142 # o Z
142 # o Z
143 #
143 #
144 # But by transitivity Ad is also a successors of A. To avoid having Ad marked
144 # But by transitivity Ad is also a successors of A. To avoid having Ad marked
145 # as bumped too, we add the `bumpedfix` flag to the marker. <A', (Ad,)>.
145 # as bumped too, we add the `bumpedfix` flag to the marker. <A', (Ad,)>.
146 # This flag mean that the successors express the changes between the public and
146 # This flag mean that the successors express the changes between the public and
147 # bumped version and fix the situation, breaking the transitivity of
147 # bumped version and fix the situation, breaking the transitivity of
148 # "bumped" here.
148 # "bumped" here.
149 bumpedfix = 1
149 bumpedfix = 1
150 usingsha256 = 2
150 usingsha256 = 2
151
151
152 ## Parsing and writing of version "0"
152 ## Parsing and writing of version "0"
153 #
153 #
154 # The header is followed by the markers. Each marker is made of:
154 # The header is followed by the markers. Each marker is made of:
155 #
155 #
156 # - 1 uint8 : number of new changesets "N", can be zero.
156 # - 1 uint8 : number of new changesets "N", can be zero.
157 #
157 #
158 # - 1 uint32: metadata size "M" in bytes.
158 # - 1 uint32: metadata size "M" in bytes.
159 #
159 #
160 # - 1 byte: a bit field. It is reserved for flags used in common
160 # - 1 byte: a bit field. It is reserved for flags used in common
161 # obsolete marker operations, to avoid repeated decoding of metadata
161 # obsolete marker operations, to avoid repeated decoding of metadata
162 # entries.
162 # entries.
163 #
163 #
164 # - 20 bytes: obsoleted changeset identifier.
164 # - 20 bytes: obsoleted changeset identifier.
165 #
165 #
166 # - N*20 bytes: new changesets identifiers.
166 # - N*20 bytes: new changesets identifiers.
167 #
167 #
168 # - M bytes: metadata as a sequence of nul-terminated strings. Each
168 # - M bytes: metadata as a sequence of nul-terminated strings. Each
169 # string contains a key and a value, separated by a colon ':', without
169 # string contains a key and a value, separated by a colon ':', without
170 # additional encoding. Keys cannot contain '\0' or ':' and values
170 # additional encoding. Keys cannot contain '\0' or ':' and values
171 # cannot contain '\0'.
171 # cannot contain '\0'.
172 _fm0version = 0
172 _fm0version = 0
173 _fm0fixed = '>BIB20s'
173 _fm0fixed = '>BIB20s'
174 _fm0node = '20s'
174 _fm0node = '20s'
175 _fm0fsize = _calcsize(_fm0fixed)
175 _fm0fsize = _calcsize(_fm0fixed)
176 _fm0fnodesize = _calcsize(_fm0node)
176 _fm0fnodesize = _calcsize(_fm0node)
177
177
178 def _fm0readmarkers(data, off):
178 def _fm0readmarkers(data, off):
179 # Loop on markers
179 # Loop on markers
180 l = len(data)
180 l = len(data)
181 while off + _fm0fsize <= l:
181 while off + _fm0fsize <= l:
182 # read fixed part
182 # read fixed part
183 cur = data[off:off + _fm0fsize]
183 cur = data[off:off + _fm0fsize]
184 off += _fm0fsize
184 off += _fm0fsize
185 numsuc, mdsize, flags, pre = _unpack(_fm0fixed, cur)
185 numsuc, mdsize, flags, pre = _unpack(_fm0fixed, cur)
186 # read replacement
186 # read replacement
187 sucs = ()
187 sucs = ()
188 if numsuc:
188 if numsuc:
189 s = (_fm0fnodesize * numsuc)
189 s = (_fm0fnodesize * numsuc)
190 cur = data[off:off + s]
190 cur = data[off:off + s]
191 sucs = _unpack(_fm0node * numsuc, cur)
191 sucs = _unpack(_fm0node * numsuc, cur)
192 off += s
192 off += s
193 # read metadata
193 # read metadata
194 # (metadata will be decoded on demand)
194 # (metadata will be decoded on demand)
195 metadata = data[off:off + mdsize]
195 metadata = data[off:off + mdsize]
196 if len(metadata) != mdsize:
196 if len(metadata) != mdsize:
197 raise error.Abort(_('parsing obsolete marker: metadata is too '
197 raise error.Abort(_('parsing obsolete marker: metadata is too '
198 'short, %d bytes expected, got %d')
198 'short, %d bytes expected, got %d')
199 % (mdsize, len(metadata)))
199 % (mdsize, len(metadata)))
200 off += mdsize
200 off += mdsize
201 metadata = _fm0decodemeta(metadata)
201 metadata = _fm0decodemeta(metadata)
202 try:
202 try:
203 when, offset = metadata.pop('date', '0 0').split(' ')
203 when, offset = metadata.pop('date', '0 0').split(' ')
204 date = float(when), int(offset)
204 date = float(when), int(offset)
205 except ValueError:
205 except ValueError:
206 date = (0., 0)
206 date = (0., 0)
207 parents = None
207 parents = None
208 if 'p2' in metadata:
208 if 'p2' in metadata:
209 parents = (metadata.pop('p1', None), metadata.pop('p2', None))
209 parents = (metadata.pop('p1', None), metadata.pop('p2', None))
210 elif 'p1' in metadata:
210 elif 'p1' in metadata:
211 parents = (metadata.pop('p1', None),)
211 parents = (metadata.pop('p1', None),)
212 elif 'p0' in metadata:
212 elif 'p0' in metadata:
213 parents = ()
213 parents = ()
214 if parents is not None:
214 if parents is not None:
215 try:
215 try:
216 parents = tuple(node.bin(p) for p in parents)
216 parents = tuple(node.bin(p) for p in parents)
217 # if parent content is not a nodeid, drop the data
217 # if parent content is not a nodeid, drop the data
218 for p in parents:
218 for p in parents:
219 if len(p) != 20:
219 if len(p) != 20:
220 parents = None
220 parents = None
221 break
221 break
222 except TypeError:
222 except TypeError:
223 # if content cannot be translated to nodeid drop the data.
223 # if content cannot be translated to nodeid drop the data.
224 parents = None
224 parents = None
225
225
226 metadata = tuple(sorted(metadata.iteritems()))
226 metadata = tuple(sorted(metadata.iteritems()))
227
227
228 yield (pre, sucs, flags, metadata, date, parents)
228 yield (pre, sucs, flags, metadata, date, parents)
229
229
230 def _fm0encodeonemarker(marker):
230 def _fm0encodeonemarker(marker):
231 pre, sucs, flags, metadata, date, parents = marker
231 pre, sucs, flags, metadata, date, parents = marker
232 if flags & usingsha256:
232 if flags & usingsha256:
233 raise error.Abort(_('cannot handle sha256 with old obsstore format'))
233 raise error.Abort(_('cannot handle sha256 with old obsstore format'))
234 metadata = dict(metadata)
234 metadata = dict(metadata)
235 time, tz = date
235 time, tz = date
236 metadata['date'] = '%r %i' % (time, tz)
236 metadata['date'] = '%r %i' % (time, tz)
237 if parents is not None:
237 if parents is not None:
238 if not parents:
238 if not parents:
239 # mark that we explicitly recorded no parents
239 # mark that we explicitly recorded no parents
240 metadata['p0'] = ''
240 metadata['p0'] = ''
241 for i, p in enumerate(parents, 1):
241 for i, p in enumerate(parents, 1):
242 metadata['p%i' % i] = node.hex(p)
242 metadata['p%i' % i] = node.hex(p)
243 metadata = _fm0encodemeta(metadata)
243 metadata = _fm0encodemeta(metadata)
244 numsuc = len(sucs)
244 numsuc = len(sucs)
245 format = _fm0fixed + (_fm0node * numsuc)
245 format = _fm0fixed + (_fm0node * numsuc)
246 data = [numsuc, len(metadata), flags, pre]
246 data = [numsuc, len(metadata), flags, pre]
247 data.extend(sucs)
247 data.extend(sucs)
248 return _pack(format, *data) + metadata
248 return _pack(format, *data) + metadata
249
249
250 def _fm0encodemeta(meta):
250 def _fm0encodemeta(meta):
251 """Return encoded metadata string to string mapping.
251 """Return encoded metadata string to string mapping.
252
252
253 Assume no ':' in key and no '\0' in both key and value."""
253 Assume no ':' in key and no '\0' in both key and value."""
254 for key, value in meta.iteritems():
254 for key, value in meta.iteritems():
255 if ':' in key or '\0' in key:
255 if ':' in key or '\0' in key:
256 raise ValueError("':' and '\0' are forbidden in metadata key'")
256 raise ValueError("':' and '\0' are forbidden in metadata key'")
257 if '\0' in value:
257 if '\0' in value:
258 raise ValueError("':' is forbidden in metadata value'")
258 raise ValueError("':' is forbidden in metadata value'")
259 return '\0'.join(['%s:%s' % (k, meta[k]) for k in sorted(meta)])
259 return '\0'.join(['%s:%s' % (k, meta[k]) for k in sorted(meta)])
260
260
261 def _fm0decodemeta(data):
261 def _fm0decodemeta(data):
262 """Return string to string dictionary from encoded version."""
262 """Return string to string dictionary from encoded version."""
263 d = {}
263 d = {}
264 for l in data.split('\0'):
264 for l in data.split('\0'):
265 if l:
265 if l:
266 key, value = l.split(':')
266 key, value = l.split(':')
267 d[key] = value
267 d[key] = value
268 return d
268 return d
269
269
270 ## Parsing and writing of version "1"
270 ## Parsing and writing of version "1"
271 #
271 #
272 # The header is followed by the markers. Each marker is made of:
272 # The header is followed by the markers. Each marker is made of:
273 #
273 #
274 # - uint32: total size of the marker (including this field)
274 # - uint32: total size of the marker (including this field)
275 #
275 #
276 # - float64: date in seconds since epoch
276 # - float64: date in seconds since epoch
277 #
277 #
278 # - int16: timezone offset in minutes
278 # - int16: timezone offset in minutes
279 #
279 #
280 # - uint16: a bit field. It is reserved for flags used in common
280 # - uint16: a bit field. It is reserved for flags used in common
281 # obsolete marker operations, to avoid repeated decoding of metadata
281 # obsolete marker operations, to avoid repeated decoding of metadata
282 # entries.
282 # entries.
283 #
283 #
284 # - uint8: number of successors "N", can be zero.
284 # - uint8: number of successors "N", can be zero.
285 #
285 #
286 # - uint8: number of parents "P", can be zero.
286 # - uint8: number of parents "P", can be zero.
287 #
287 #
288 # 0: parents data stored but no parent,
288 # 0: parents data stored but no parent,
289 # 1: one parent stored,
289 # 1: one parent stored,
290 # 2: two parents stored,
290 # 2: two parents stored,
291 # 3: no parent data stored
291 # 3: no parent data stored
292 #
292 #
293 # - uint8: number of metadata entries M
293 # - uint8: number of metadata entries M
294 #
294 #
295 # - 20 or 32 bytes: precursor changeset identifier.
295 # - 20 or 32 bytes: precursor changeset identifier.
296 #
296 #
297 # - N*(20 or 32) bytes: successors changesets identifiers.
297 # - N*(20 or 32) bytes: successors changesets identifiers.
298 #
298 #
299 # - P*(20 or 32) bytes: parents of the precursors changesets.
299 # - P*(20 or 32) bytes: parents of the precursors changesets.
300 #
300 #
301 # - M*(uint8, uint8): size of all metadata entries (key and value)
301 # - M*(uint8, uint8): size of all metadata entries (key and value)
302 #
302 #
303 # - remaining bytes: the metadata, each (key, value) pair after the other.
303 # - remaining bytes: the metadata, each (key, value) pair after the other.
304 _fm1version = 1
304 _fm1version = 1
305 _fm1fixed = '>IdhHBBB20s'
305 _fm1fixed = '>IdhHBBB20s'
306 _fm1nodesha1 = '20s'
306 _fm1nodesha1 = '20s'
307 _fm1nodesha256 = '32s'
307 _fm1nodesha256 = '32s'
308 _fm1nodesha1size = _calcsize(_fm1nodesha1)
308 _fm1nodesha1size = _calcsize(_fm1nodesha1)
309 _fm1nodesha256size = _calcsize(_fm1nodesha256)
309 _fm1nodesha256size = _calcsize(_fm1nodesha256)
310 _fm1fsize = _calcsize(_fm1fixed)
310 _fm1fsize = _calcsize(_fm1fixed)
311 _fm1parentnone = 3
311 _fm1parentnone = 3
312 _fm1parentshift = 14
312 _fm1parentshift = 14
313 _fm1parentmask = (_fm1parentnone << _fm1parentshift)
313 _fm1parentmask = (_fm1parentnone << _fm1parentshift)
314 _fm1metapair = 'BB'
314 _fm1metapair = 'BB'
315 _fm1metapairsize = _calcsize('BB')
315 _fm1metapairsize = _calcsize('BB')
316
316
317 def _fm1purereadmarkers(data, off):
317 def _fm1purereadmarkers(data, off):
318 # make some global constants local for performance
318 # make some global constants local for performance
319 noneflag = _fm1parentnone
319 noneflag = _fm1parentnone
320 sha2flag = usingsha256
320 sha2flag = usingsha256
321 sha1size = _fm1nodesha1size
321 sha1size = _fm1nodesha1size
322 sha2size = _fm1nodesha256size
322 sha2size = _fm1nodesha256size
323 sha1fmt = _fm1nodesha1
323 sha1fmt = _fm1nodesha1
324 sha2fmt = _fm1nodesha256
324 sha2fmt = _fm1nodesha256
325 metasize = _fm1metapairsize
325 metasize = _fm1metapairsize
326 metafmt = _fm1metapair
326 metafmt = _fm1metapair
327 fsize = _fm1fsize
327 fsize = _fm1fsize
328 unpack = _unpack
328 unpack = _unpack
329
329
330 # Loop on markers
330 # Loop on markers
331 stop = len(data) - _fm1fsize
331 stop = len(data) - _fm1fsize
332 ufixed = struct.Struct(_fm1fixed).unpack
332 ufixed = struct.Struct(_fm1fixed).unpack
333
333
334 while off <= stop:
334 while off <= stop:
335 # read fixed part
335 # read fixed part
336 o1 = off + fsize
336 o1 = off + fsize
337 t, secs, tz, flags, numsuc, numpar, nummeta, prec = ufixed(data[off:o1])
337 t, secs, tz, flags, numsuc, numpar, nummeta, prec = ufixed(data[off:o1])
338
338
339 if flags & sha2flag:
339 if flags & sha2flag:
340 # FIXME: prec was read as a SHA1, needs to be amended
340 # FIXME: prec was read as a SHA1, needs to be amended
341
341
342 # read 0 or more successors
342 # read 0 or more successors
343 if numsuc == 1:
343 if numsuc == 1:
344 o2 = o1 + sha2size
344 o2 = o1 + sha2size
345 sucs = (data[o1:o2],)
345 sucs = (data[o1:o2],)
346 else:
346 else:
347 o2 = o1 + sha2size * numsuc
347 o2 = o1 + sha2size * numsuc
348 sucs = unpack(sha2fmt * numsuc, data[o1:o2])
348 sucs = unpack(sha2fmt * numsuc, data[o1:o2])
349
349
350 # read parents
350 # read parents
351 if numpar == noneflag:
351 if numpar == noneflag:
352 o3 = o2
352 o3 = o2
353 parents = None
353 parents = None
354 elif numpar == 1:
354 elif numpar == 1:
355 o3 = o2 + sha2size
355 o3 = o2 + sha2size
356 parents = (data[o2:o3],)
356 parents = (data[o2:o3],)
357 else:
357 else:
358 o3 = o2 + sha2size * numpar
358 o3 = o2 + sha2size * numpar
359 parents = unpack(sha2fmt * numpar, data[o2:o3])
359 parents = unpack(sha2fmt * numpar, data[o2:o3])
360 else:
360 else:
361 # read 0 or more successors
361 # read 0 or more successors
362 if numsuc == 1:
362 if numsuc == 1:
363 o2 = o1 + sha1size
363 o2 = o1 + sha1size
364 sucs = (data[o1:o2],)
364 sucs = (data[o1:o2],)
365 else:
365 else:
366 o2 = o1 + sha1size * numsuc
366 o2 = o1 + sha1size * numsuc
367 sucs = unpack(sha1fmt * numsuc, data[o1:o2])
367 sucs = unpack(sha1fmt * numsuc, data[o1:o2])
368
368
369 # read parents
369 # read parents
370 if numpar == noneflag:
370 if numpar == noneflag:
371 o3 = o2
371 o3 = o2
372 parents = None
372 parents = None
373 elif numpar == 1:
373 elif numpar == 1:
374 o3 = o2 + sha1size
374 o3 = o2 + sha1size
375 parents = (data[o2:o3],)
375 parents = (data[o2:o3],)
376 else:
376 else:
377 o3 = o2 + sha1size * numpar
377 o3 = o2 + sha1size * numpar
378 parents = unpack(sha1fmt * numpar, data[o2:o3])
378 parents = unpack(sha1fmt * numpar, data[o2:o3])
379
379
380 # read metadata
380 # read metadata
381 off = o3 + metasize * nummeta
381 off = o3 + metasize * nummeta
382 metapairsize = unpack('>' + (metafmt * nummeta), data[o3:off])
382 metapairsize = unpack('>' + (metafmt * nummeta), data[o3:off])
383 metadata = []
383 metadata = []
384 for idx in xrange(0, len(metapairsize), 2):
384 for idx in xrange(0, len(metapairsize), 2):
385 o1 = off + metapairsize[idx]
385 o1 = off + metapairsize[idx]
386 o2 = o1 + metapairsize[idx + 1]
386 o2 = o1 + metapairsize[idx + 1]
387 metadata.append((data[off:o1], data[o1:o2]))
387 metadata.append((data[off:o1], data[o1:o2]))
388 off = o2
388 off = o2
389
389
390 yield (prec, sucs, flags, tuple(metadata), (secs, tz * 60), parents)
390 yield (prec, sucs, flags, tuple(metadata), (secs, tz * 60), parents)
391
391
392 def _fm1encodeonemarker(marker):
392 def _fm1encodeonemarker(marker):
393 pre, sucs, flags, metadata, date, parents = marker
393 pre, sucs, flags, metadata, date, parents = marker
394 # determine node size
394 # determine node size
395 _fm1node = _fm1nodesha1
395 _fm1node = _fm1nodesha1
396 if flags & usingsha256:
396 if flags & usingsha256:
397 _fm1node = _fm1nodesha256
397 _fm1node = _fm1nodesha256
398 numsuc = len(sucs)
398 numsuc = len(sucs)
399 numextranodes = numsuc
399 numextranodes = numsuc
400 if parents is None:
400 if parents is None:
401 numpar = _fm1parentnone
401 numpar = _fm1parentnone
402 else:
402 else:
403 numpar = len(parents)
403 numpar = len(parents)
404 numextranodes += numpar
404 numextranodes += numpar
405 formatnodes = _fm1node * numextranodes
405 formatnodes = _fm1node * numextranodes
406 formatmeta = _fm1metapair * len(metadata)
406 formatmeta = _fm1metapair * len(metadata)
407 format = _fm1fixed + formatnodes + formatmeta
407 format = _fm1fixed + formatnodes + formatmeta
408 # tz is stored in minutes so we divide by 60
408 # tz is stored in minutes so we divide by 60
409 tz = date[1]//60
409 tz = date[1]//60
410 data = [None, date[0], tz, flags, numsuc, numpar, len(metadata), pre]
410 data = [None, date[0], tz, flags, numsuc, numpar, len(metadata), pre]
411 data.extend(sucs)
411 data.extend(sucs)
412 if parents is not None:
412 if parents is not None:
413 data.extend(parents)
413 data.extend(parents)
414 totalsize = _calcsize(format)
414 totalsize = _calcsize(format)
415 for key, value in metadata:
415 for key, value in metadata:
416 lk = len(key)
416 lk = len(key)
417 lv = len(value)
417 lv = len(value)
418 data.append(lk)
418 data.append(lk)
419 data.append(lv)
419 data.append(lv)
420 totalsize += lk + lv
420 totalsize += lk + lv
421 data[0] = totalsize
421 data[0] = totalsize
422 data = [_pack(format, *data)]
422 data = [_pack(format, *data)]
423 for key, value in metadata:
423 for key, value in metadata:
424 data.append(key)
424 data.append(key)
425 data.append(value)
425 data.append(value)
426 return ''.join(data)
426 return ''.join(data)
427
427
428 def _fm1readmarkers(data, off):
428 def _fm1readmarkers(data, off):
429 native = getattr(parsers, 'fm1readmarkers', None)
429 native = getattr(parsers, 'fm1readmarkers', None)
430 if not native:
430 if not native:
431 return _fm1purereadmarkers(data, off)
431 return _fm1purereadmarkers(data, off)
432 stop = len(data) - _fm1fsize
432 stop = len(data) - _fm1fsize
433 return native(data, off, stop)
433 return native(data, off, stop)
434
434
435 # mapping to read/write various marker formats
435 # mapping to read/write various marker formats
436 # <version> -> (decoder, encoder)
436 # <version> -> (decoder, encoder)
437 formats = {_fm0version: (_fm0readmarkers, _fm0encodeonemarker),
437 formats = {_fm0version: (_fm0readmarkers, _fm0encodeonemarker),
438 _fm1version: (_fm1readmarkers, _fm1encodeonemarker)}
438 _fm1version: (_fm1readmarkers, _fm1encodeonemarker)}
439
439
440 @util.nogc
440 @util.nogc
441 def _readmarkers(data):
441 def _readmarkers(data):
442 """Read and enumerate markers from raw data"""
442 """Read and enumerate markers from raw data"""
443 off = 0
443 off = 0
444 diskversion = _unpack('>B', data[off:off + 1])[0]
444 diskversion = _unpack('>B', data[off:off + 1])[0]
445 off += 1
445 off += 1
446 if diskversion not in formats:
446 if diskversion not in formats:
447 raise error.Abort(_('parsing obsolete marker: unknown version %r')
447 raise error.Abort(_('parsing obsolete marker: unknown version %r')
448 % diskversion)
448 % diskversion)
449 return diskversion, formats[diskversion][0](data, off)
449 return diskversion, formats[diskversion][0](data, off)
450
450
451 def encodemarkers(markers, addheader=False, version=_fm0version):
451 def encodemarkers(markers, addheader=False, version=_fm0version):
452 # Kept separate from flushmarkers(), it will be reused for
452 # Kept separate from flushmarkers(), it will be reused for
453 # markers exchange.
453 # markers exchange.
454 encodeone = formats[version][1]
454 encodeone = formats[version][1]
455 if addheader:
455 if addheader:
456 yield _pack('>B', version)
456 yield _pack('>B', version)
457 for marker in markers:
457 for marker in markers:
458 yield encodeone(marker)
458 yield encodeone(marker)
459
459
460
460
461 class marker(object):
461 class marker(object):
462 """Wrap obsolete marker raw data"""
462 """Wrap obsolete marker raw data"""
463
463
464 def __init__(self, repo, data):
464 def __init__(self, repo, data):
465 # the repo argument will be used to create changectx in later version
465 # the repo argument will be used to create changectx in later version
466 self._repo = repo
466 self._repo = repo
467 self._data = data
467 self._data = data
468 self._decodedmeta = None
468 self._decodedmeta = None
469
469
470 def __hash__(self):
470 def __hash__(self):
471 return hash(self._data)
471 return hash(self._data)
472
472
473 def __eq__(self, other):
473 def __eq__(self, other):
474 if type(other) != type(self):
474 if type(other) != type(self):
475 return False
475 return False
476 return self._data == other._data
476 return self._data == other._data
477
477
478 def precnode(self):
478 def precnode(self):
479 """Precursor changeset node identifier"""
479 """Precursor changeset node identifier"""
480 return self._data[0]
480 return self._data[0]
481
481
482 def succnodes(self):
482 def succnodes(self):
483 """List of successor changesets node identifiers"""
483 """List of successor changesets node identifiers"""
484 return self._data[1]
484 return self._data[1]
485
485
486 def parentnodes(self):
486 def parentnodes(self):
487 """Parents of the precursors (None if not recorded)"""
487 """Parents of the precursors (None if not recorded)"""
488 return self._data[5]
488 return self._data[5]
489
489
490 def metadata(self):
490 def metadata(self):
491 """Decoded metadata dictionary"""
491 """Decoded metadata dictionary"""
492 return dict(self._data[3])
492 return dict(self._data[3])
493
493
494 def date(self):
494 def date(self):
495 """Creation date as (unixtime, offset)"""
495 """Creation date as (unixtime, offset)"""
496 return self._data[4]
496 return self._data[4]
497
497
498 def flags(self):
498 def flags(self):
499 """The flags field of the marker"""
499 """The flags field of the marker"""
500 return self._data[2]
500 return self._data[2]
501
501
502 @util.nogc
502 @util.nogc
503 def _addsuccessors(successors, markers):
503 def _addsuccessors(successors, markers):
504 for mark in markers:
504 for mark in markers:
505 successors.setdefault(mark[0], set()).add(mark)
505 successors.setdefault(mark[0], set()).add(mark)
506
506
507 @util.nogc
507 @util.nogc
508 def _addprecursors(precursors, markers):
508 def _addprecursors(precursors, markers):
509 for mark in markers:
509 for mark in markers:
510 for suc in mark[1]:
510 for suc in mark[1]:
511 precursors.setdefault(suc, set()).add(mark)
511 precursors.setdefault(suc, set()).add(mark)
512
512
513 @util.nogc
513 @util.nogc
514 def _addchildren(children, markers):
514 def _addchildren(children, markers):
515 for mark in markers:
515 for mark in markers:
516 parents = mark[5]
516 parents = mark[5]
517 if parents is not None:
517 if parents is not None:
518 for p in parents:
518 for p in parents:
519 children.setdefault(p, set()).add(mark)
519 children.setdefault(p, set()).add(mark)
520
520
521 def _checkinvalidmarkers(markers):
521 def _checkinvalidmarkers(markers):
522 """search for marker with invalid data and raise error if needed
522 """search for marker with invalid data and raise error if needed
523
523
524 Exist as a separated function to allow the evolve extension for a more
524 Exist as a separated function to allow the evolve extension for a more
525 subtle handling.
525 subtle handling.
526 """
526 """
527 for mark in markers:
527 for mark in markers:
528 if node.nullid in mark[1]:
528 if node.nullid in mark[1]:
529 raise error.Abort(_('bad obsolescence marker detected: '
529 raise error.Abort(_('bad obsolescence marker detected: '
530 'invalid successors nullid'))
530 'invalid successors nullid'))
531
531
532 class obsstore(object):
532 class obsstore(object):
533 """Store obsolete markers
533 """Store obsolete markers
534
534
535 Markers can be accessed with two mappings:
535 Markers can be accessed with two mappings:
536 - precursors[x] -> set(markers on precursors edges of x)
536 - precursors[x] -> set(markers on precursors edges of x)
537 - successors[x] -> set(markers on successors edges of x)
537 - successors[x] -> set(markers on successors edges of x)
538 - children[x] -> set(markers on precursors edges of children(x)
538 - children[x] -> set(markers on precursors edges of children(x)
539 """
539 """
540
540
541 fields = ('prec', 'succs', 'flag', 'meta', 'date', 'parents')
541 fields = ('prec', 'succs', 'flag', 'meta', 'date', 'parents')
542 # prec: nodeid, precursor changesets
542 # prec: nodeid, precursor changesets
543 # succs: tuple of nodeid, successor changesets (0-N length)
543 # succs: tuple of nodeid, successor changesets (0-N length)
544 # flag: integer, flag field carrying modifier for the markers (see doc)
544 # flag: integer, flag field carrying modifier for the markers (see doc)
545 # meta: binary blob, encoded metadata dictionary
545 # meta: binary blob, encoded metadata dictionary
546 # date: (float, int) tuple, date of marker creation
546 # date: (float, int) tuple, date of marker creation
547 # parents: (tuple of nodeid) or None, parents of precursors
547 # parents: (tuple of nodeid) or None, parents of precursors
548 # None is used when no data has been recorded
548 # None is used when no data has been recorded
549
549
550 def __init__(self, svfs, defaultformat=_fm1version, readonly=False):
550 def __init__(self, svfs, defaultformat=_fm1version, readonly=False):
551 # caches for various obsolescence related cache
551 # caches for various obsolescence related cache
552 self.caches = {}
552 self.caches = {}
553 self.svfs = svfs
553 self.svfs = svfs
554 self._version = defaultformat
554 self._version = defaultformat
555 self._readonly = readonly
555 self._readonly = readonly
556
556
557 def __iter__(self):
557 def __iter__(self):
558 return iter(self._all)
558 return iter(self._all)
559
559
560 def __len__(self):
560 def __len__(self):
561 return len(self._all)
561 return len(self._all)
562
562
563 def __nonzero__(self):
563 def __nonzero__(self):
564 if not self._cached('_all'):
564 if not self._cached('_all'):
565 try:
565 try:
566 return self.svfs.stat('obsstore').st_size > 1
566 return self.svfs.stat('obsstore').st_size > 1
567 except OSError as inst:
567 except OSError as inst:
568 if inst.errno != errno.ENOENT:
568 if inst.errno != errno.ENOENT:
569 raise
569 raise
570 # just build an empty _all list if no obsstore exists, which
570 # just build an empty _all list if no obsstore exists, which
571 # avoids further stat() syscalls
571 # avoids further stat() syscalls
572 pass
572 pass
573 return bool(self._all)
573 return bool(self._all)
574
574
575 __bool__ = __nonzero__
575 __bool__ = __nonzero__
576
576
577 @property
577 @property
578 def readonly(self):
578 def readonly(self):
579 """True if marker creation is disabled
579 """True if marker creation is disabled
580
580
581 Remove me in the future when obsolete marker is always on."""
581 Remove me in the future when obsolete marker is always on."""
582 return self._readonly
582 return self._readonly
583
583
584 def create(self, transaction, prec, succs=(), flag=0, parents=None,
584 def create(self, transaction, prec, succs=(), flag=0, parents=None,
585 date=None, metadata=None):
585 date=None, metadata=None):
586 """obsolete: add a new obsolete marker
586 """obsolete: add a new obsolete marker
587
587
588 * ensuring it is hashable
588 * ensuring it is hashable
589 * check mandatory metadata
589 * check mandatory metadata
590 * encode metadata
590 * encode metadata
591
591
592 If you are a human writing code creating marker you want to use the
592 If you are a human writing code creating marker you want to use the
593 `createmarkers` function in this module instead.
593 `createmarkers` function in this module instead.
594
594
595 return True if a new marker have been added, False if the markers
595 return True if a new marker have been added, False if the markers
596 already existed (no op).
596 already existed (no op).
597 """
597 """
598 if metadata is None:
598 if metadata is None:
599 metadata = {}
599 metadata = {}
600 if date is None:
600 if date is None:
601 if 'date' in metadata:
601 if 'date' in metadata:
602 # as a courtesy for out-of-tree extensions
602 # as a courtesy for out-of-tree extensions
603 date = util.parsedate(metadata.pop('date'))
603 date = util.parsedate(metadata.pop('date'))
604 else:
604 else:
605 date = util.makedate()
605 date = util.makedate()
606 if len(prec) != 20:
606 if len(prec) != 20:
607 raise ValueError(prec)
607 raise ValueError(prec)
608 for succ in succs:
608 for succ in succs:
609 if len(succ) != 20:
609 if len(succ) != 20:
610 raise ValueError(succ)
610 raise ValueError(succ)
611 if prec in succs:
611 if prec in succs:
612 raise ValueError(_('in-marker cycle with %s') % node.hex(prec))
612 raise ValueError(_('in-marker cycle with %s') % node.hex(prec))
613
613
614 metadata = tuple(sorted(metadata.iteritems()))
614 metadata = tuple(sorted(metadata.iteritems()))
615
615
616 marker = (str(prec), tuple(succs), int(flag), metadata, date, parents)
616 marker = (str(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(self._all)
627 known = set(self._all)
628 new = []
628 new = []
629 for m in markers:
629 for m in markers:
630 if m not in known:
630 if m not in known:
631 known.add(m)
631 known.add(m)
632 new.append(m)
632 new.append(m)
633 if new:
633 if new:
634 f = self.svfs('obsstore', 'ab')
634 f = self.svfs('obsstore', 'ab')
635 try:
635 try:
636 offset = f.tell()
636 offset = f.tell()
637 transaction.add('obsstore', offset)
637 transaction.add('obsstore', offset)
638 # offset == 0: new file - add the version header
638 # offset == 0: new file - add the version header
639 for bytes in encodemarkers(new, offset == 0, self._version):
639 for bytes in encodemarkers(new, offset == 0, self._version):
640 f.write(bytes)
640 f.write(bytes)
641 finally:
641 finally:
642 # XXX: f.close() == filecache invalidation == obsstore rebuilt.
642 # XXX: f.close() == filecache invalidation == obsstore rebuilt.
643 # call 'filecacheentry.refresh()' here
643 # call 'filecacheentry.refresh()' here
644 f.close()
644 f.close()
645 self._addmarkers(new)
645 self._addmarkers(new)
646 # new marker *may* have changed several set. invalidate the cache.
646 # new marker *may* have changed several set. invalidate the cache.
647 self.caches.clear()
647 self.caches.clear()
648 # records the number of new markers for the transaction hooks
648 # records the number of new markers for the transaction hooks
649 previous = int(transaction.hookargs.get('new_obsmarkers', '0'))
649 previous = int(transaction.hookargs.get('new_obsmarkers', '0'))
650 transaction.hookargs['new_obsmarkers'] = str(previous + len(new))
650 transaction.hookargs['new_obsmarkers'] = str(previous + len(new))
651 return len(new)
651 return len(new)
652
652
653 def mergemarkers(self, transaction, data):
653 def mergemarkers(self, transaction, data):
654 """merge a binary stream of markers inside the obsstore
654 """merge a binary stream of markers inside the obsstore
655
655
656 Returns the number of new markers added."""
656 Returns the number of new markers added."""
657 version, markers = _readmarkers(data)
657 version, markers = _readmarkers(data)
658 return self.add(transaction, markers)
658 return self.add(transaction, markers)
659
659
660 @propertycache
660 @propertycache
661 def _all(self):
661 def _all(self):
662 data = self.svfs.tryread('obsstore')
662 data = self.svfs.tryread('obsstore')
663 if not data:
663 if not data:
664 return []
664 return []
665 self._version, markers = _readmarkers(data)
665 self._version, markers = _readmarkers(data)
666 markers = list(markers)
666 markers = list(markers)
667 _checkinvalidmarkers(markers)
667 _checkinvalidmarkers(markers)
668 return markers
668 return markers
669
669
670 @propertycache
670 @propertycache
671 def successors(self):
671 def successors(self):
672 successors = {}
672 successors = {}
673 _addsuccessors(successors, self._all)
673 _addsuccessors(successors, self._all)
674 return successors
674 return successors
675
675
676 @propertycache
676 @propertycache
677 def precursors(self):
677 def precursors(self):
678 precursors = {}
678 precursors = {}
679 _addprecursors(precursors, self._all)
679 _addprecursors(precursors, self._all)
680 return precursors
680 return precursors
681
681
682 @propertycache
682 @propertycache
683 def children(self):
683 def children(self):
684 children = {}
684 children = {}
685 _addchildren(children, self._all)
685 _addchildren(children, self._all)
686 return children
686 return children
687
687
688 def _cached(self, attr):
688 def _cached(self, attr):
689 return attr in self.__dict__
689 return attr in self.__dict__
690
690
691 def _addmarkers(self, markers):
691 def _addmarkers(self, markers):
692 markers = list(markers) # to allow repeated iteration
692 markers = list(markers) # to allow repeated iteration
693 self._all.extend(markers)
693 self._all.extend(markers)
694 if self._cached('successors'):
694 if self._cached('successors'):
695 _addsuccessors(self.successors, markers)
695 _addsuccessors(self.successors, markers)
696 if self._cached('precursors'):
696 if self._cached('precursors'):
697 _addprecursors(self.precursors, markers)
697 _addprecursors(self.precursors, markers)
698 if self._cached('children'):
698 if self._cached('children'):
699 _addchildren(self.children, markers)
699 _addchildren(self.children, markers)
700 _checkinvalidmarkers(markers)
700 _checkinvalidmarkers(markers)
701
701
702 def relevantmarkers(self, nodes):
702 def relevantmarkers(self, nodes):
703 """return a set of all obsolescence markers relevant to a set of nodes.
703 """return a set of all obsolescence markers relevant to a set of nodes.
704
704
705 "relevant" to a set of nodes mean:
705 "relevant" to a set of nodes mean:
706
706
707 - marker that use this changeset as successor
707 - marker that use this changeset as successor
708 - prune marker of direct children on this changeset
708 - prune marker of direct children on this changeset
709 - recursive application of the two rules on precursors of these markers
709 - recursive application of the two rules on precursors of these markers
710
710
711 It is a set so you cannot rely on order."""
711 It is a set so you cannot rely on order."""
712
712
713 pendingnodes = set(nodes)
713 pendingnodes = set(nodes)
714 seenmarkers = set()
714 seenmarkers = set()
715 seennodes = set(pendingnodes)
715 seennodes = set(pendingnodes)
716 precursorsmarkers = self.precursors
716 precursorsmarkers = self.precursors
717 children = self.children
717 children = self.children
718 while pendingnodes:
718 while pendingnodes:
719 direct = set()
719 direct = set()
720 for current in pendingnodes:
720 for current in pendingnodes:
721 direct.update(precursorsmarkers.get(current, ()))
721 direct.update(precursorsmarkers.get(current, ()))
722 pruned = [m for m in children.get(current, ()) if not m[1]]
722 pruned = [m for m in children.get(current, ()) if not m[1]]
723 direct.update(pruned)
723 direct.update(pruned)
724 direct -= seenmarkers
724 direct -= seenmarkers
725 pendingnodes = set([m[0] for m in direct])
725 pendingnodes = set([m[0] for m in direct])
726 seenmarkers |= direct
726 seenmarkers |= direct
727 pendingnodes -= seennodes
727 pendingnodes -= seennodes
728 seennodes |= pendingnodes
728 seennodes |= pendingnodes
729 return seenmarkers
729 return seenmarkers
730
730
731 def commonversion(versions):
731 def commonversion(versions):
732 """Return the newest version listed in both versions and our local formats.
732 """Return the newest version listed in both versions and our local formats.
733
733
734 Returns None if no common version exists.
734 Returns None if no common version exists.
735 """
735 """
736 versions.sort(reverse=True)
736 versions.sort(reverse=True)
737 # search for highest version known on both side
737 # search for highest version known on both side
738 for v in versions:
738 for v in versions:
739 if v in formats:
739 if v in formats:
740 return v
740 return v
741 return None
741 return None
742
742
743 # arbitrary picked to fit into 8K limit from HTTP server
743 # arbitrary picked to fit into 8K limit from HTTP server
744 # you have to take in account:
744 # you have to take in account:
745 # - the version header
745 # - the version header
746 # - the base85 encoding
746 # - the base85 encoding
747 _maxpayload = 5300
747 _maxpayload = 5300
748
748
749 def _pushkeyescape(markers):
749 def _pushkeyescape(markers):
750 """encode markers into a dict suitable for pushkey exchange
750 """encode markers into a dict suitable for pushkey exchange
751
751
752 - binary data is base85 encoded
752 - binary data is base85 encoded
753 - split in chunks smaller than 5300 bytes"""
753 - split in chunks smaller than 5300 bytes"""
754 keys = {}
754 keys = {}
755 parts = []
755 parts = []
756 currentlen = _maxpayload * 2 # ensure we create a new part
756 currentlen = _maxpayload * 2 # ensure we create a new part
757 for marker in markers:
757 for marker in markers:
758 nextdata = _fm0encodeonemarker(marker)
758 nextdata = _fm0encodeonemarker(marker)
759 if (len(nextdata) + currentlen > _maxpayload):
759 if (len(nextdata) + currentlen > _maxpayload):
760 currentpart = []
760 currentpart = []
761 currentlen = 0
761 currentlen = 0
762 parts.append(currentpart)
762 parts.append(currentpart)
763 currentpart.append(nextdata)
763 currentpart.append(nextdata)
764 currentlen += len(nextdata)
764 currentlen += len(nextdata)
765 for idx, part in enumerate(reversed(parts)):
765 for idx, part in enumerate(reversed(parts)):
766 data = ''.join([_pack('>B', _fm0version)] + part)
766 data = ''.join([_pack('>B', _fm0version)] + part)
767 keys['dump%i' % idx] = util.b85encode(data)
767 keys['dump%i' % idx] = util.b85encode(data)
768 return keys
768 return keys
769
769
770 def listmarkers(repo):
770 def listmarkers(repo):
771 """List markers over pushkey"""
771 """List markers over pushkey"""
772 if not repo.obsstore:
772 if not repo.obsstore:
773 return {}
773 return {}
774 return _pushkeyescape(sorted(repo.obsstore))
774 return _pushkeyescape(sorted(repo.obsstore))
775
775
776 def pushmarker(repo, key, old, new):
776 def pushmarker(repo, key, old, new):
777 """Push markers over pushkey"""
777 """Push markers over pushkey"""
778 if not key.startswith('dump'):
778 if not key.startswith('dump'):
779 repo.ui.warn(_('unknown key: %r') % key)
779 repo.ui.warn(_('unknown key: %r') % key)
780 return 0
780 return 0
781 if old:
781 if old:
782 repo.ui.warn(_('unexpected old value for %r') % key)
782 repo.ui.warn(_('unexpected old value for %r') % key)
783 return 0
783 return 0
784 data = util.b85decode(new)
784 data = util.b85decode(new)
785 lock = repo.lock()
785 lock = repo.lock()
786 try:
786 try:
787 tr = repo.transaction('pushkey: obsolete markers')
787 tr = repo.transaction('pushkey: obsolete markers')
788 try:
788 try:
789 repo.obsstore.mergemarkers(tr, data)
789 repo.obsstore.mergemarkers(tr, data)
790 tr.close()
790 tr.close()
791 return 1
791 return 1
792 finally:
792 finally:
793 tr.release()
793 tr.release()
794 finally:
794 finally:
795 lock.release()
795 lock.release()
796
796
797 def getmarkers(repo, nodes=None):
797 def getmarkers(repo, nodes=None):
798 """returns markers known in a repository
798 """returns markers known in a repository
799
799
800 If <nodes> is specified, only markers "relevant" to those nodes are are
800 If <nodes> is specified, only markers "relevant" to those nodes are are
801 returned"""
801 returned"""
802 if nodes is None:
802 if nodes is None:
803 rawmarkers = repo.obsstore
803 rawmarkers = repo.obsstore
804 else:
804 else:
805 rawmarkers = repo.obsstore.relevantmarkers(nodes)
805 rawmarkers = repo.obsstore.relevantmarkers(nodes)
806
806
807 for markerdata in rawmarkers:
807 for markerdata in rawmarkers:
808 yield marker(repo, markerdata)
808 yield marker(repo, markerdata)
809
809
810 def relevantmarkers(repo, node):
810 def relevantmarkers(repo, node):
811 """all obsolete markers relevant to some revision"""
811 """all obsolete markers relevant to some revision"""
812 for markerdata in repo.obsstore.relevantmarkers(node):
812 for markerdata in repo.obsstore.relevantmarkers(node):
813 yield marker(repo, markerdata)
813 yield marker(repo, markerdata)
814
814
815
815
816 def precursormarkers(ctx):
816 def precursormarkers(ctx):
817 """obsolete marker marking this changeset as a successors"""
817 """obsolete marker marking this changeset as a successors"""
818 for data in ctx.repo().obsstore.precursors.get(ctx.node(), ()):
818 for data in ctx.repo().obsstore.precursors.get(ctx.node(), ()):
819 yield marker(ctx.repo(), data)
819 yield marker(ctx.repo(), data)
820
820
821 def successormarkers(ctx):
821 def successormarkers(ctx):
822 """obsolete marker making this changeset obsolete"""
822 """obsolete marker making this changeset obsolete"""
823 for data in ctx.repo().obsstore.successors.get(ctx.node(), ()):
823 for data in ctx.repo().obsstore.successors.get(ctx.node(), ()):
824 yield marker(ctx.repo(), data)
824 yield marker(ctx.repo(), data)
825
825
826 def allsuccessors(obsstore, nodes, ignoreflags=0):
826 def allsuccessors(obsstore, nodes, ignoreflags=0):
827 """Yield node for every successor of <nodes>.
827 """Yield node for every successor of <nodes>.
828
828
829 Some successors may be unknown locally.
829 Some successors may be unknown locally.
830
830
831 This is a linear yield unsuited to detecting split changesets. It includes
831 This is a linear yield unsuited to detecting split changesets. It includes
832 initial nodes too."""
832 initial nodes too."""
833 remaining = set(nodes)
833 remaining = set(nodes)
834 seen = set(remaining)
834 seen = set(remaining)
835 while remaining:
835 while remaining:
836 current = remaining.pop()
836 current = remaining.pop()
837 yield current
837 yield current
838 for mark in obsstore.successors.get(current, ()):
838 for mark in obsstore.successors.get(current, ()):
839 # ignore marker flagged with specified flag
839 # ignore marker flagged with specified flag
840 if mark[2] & ignoreflags:
840 if mark[2] & ignoreflags:
841 continue
841 continue
842 for suc in mark[1]:
842 for suc in mark[1]:
843 if suc not in seen:
843 if suc not in seen:
844 seen.add(suc)
844 seen.add(suc)
845 remaining.add(suc)
845 remaining.add(suc)
846
846
847 def allprecursors(obsstore, nodes, ignoreflags=0):
847 def allprecursors(obsstore, nodes, ignoreflags=0):
848 """Yield node for every precursors of <nodes>.
848 """Yield node for every precursors of <nodes>.
849
849
850 Some precursors may be unknown locally.
850 Some precursors may be unknown locally.
851
851
852 This is a linear yield unsuited to detecting folded changesets. It includes
852 This is a linear yield unsuited to detecting folded changesets. It includes
853 initial nodes too."""
853 initial nodes too."""
854
854
855 remaining = set(nodes)
855 remaining = set(nodes)
856 seen = set(remaining)
856 seen = set(remaining)
857 while remaining:
857 while remaining:
858 current = remaining.pop()
858 current = remaining.pop()
859 yield current
859 yield current
860 for mark in obsstore.precursors.get(current, ()):
860 for mark in obsstore.precursors.get(current, ()):
861 # ignore marker flagged with specified flag
861 # ignore marker flagged with specified flag
862 if mark[2] & ignoreflags:
862 if mark[2] & ignoreflags:
863 continue
863 continue
864 suc = mark[0]
864 suc = mark[0]
865 if suc not in seen:
865 if suc not in seen:
866 seen.add(suc)
866 seen.add(suc)
867 remaining.add(suc)
867 remaining.add(suc)
868
868
869 def foreground(repo, nodes):
869 def foreground(repo, nodes):
870 """return all nodes in the "foreground" of other node
870 """return all nodes in the "foreground" of other node
871
871
872 The foreground of a revision is anything reachable using parent -> children
872 The foreground of a revision is anything reachable using parent -> children
873 or precursor -> successor relation. It is very similar to "descendant" but
873 or precursor -> successor relation. It is very similar to "descendant" but
874 augmented with obsolescence information.
874 augmented with obsolescence information.
875
875
876 Beware that possible obsolescence cycle may result if complex situation.
876 Beware that possible obsolescence cycle may result if complex situation.
877 """
877 """
878 repo = repo.unfiltered()
878 repo = repo.unfiltered()
879 foreground = set(repo.set('%ln::', nodes))
879 foreground = set(repo.set('%ln::', nodes))
880 if repo.obsstore:
880 if repo.obsstore:
881 # We only need this complicated logic if there is obsolescence
881 # We only need this complicated logic if there is obsolescence
882 # XXX will probably deserve an optimised revset.
882 # XXX will probably deserve an optimised revset.
883 nm = repo.changelog.nodemap
883 nm = repo.changelog.nodemap
884 plen = -1
884 plen = -1
885 # compute the whole set of successors or descendants
885 # compute the whole set of successors or descendants
886 while len(foreground) != plen:
886 while len(foreground) != plen:
887 plen = len(foreground)
887 plen = len(foreground)
888 succs = set(c.node() for c in foreground)
888 succs = set(c.node() for c in foreground)
889 mutable = [c.node() for c in foreground if c.mutable()]
889 mutable = [c.node() for c in foreground if c.mutable()]
890 succs.update(allsuccessors(repo.obsstore, mutable))
890 succs.update(allsuccessors(repo.obsstore, mutable))
891 known = (n for n in succs if n in nm)
891 known = (n for n in succs if n in nm)
892 foreground = set(repo.set('%ln::', known))
892 foreground = set(repo.set('%ln::', known))
893 return set(c.node() for c in foreground)
893 return set(c.node() for c in foreground)
894
894
895
895
896 def successorssets(repo, initialnode, cache=None):
896 def successorssets(repo, initialnode, cache=None):
897 """Return set of all latest successors of initial nodes
897 """Return set of all latest successors of initial nodes
898
898
899 The successors set of a changeset A are the group of revisions that succeed
899 The successors set of a changeset A are the group of revisions that succeed
900 A. It succeeds A as a consistent whole, each revision being only a partial
900 A. It succeeds A as a consistent whole, each revision being only a partial
901 replacement. The successors set contains non-obsolete changesets only.
901 replacement. The successors set contains non-obsolete changesets only.
902
902
903 This function returns the full list of successor sets which is why it
903 This function returns the full list of successor sets which is why it
904 returns a list of tuples and not just a single tuple. Each tuple is a valid
904 returns a list of tuples and not just a single tuple. Each tuple is a valid
905 successors set. Note that (A,) may be a valid successors set for changeset A
905 successors set. Note that (A,) may be a valid successors set for changeset A
906 (see below).
906 (see below).
907
907
908 In most cases, a changeset A will have a single element (e.g. the changeset
908 In most cases, a changeset A will have a single element (e.g. the changeset
909 A is replaced by A') in its successors set. Though, it is also common for a
909 A is replaced by A') in its successors set. Though, it is also common for a
910 changeset A to have no elements in its successor set (e.g. the changeset
910 changeset A to have no elements in its successor set (e.g. the changeset
911 has been pruned). Therefore, the returned list of successors sets will be
911 has been pruned). Therefore, the returned list of successors sets will be
912 [(A',)] or [], respectively.
912 [(A',)] or [], respectively.
913
913
914 When a changeset A is split into A' and B', however, it will result in a
914 When a changeset A is split into A' and B', however, it will result in a
915 successors set containing more than a single element, i.e. [(A',B')].
915 successors set containing more than a single element, i.e. [(A',B')].
916 Divergent changesets will result in multiple successors sets, i.e. [(A',),
916 Divergent changesets will result in multiple successors sets, i.e. [(A',),
917 (A'')].
917 (A'')].
918
918
919 If a changeset A is not obsolete, then it will conceptually have no
919 If a changeset A is not obsolete, then it will conceptually have no
920 successors set. To distinguish this from a pruned changeset, the successor
920 successors set. To distinguish this from a pruned changeset, the successor
921 set will contain itself only, i.e. [(A,)].
921 set will contain itself only, i.e. [(A,)].
922
922
923 Finally, successors unknown locally are considered to be pruned (obsoleted
923 Finally, successors unknown locally are considered to be pruned (obsoleted
924 without any successors).
924 without any successors).
925
925
926 The optional `cache` parameter is a dictionary that may contain precomputed
926 The optional `cache` parameter is a dictionary that may contain precomputed
927 successors sets. It is meant to reuse the computation of a previous call to
927 successors sets. It is meant to reuse the computation of a previous call to
928 `successorssets` when multiple calls are made at the same time. The cache
928 `successorssets` when multiple calls are made at the same time. The cache
929 dictionary is updated in place. The caller is responsible for its life
929 dictionary is updated in place. The caller is responsible for its life
930 span. Code that makes multiple calls to `successorssets` *must* use this
930 span. Code that makes multiple calls to `successorssets` *must* use this
931 cache mechanism or suffer terrible performance.
931 cache mechanism or suffer terrible performance.
932 """
932 """
933
933
934 succmarkers = repo.obsstore.successors
934 succmarkers = repo.obsstore.successors
935
935
936 # Stack of nodes we search successors sets for
936 # Stack of nodes we search successors sets for
937 toproceed = [initialnode]
937 toproceed = [initialnode]
938 # set version of above list for fast loop detection
938 # set version of above list for fast loop detection
939 # element added to "toproceed" must be added here
939 # element added to "toproceed" must be added here
940 stackedset = set(toproceed)
940 stackedset = set(toproceed)
941 if cache is None:
941 if cache is None:
942 cache = {}
942 cache = {}
943
943
944 # This while loop is the flattened version of a recursive search for
944 # This while loop is the flattened version of a recursive search for
945 # successors sets
945 # successors sets
946 #
946 #
947 # def successorssets(x):
947 # def successorssets(x):
948 # successors = directsuccessors(x)
948 # successors = directsuccessors(x)
949 # ss = [[]]
949 # ss = [[]]
950 # for succ in directsuccessors(x):
950 # for succ in directsuccessors(x):
951 # # product as in itertools cartesian product
951 # # product as in itertools cartesian product
952 # ss = product(ss, successorssets(succ))
952 # ss = product(ss, successorssets(succ))
953 # return ss
953 # return ss
954 #
954 #
955 # But we can not use plain recursive calls here:
955 # But we can not use plain recursive calls here:
956 # - that would blow the python call stack
956 # - that would blow the python call stack
957 # - obsolescence markers may have cycles, we need to handle them.
957 # - obsolescence markers may have cycles, we need to handle them.
958 #
958 #
959 # The `toproceed` list act as our call stack. Every node we search
959 # The `toproceed` list act as our call stack. Every node we search
960 # successors set for are stacked there.
960 # successors set for are stacked there.
961 #
961 #
962 # The `stackedset` is set version of this stack used to check if a node is
962 # The `stackedset` is set version of this stack used to check if a node is
963 # already stacked. This check is used to detect cycles and prevent infinite
963 # already stacked. This check is used to detect cycles and prevent infinite
964 # loop.
964 # loop.
965 #
965 #
966 # successors set of all nodes are stored in the `cache` dictionary.
966 # successors set of all nodes are stored in the `cache` dictionary.
967 #
967 #
968 # After this while loop ends we use the cache to return the successors sets
968 # After this while loop ends we use the cache to return the successors sets
969 # for the node requested by the caller.
969 # for the node requested by the caller.
970 while toproceed:
970 while toproceed:
971 # Every iteration tries to compute the successors sets of the topmost
971 # Every iteration tries to compute the successors sets of the topmost
972 # node of the stack: CURRENT.
972 # node of the stack: CURRENT.
973 #
973 #
974 # There are four possible outcomes:
974 # There are four possible outcomes:
975 #
975 #
976 # 1) We already know the successors sets of CURRENT:
976 # 1) We already know the successors sets of CURRENT:
977 # -> mission accomplished, pop it from the stack.
977 # -> mission accomplished, pop it from the stack.
978 # 2) Node is not obsolete:
978 # 2) Node is not obsolete:
979 # -> the node is its own successors sets. Add it to the cache.
979 # -> the node is its own successors sets. Add it to the cache.
980 # 3) We do not know successors set of direct successors of CURRENT:
980 # 3) We do not know successors set of direct successors of CURRENT:
981 # -> We add those successors to the stack.
981 # -> We add those successors to the stack.
982 # 4) We know successors sets of all direct successors of CURRENT:
982 # 4) We know successors sets of all direct successors of CURRENT:
983 # -> We can compute CURRENT successors set and add it to the
983 # -> We can compute CURRENT successors set and add it to the
984 # cache.
984 # cache.
985 #
985 #
986 current = toproceed[-1]
986 current = toproceed[-1]
987 if current in cache:
987 if current in cache:
988 # case (1): We already know the successors sets
988 # case (1): We already know the successors sets
989 stackedset.remove(toproceed.pop())
989 stackedset.remove(toproceed.pop())
990 elif current not in succmarkers:
990 elif current not in succmarkers:
991 # case (2): The node is not obsolete.
991 # case (2): The node is not obsolete.
992 if current in repo:
992 if current in repo:
993 # We have a valid last successors.
993 # We have a valid last successors.
994 cache[current] = [(current,)]
994 cache[current] = [(current,)]
995 else:
995 else:
996 # Final obsolete version is unknown locally.
996 # Final obsolete version is unknown locally.
997 # Do not count that as a valid successors
997 # Do not count that as a valid successors
998 cache[current] = []
998 cache[current] = []
999 else:
999 else:
1000 # cases (3) and (4)
1000 # cases (3) and (4)
1001 #
1001 #
1002 # We proceed in two phases. Phase 1 aims to distinguish case (3)
1002 # We proceed in two phases. Phase 1 aims to distinguish case (3)
1003 # from case (4):
1003 # from case (4):
1004 #
1004 #
1005 # For each direct successors of CURRENT, we check whether its
1005 # For each direct successors of CURRENT, we check whether its
1006 # successors sets are known. If they are not, we stack the
1006 # successors sets are known. If they are not, we stack the
1007 # unknown node and proceed to the next iteration of the while
1007 # unknown node and proceed to the next iteration of the while
1008 # loop. (case 3)
1008 # loop. (case 3)
1009 #
1009 #
1010 # During this step, we may detect obsolescence cycles: a node
1010 # During this step, we may detect obsolescence cycles: a node
1011 # with unknown successors sets but already in the call stack.
1011 # with unknown successors sets but already in the call stack.
1012 # In such a situation, we arbitrary set the successors sets of
1012 # In such a situation, we arbitrary set the successors sets of
1013 # the node to nothing (node pruned) to break the cycle.
1013 # the node to nothing (node pruned) to break the cycle.
1014 #
1014 #
1015 # If no break was encountered we proceed to phase 2.
1015 # If no break was encountered we proceed to phase 2.
1016 #
1016 #
1017 # Phase 2 computes successors sets of CURRENT (case 4); see details
1017 # Phase 2 computes successors sets of CURRENT (case 4); see details
1018 # in phase 2 itself.
1018 # in phase 2 itself.
1019 #
1019 #
1020 # Note the two levels of iteration in each phase.
1020 # Note the two levels of iteration in each phase.
1021 # - The first one handles obsolescence markers using CURRENT as
1021 # - The first one handles obsolescence markers using CURRENT as
1022 # precursor (successors markers of CURRENT).
1022 # precursor (successors markers of CURRENT).
1023 #
1023 #
1024 # Having multiple entry here means divergence.
1024 # Having multiple entry here means divergence.
1025 #
1025 #
1026 # - The second one handles successors defined in each marker.
1026 # - The second one handles successors defined in each marker.
1027 #
1027 #
1028 # Having none means pruned node, multiple successors means split,
1028 # Having none means pruned node, multiple successors means split,
1029 # single successors are standard replacement.
1029 # single successors are standard replacement.
1030 #
1030 #
1031 for mark in sorted(succmarkers[current]):
1031 for mark in sorted(succmarkers[current]):
1032 for suc in mark[1]:
1032 for suc in mark[1]:
1033 if suc not in cache:
1033 if suc not in cache:
1034 if suc in stackedset:
1034 if suc in stackedset:
1035 # cycle breaking
1035 # cycle breaking
1036 cache[suc] = []
1036 cache[suc] = []
1037 else:
1037 else:
1038 # case (3) If we have not computed successors sets
1038 # case (3) If we have not computed successors sets
1039 # of one of those successors we add it to the
1039 # of one of those successors we add it to the
1040 # `toproceed` stack and stop all work for this
1040 # `toproceed` stack and stop all work for this
1041 # iteration.
1041 # iteration.
1042 toproceed.append(suc)
1042 toproceed.append(suc)
1043 stackedset.add(suc)
1043 stackedset.add(suc)
1044 break
1044 break
1045 else:
1045 else:
1046 continue
1046 continue
1047 break
1047 break
1048 else:
1048 else:
1049 # case (4): we know all successors sets of all direct
1049 # case (4): we know all successors sets of all direct
1050 # successors
1050 # successors
1051 #
1051 #
1052 # Successors set contributed by each marker depends on the
1052 # Successors set contributed by each marker depends on the
1053 # successors sets of all its "successors" node.
1053 # successors sets of all its "successors" node.
1054 #
1054 #
1055 # Each different marker is a divergence in the obsolescence
1055 # Each different marker is a divergence in the obsolescence
1056 # history. It contributes successors sets distinct from other
1056 # history. It contributes successors sets distinct from other
1057 # markers.
1057 # markers.
1058 #
1058 #
1059 # Within a marker, a successor may have divergent successors
1059 # Within a marker, a successor may have divergent successors
1060 # sets. In such a case, the marker will contribute multiple
1060 # sets. In such a case, the marker will contribute multiple
1061 # divergent successors sets. If multiple successors have
1061 # divergent successors sets. If multiple successors have
1062 # divergent successors sets, a Cartesian product is used.
1062 # divergent successors sets, a Cartesian product is used.
1063 #
1063 #
1064 # At the end we post-process successors sets to remove
1064 # At the end we post-process successors sets to remove
1065 # duplicated entry and successors set that are strict subset of
1065 # duplicated entry and successors set that are strict subset of
1066 # another one.
1066 # another one.
1067 succssets = []
1067 succssets = []
1068 for mark in sorted(succmarkers[current]):
1068 for mark in sorted(succmarkers[current]):
1069 # successors sets contributed by this marker
1069 # successors sets contributed by this marker
1070 markss = [[]]
1070 markss = [[]]
1071 for suc in mark[1]:
1071 for suc in mark[1]:
1072 # cardinal product with previous successors
1072 # cardinal product with previous successors
1073 productresult = []
1073 productresult = []
1074 for prefix in markss:
1074 for prefix in markss:
1075 for suffix in cache[suc]:
1075 for suffix in cache[suc]:
1076 newss = list(prefix)
1076 newss = list(prefix)
1077 for part in suffix:
1077 for part in suffix:
1078 # do not duplicated entry in successors set
1078 # do not duplicated entry in successors set
1079 # first entry wins.
1079 # first entry wins.
1080 if part not in newss:
1080 if part not in newss:
1081 newss.append(part)
1081 newss.append(part)
1082 productresult.append(newss)
1082 productresult.append(newss)
1083 markss = productresult
1083 markss = productresult
1084 succssets.extend(markss)
1084 succssets.extend(markss)
1085 # remove duplicated and subset
1085 # remove duplicated and subset
1086 seen = []
1086 seen = []
1087 final = []
1087 final = []
1088 candidate = sorted(((set(s), s) for s in succssets if s),
1088 candidate = sorted(((set(s), s) for s in succssets if s),
1089 key=lambda x: len(x[1]), reverse=True)
1089 key=lambda x: len(x[1]), reverse=True)
1090 for setversion, listversion in candidate:
1090 for setversion, listversion in candidate:
1091 for seenset in seen:
1091 for seenset in seen:
1092 if setversion.issubset(seenset):
1092 if setversion.issubset(seenset):
1093 break
1093 break
1094 else:
1094 else:
1095 final.append(listversion)
1095 final.append(listversion)
1096 seen.append(setversion)
1096 seen.append(setversion)
1097 final.reverse() # put small successors set first
1097 final.reverse() # put small successors set first
1098 cache[current] = final
1098 cache[current] = final
1099 return cache[initialnode]
1099 return cache[initialnode]
1100
1100
1101 # mapping of 'set-name' -> <function to compute this set>
1101 # mapping of 'set-name' -> <function to compute this set>
1102 cachefuncs = {}
1102 cachefuncs = {}
1103 def cachefor(name):
1103 def cachefor(name):
1104 """Decorator to register a function as computing the cache for a set"""
1104 """Decorator to register a function as computing the cache for a set"""
1105 def decorator(func):
1105 def decorator(func):
1106 assert name not in cachefuncs
1106 assert name not in cachefuncs
1107 cachefuncs[name] = func
1107 cachefuncs[name] = func
1108 return func
1108 return func
1109 return decorator
1109 return decorator
1110
1110
1111 def getrevs(repo, name):
1111 def getrevs(repo, name):
1112 """Return the set of revision that belong to the <name> set
1112 """Return the set of revision that belong to the <name> set
1113
1113
1114 Such access may compute the set and cache it for future use"""
1114 Such access may compute the set and cache it for future use"""
1115 repo = repo.unfiltered()
1115 repo = repo.unfiltered()
1116 if not repo.obsstore:
1116 if not repo.obsstore:
1117 return frozenset()
1117 return frozenset()
1118 if name not in repo.obsstore.caches:
1118 if name not in repo.obsstore.caches:
1119 repo.obsstore.caches[name] = cachefuncs[name](repo)
1119 repo.obsstore.caches[name] = cachefuncs[name](repo)
1120 return repo.obsstore.caches[name]
1120 return repo.obsstore.caches[name]
1121
1121
1122 # To be simple we need to invalidate obsolescence cache when:
1122 # To be simple we need to invalidate obsolescence cache when:
1123 #
1123 #
1124 # - new changeset is added:
1124 # - new changeset is added:
1125 # - public phase is changed
1125 # - public phase is changed
1126 # - obsolescence marker are added
1126 # - obsolescence marker are added
1127 # - strip is used a repo
1127 # - strip is used a repo
1128 def clearobscaches(repo):
1128 def clearobscaches(repo):
1129 """Remove all obsolescence related cache from a repo
1129 """Remove all obsolescence related cache from a repo
1130
1130
1131 This remove all cache in obsstore is the obsstore already exist on the
1131 This remove all cache in obsstore is the obsstore already exist on the
1132 repo.
1132 repo.
1133
1133
1134 (We could be smarter here given the exact event that trigger the cache
1134 (We could be smarter here given the exact event that trigger the cache
1135 clearing)"""
1135 clearing)"""
1136 # only clear cache is there is obsstore data in this repo
1136 # only clear cache is there is obsstore data in this repo
1137 if 'obsstore' in repo._filecache:
1137 if 'obsstore' in repo._filecache:
1138 repo.obsstore.caches.clear()
1138 repo.obsstore.caches.clear()
1139
1139
1140 @cachefor('obsolete')
1140 @cachefor('obsolete')
1141 def _computeobsoleteset(repo):
1141 def _computeobsoleteset(repo):
1142 """the set of obsolete revisions"""
1142 """the set of obsolete revisions"""
1143 obs = set()
1143 obs = set()
1144 getnode = repo.changelog.node
1144 getnode = repo.changelog.node
1145 notpublic = repo._phasecache.getrevset(repo, (phases.draft, phases.secret))
1145 notpublic = repo._phasecache.getrevset(repo, (phases.draft, phases.secret))
1146 for r in notpublic:
1146 for r in notpublic:
1147 if getnode(r) in repo.obsstore.successors:
1147 if getnode(r) in repo.obsstore.successors:
1148 obs.add(r)
1148 obs.add(r)
1149 return obs
1149 return obs
1150
1150
1151 @cachefor('unstable')
1151 @cachefor('unstable')
1152 def _computeunstableset(repo):
1152 def _computeunstableset(repo):
1153 """the set of non obsolete revisions with obsolete parents"""
1153 """the set of non obsolete revisions with obsolete parents"""
1154 revs = [(ctx.rev(), ctx) for ctx in
1154 revs = [(ctx.rev(), ctx) for ctx in
1155 repo.set('(not public()) and (not obsolete())')]
1155 repo.set('(not public()) and (not obsolete())')]
1156 revs.sort(key=lambda x:x[0])
1156 revs.sort(key=lambda x:x[0])
1157 unstable = set()
1157 unstable = set()
1158 for rev, ctx in revs:
1158 for rev, ctx in revs:
1159 # A rev is unstable if one of its parent is obsolete or unstable
1159 # A rev is unstable if one of its parent is obsolete or unstable
1160 # this works since we traverse following growing rev order
1160 # this works since we traverse following growing rev order
1161 if any((x.obsolete() or (x.rev() in unstable))
1161 if any((x.obsolete() or (x.rev() in unstable))
1162 for x in ctx.parents()):
1162 for x in ctx.parents()):
1163 unstable.add(rev)
1163 unstable.add(rev)
1164 return unstable
1164 return unstable
1165
1165
1166 @cachefor('suspended')
1166 @cachefor('suspended')
1167 def _computesuspendedset(repo):
1167 def _computesuspendedset(repo):
1168 """the set of obsolete parents with non obsolete descendants"""
1168 """the set of obsolete parents with non obsolete descendants"""
1169 suspended = repo.changelog.ancestors(getrevs(repo, 'unstable'))
1169 suspended = repo.changelog.ancestors(getrevs(repo, 'unstable'))
1170 return set(r for r in getrevs(repo, 'obsolete') if r in suspended)
1170 return set(r for r in getrevs(repo, 'obsolete') if r in suspended)
1171
1171
1172 @cachefor('extinct')
1172 @cachefor('extinct')
1173 def _computeextinctset(repo):
1173 def _computeextinctset(repo):
1174 """the set of obsolete parents without non obsolete descendants"""
1174 """the set of obsolete parents without non obsolete descendants"""
1175 return getrevs(repo, 'obsolete') - getrevs(repo, 'suspended')
1175 return getrevs(repo, 'obsolete') - getrevs(repo, 'suspended')
1176
1176
1177
1177
1178 @cachefor('bumped')
1178 @cachefor('bumped')
1179 def _computebumpedset(repo):
1179 def _computebumpedset(repo):
1180 """the set of revs trying to obsolete public revisions"""
1180 """the set of revs trying to obsolete public revisions"""
1181 bumped = set()
1181 bumped = set()
1182 # util function (avoid attribute lookup in the loop)
1182 # util function (avoid attribute lookup in the loop)
1183 phase = repo._phasecache.phase # would be faster to grab the full list
1183 phase = repo._phasecache.phase # would be faster to grab the full list
1184 public = phases.public
1184 public = phases.public
1185 cl = repo.changelog
1185 cl = repo.changelog
1186 torev = cl.nodemap.get
1186 torev = cl.nodemap.get
1187 for ctx in repo.set('(not public()) and (not obsolete())'):
1187 for ctx in repo.set('(not public()) and (not obsolete())'):
1188 rev = ctx.rev()
1188 rev = ctx.rev()
1189 # We only evaluate mutable, non-obsolete revision
1189 # We only evaluate mutable, non-obsolete revision
1190 node = ctx.node()
1190 node = ctx.node()
1191 # (future) A cache of precursors may worth if split is very common
1191 # (future) A cache of precursors may worth if split is very common
1192 for pnode in allprecursors(repo.obsstore, [node],
1192 for pnode in allprecursors(repo.obsstore, [node],
1193 ignoreflags=bumpedfix):
1193 ignoreflags=bumpedfix):
1194 prev = torev(pnode) # unfiltered! but so is phasecache
1194 prev = torev(pnode) # unfiltered! but so is phasecache
1195 if (prev is not None) and (phase(repo, prev) <= public):
1195 if (prev is not None) and (phase(repo, prev) <= public):
1196 # we have a public precursor
1196 # we have a public precursor
1197 bumped.add(rev)
1197 bumped.add(rev)
1198 break # Next draft!
1198 break # Next draft!
1199 return bumped
1199 return bumped
1200
1200
1201 @cachefor('divergent')
1201 @cachefor('divergent')
1202 def _computedivergentset(repo):
1202 def _computedivergentset(repo):
1203 """the set of rev that compete to be the final successors of some revision.
1203 """the set of rev that compete to be the final successors of some revision.
1204 """
1204 """
1205 divergent = set()
1205 divergent = set()
1206 obsstore = repo.obsstore
1206 obsstore = repo.obsstore
1207 newermap = {}
1207 newermap = {}
1208 for ctx in repo.set('(not public()) - obsolete()'):
1208 for ctx in repo.set('(not public()) - obsolete()'):
1209 mark = obsstore.precursors.get(ctx.node(), ())
1209 mark = obsstore.precursors.get(ctx.node(), ())
1210 toprocess = set(mark)
1210 toprocess = set(mark)
1211 seen = set()
1211 seen = set()
1212 while toprocess:
1212 while toprocess:
1213 prec = toprocess.pop()[0]
1213 prec = toprocess.pop()[0]
1214 if prec in seen:
1214 if prec in seen:
1215 continue # emergency cycle hanging prevention
1215 continue # emergency cycle hanging prevention
1216 seen.add(prec)
1216 seen.add(prec)
1217 if prec not in newermap:
1217 if prec not in newermap:
1218 successorssets(repo, prec, newermap)
1218 successorssets(repo, prec, newermap)
1219 newer = [n for n in newermap[prec] if n]
1219 newer = [n for n in newermap[prec] if n]
1220 if len(newer) > 1:
1220 if len(newer) > 1:
1221 divergent.add(ctx.rev())
1221 divergent.add(ctx.rev())
1222 break
1222 break
1223 toprocess.update(obsstore.precursors.get(prec, ()))
1223 toprocess.update(obsstore.precursors.get(prec, ()))
1224 return divergent
1224 return divergent
1225
1225
1226
1226
1227 def createmarkers(repo, relations, flag=0, date=None, metadata=None,
1227 def createmarkers(repo, relations, flag=0, date=None, metadata=None,
1228 operation=None):
1228 operation=None):
1229 """Add obsolete markers between changesets in a repo
1229 """Add obsolete markers between changesets in a repo
1230
1230
1231 <relations> must be an iterable of (<old>, (<new>, ...)[,{metadata}])
1231 <relations> must be an iterable of (<old>, (<new>, ...)[,{metadata}])
1232 tuple. `old` and `news` are changectx. metadata is an optional dictionary
1232 tuple. `old` and `news` are changectx. metadata is an optional dictionary
1233 containing metadata for this marker only. It is merged with the global
1233 containing metadata for this marker only. It is merged with the global
1234 metadata specified through the `metadata` argument of this function,
1234 metadata specified through the `metadata` argument of this function,
1235
1235
1236 Trying to obsolete a public changeset will raise an exception.
1236 Trying to obsolete a public changeset will raise an exception.
1237
1237
1238 Current user and date are used except if specified otherwise in the
1238 Current user and date are used except if specified otherwise in the
1239 metadata attribute.
1239 metadata attribute.
1240
1240
1241 This function operates within a transaction of its own, but does
1241 This function operates within a transaction of its own, but does
1242 not take any lock on the repo.
1242 not take any lock on the repo.
1243 """
1243 """
1244 # prepare metadata
1244 # prepare metadata
1245 if metadata is None:
1245 if metadata is None:
1246 metadata = {}
1246 metadata = {}
1247 if 'user' not in metadata:
1247 if 'user' not in metadata:
1248 metadata['user'] = repo.ui.username()
1248 metadata['user'] = repo.ui.username()
1249 if operation:
1249 useoperation = repo.ui.configbool('experimental',
1250 'evolution.track-operation',
1251 False)
1252 if useoperation and operation:
1250 metadata['operation'] = operation
1253 metadata['operation'] = operation
1251 tr = repo.transaction('add-obsolescence-marker')
1254 tr = repo.transaction('add-obsolescence-marker')
1252 try:
1255 try:
1253 markerargs = []
1256 markerargs = []
1254 for rel in relations:
1257 for rel in relations:
1255 prec = rel[0]
1258 prec = rel[0]
1256 sucs = rel[1]
1259 sucs = rel[1]
1257 localmetadata = metadata.copy()
1260 localmetadata = metadata.copy()
1258 if 2 < len(rel):
1261 if 2 < len(rel):
1259 localmetadata.update(rel[2])
1262 localmetadata.update(rel[2])
1260
1263
1261 if not prec.mutable():
1264 if not prec.mutable():
1262 raise error.Abort(_("cannot obsolete public changeset: %s")
1265 raise error.Abort(_("cannot obsolete public changeset: %s")
1263 % prec,
1266 % prec,
1264 hint="see 'hg help phases' for details")
1267 hint="see 'hg help phases' for details")
1265 nprec = prec.node()
1268 nprec = prec.node()
1266 nsucs = tuple(s.node() for s in sucs)
1269 nsucs = tuple(s.node() for s in sucs)
1267 npare = None
1270 npare = None
1268 if not nsucs:
1271 if not nsucs:
1269 npare = tuple(p.node() for p in prec.parents())
1272 npare = tuple(p.node() for p in prec.parents())
1270 if nprec in nsucs:
1273 if nprec in nsucs:
1271 raise error.Abort(_("changeset %s cannot obsolete itself")
1274 raise error.Abort(_("changeset %s cannot obsolete itself")
1272 % prec)
1275 % prec)
1273
1276
1274 # Creating the marker causes the hidden cache to become invalid,
1277 # Creating the marker causes the hidden cache to become invalid,
1275 # which causes recomputation when we ask for prec.parents() above.
1278 # which causes recomputation when we ask for prec.parents() above.
1276 # Resulting in n^2 behavior. So let's prepare all of the args
1279 # Resulting in n^2 behavior. So let's prepare all of the args
1277 # first, then create the markers.
1280 # first, then create the markers.
1278 markerargs.append((nprec, nsucs, npare, localmetadata))
1281 markerargs.append((nprec, nsucs, npare, localmetadata))
1279
1282
1280 for args in markerargs:
1283 for args in markerargs:
1281 nprec, nsucs, npare, localmetadata = args
1284 nprec, nsucs, npare, localmetadata = args
1282 repo.obsstore.create(tr, nprec, nsucs, flag, parents=npare,
1285 repo.obsstore.create(tr, nprec, nsucs, flag, parents=npare,
1283 date=date, metadata=localmetadata)
1286 date=date, metadata=localmetadata)
1284 repo.filteredrevcache.clear()
1287 repo.filteredrevcache.clear()
1285 tr.close()
1288 tr.close()
1286 finally:
1289 finally:
1287 tr.release()
1290 tr.release()
@@ -1,576 +1,578 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 Enable obsolete
3 Enable obsolete
4
4
5 $ cat >> $HGRCPATH << EOF
5 $ cat >> $HGRCPATH << EOF
6 > [ui]
6 > [ui]
7 > logtemplate= {rev}:{node|short} {desc|firstline}
7 > logtemplate= {rev}:{node|short} {desc|firstline}
8 > [phases]
8 > [phases]
9 > publish=False
9 > publish=False
10 > [experimental]
10 > [experimental]
11 > evolution=createmarkers,allowunstable
11 > evolution=createmarkers,allowunstable
12 > [extensions]
12 > [extensions]
13 > histedit=
13 > histedit=
14 > rebase=
14 > rebase=
15 > EOF
15 > EOF
16
16
17 Test that histedit learns about obsolescence not stored in histedit state
17 Test that histedit learns about obsolescence not stored in histedit state
18 $ hg init boo
18 $ hg init boo
19 $ cd boo
19 $ cd boo
20 $ echo a > a
20 $ echo a > a
21 $ hg ci -Am a
21 $ hg ci -Am a
22 adding a
22 adding a
23 $ echo a > b
23 $ echo a > b
24 $ echo a > c
24 $ echo a > c
25 $ echo a > c
25 $ echo a > c
26 $ hg ci -Am b
26 $ hg ci -Am b
27 adding b
27 adding b
28 adding c
28 adding c
29 $ echo a > d
29 $ echo a > d
30 $ hg ci -Am c
30 $ hg ci -Am c
31 adding d
31 adding d
32 $ echo "pick `hg log -r 0 -T '{node|short}'`" > plan
32 $ echo "pick `hg log -r 0 -T '{node|short}'`" > plan
33 $ echo "pick `hg log -r 2 -T '{node|short}'`" >> plan
33 $ echo "pick `hg log -r 2 -T '{node|short}'`" >> plan
34 $ echo "edit `hg log -r 1 -T '{node|short}'`" >> plan
34 $ echo "edit `hg log -r 1 -T '{node|short}'`" >> plan
35 $ hg histedit -r 'all()' --commands plan
35 $ hg histedit -r 'all()' --commands plan
36 Editing (1b2d564fad96), you may commit or record as needed now.
36 Editing (1b2d564fad96), you may commit or record as needed now.
37 (hg histedit --continue to resume)
37 (hg histedit --continue to resume)
38 [1]
38 [1]
39 $ hg st
39 $ hg st
40 A b
40 A b
41 A c
41 A c
42 ? plan
42 ? plan
43 $ hg commit --amend b
43 $ hg commit --amend b
44 $ hg histedit --continue
44 $ hg histedit --continue
45 $ hg log -G
45 $ hg log -G
46 @ 6:46abc7c4d873 b
46 @ 6:46abc7c4d873 b
47 |
47 |
48 o 5:49d44ab2be1b c
48 o 5:49d44ab2be1b c
49 |
49 |
50 o 0:cb9a9f314b8b a
50 o 0:cb9a9f314b8b a
51
51
52 $ hg debugobsolete
52 $ hg debugobsolete
53 e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf 49d44ab2be1b67a79127568a67c9c99430633b48 0 (*) {'operation': 'amend', 'user': 'test'} (glob)
53 e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf 49d44ab2be1b67a79127568a67c9c99430633b48 0 (*) {'user': 'test'} (glob)
54 3e30a45cf2f719e96ab3922dfe039cfd047956ce 0 {e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf} (*) {'operation': 'amend', 'user': 'test'} (glob)
54 3e30a45cf2f719e96ab3922dfe039cfd047956ce 0 {e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf} (*) {'user': 'test'} (glob)
55 1b2d564fad96311b45362f17c2aa855150efb35f 46abc7c4d8738e8563e577f7889e1b6db3da4199 0 (*) {'operation': 'histedit', 'user': 'test'} (glob)
55 1b2d564fad96311b45362f17c2aa855150efb35f 46abc7c4d8738e8563e577f7889e1b6db3da4199 0 (*) {'user': 'test'} (glob)
56 114f4176969ef342759a8a57e6bccefc4234829b 49d44ab2be1b67a79127568a67c9c99430633b48 0 (*) {'operation': 'histedit', 'user': 'test'} (glob)
56 114f4176969ef342759a8a57e6bccefc4234829b 49d44ab2be1b67a79127568a67c9c99430633b48 0 (*) {'user': 'test'} (glob)
57
57
58 With some node gone missing during the edit.
58 With some node gone missing during the edit.
59
59
60 $ echo "pick `hg log -r 0 -T '{node|short}'`" > plan
60 $ echo "pick `hg log -r 0 -T '{node|short}'`" > plan
61 $ echo "pick `hg log -r 6 -T '{node|short}'`" >> plan
61 $ echo "pick `hg log -r 6 -T '{node|short}'`" >> plan
62 $ echo "edit `hg log -r 5 -T '{node|short}'`" >> plan
62 $ echo "edit `hg log -r 5 -T '{node|short}'`" >> plan
63 $ hg histedit -r 'all()' --commands plan
63 $ hg histedit -r 'all()' --commands plan
64 Editing (49d44ab2be1b), you may commit or record as needed now.
64 Editing (49d44ab2be1b), you may commit or record as needed now.
65 (hg histedit --continue to resume)
65 (hg histedit --continue to resume)
66 [1]
66 [1]
67 $ hg st
67 $ hg st
68 A b
68 A b
69 A d
69 A d
70 ? plan
70 ? plan
71 $ hg commit --amend -X . -m XXXXXX
71 $ hg commit --amend -X . -m XXXXXX
72 $ hg commit --amend -X . -m b2
72 $ hg commit --amend -X . -m b2
73 $ hg --hidden --config extensions.strip= strip 'desc(XXXXXX)' --no-backup
73 $ hg --hidden --config extensions.strip= strip 'desc(XXXXXX)' --no-backup
74 $ hg histedit --continue
74 $ hg histedit --continue
75 $ hg log -G
75 $ hg log -G
76 @ 9:273c1f3b8626 c
76 @ 9:273c1f3b8626 c
77 |
77 |
78 o 8:aba7da937030 b2
78 o 8:aba7da937030 b2
79 |
79 |
80 o 0:cb9a9f314b8b a
80 o 0:cb9a9f314b8b a
81
81
82 $ hg debugobsolete
82 $ hg debugobsolete
83 e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf 49d44ab2be1b67a79127568a67c9c99430633b48 0 (*) {'operation': 'amend', 'user': 'test'} (glob)
83 e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf 49d44ab2be1b67a79127568a67c9c99430633b48 0 (*) {'user': 'test'} (glob)
84 3e30a45cf2f719e96ab3922dfe039cfd047956ce 0 {e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf} (*) {'operation': 'amend', 'user': 'test'} (glob)
84 3e30a45cf2f719e96ab3922dfe039cfd047956ce 0 {e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf} (*) {'user': 'test'} (glob)
85 1b2d564fad96311b45362f17c2aa855150efb35f 46abc7c4d8738e8563e577f7889e1b6db3da4199 0 (*) {'operation': 'histedit', 'user': 'test'} (glob)
85 1b2d564fad96311b45362f17c2aa855150efb35f 46abc7c4d8738e8563e577f7889e1b6db3da4199 0 (*) {'user': 'test'} (glob)
86 114f4176969ef342759a8a57e6bccefc4234829b 49d44ab2be1b67a79127568a67c9c99430633b48 0 (*) {'operation': 'histedit', 'user': 'test'} (glob)
86 114f4176969ef342759a8a57e6bccefc4234829b 49d44ab2be1b67a79127568a67c9c99430633b48 0 (*) {'user': 'test'} (glob)
87 76f72745eac0643d16530e56e2f86e36e40631f1 2ca853e48edbd6453a0674dc0fe28a0974c51b9c 0 (*) {'operation': 'amend', 'user': 'test'} (glob)
87 76f72745eac0643d16530e56e2f86e36e40631f1 2ca853e48edbd6453a0674dc0fe28a0974c51b9c 0 (*) {'user': 'test'} (glob)
88 2ca853e48edbd6453a0674dc0fe28a0974c51b9c aba7da93703075eec9fb1dbaf143ff2bc1c49d46 0 (*) {'operation': 'amend', 'user': 'test'} (glob)
88 2ca853e48edbd6453a0674dc0fe28a0974c51b9c aba7da93703075eec9fb1dbaf143ff2bc1c49d46 0 (*) {'user': 'test'} (glob)
89 49d44ab2be1b67a79127568a67c9c99430633b48 273c1f3b86267ed3ec684bb13af1fa4d6ba56e02 0 (*) {'operation': 'histedit', 'user': 'test'} (glob)
89 49d44ab2be1b67a79127568a67c9c99430633b48 273c1f3b86267ed3ec684bb13af1fa4d6ba56e02 0 (*) {'user': 'test'} (glob)
90 46abc7c4d8738e8563e577f7889e1b6db3da4199 aba7da93703075eec9fb1dbaf143ff2bc1c49d46 0 (*) {'operation': 'histedit', 'user': 'test'} (glob)
90 46abc7c4d8738e8563e577f7889e1b6db3da4199 aba7da93703075eec9fb1dbaf143ff2bc1c49d46 0 (*) {'user': 'test'} (glob)
91 $ cd ..
91 $ cd ..
92
92
93 Base setup for the rest of the testing
93 Base setup for the rest of the testing
94 ======================================
94 ======================================
95
95
96 $ hg init base
96 $ hg init base
97 $ cd base
97 $ cd base
98
98
99 $ for x in a b c d e f ; do
99 $ for x in a b c d e f ; do
100 > echo $x > $x
100 > echo $x > $x
101 > hg add $x
101 > hg add $x
102 > hg ci -m $x
102 > hg ci -m $x
103 > done
103 > done
104
104
105 $ hg log --graph
105 $ hg log --graph
106 @ 5:652413bf663e f
106 @ 5:652413bf663e f
107 |
107 |
108 o 4:e860deea161a e
108 o 4:e860deea161a e
109 |
109 |
110 o 3:055a42cdd887 d
110 o 3:055a42cdd887 d
111 |
111 |
112 o 2:177f92b77385 c
112 o 2:177f92b77385 c
113 |
113 |
114 o 1:d2ae7f538514 b
114 o 1:d2ae7f538514 b
115 |
115 |
116 o 0:cb9a9f314b8b a
116 o 0:cb9a9f314b8b a
117
117
118
118
119 $ HGEDITOR=cat hg histedit 1
119 $ HGEDITOR=cat hg histedit 1
120 pick d2ae7f538514 1 b
120 pick d2ae7f538514 1 b
121 pick 177f92b77385 2 c
121 pick 177f92b77385 2 c
122 pick 055a42cdd887 3 d
122 pick 055a42cdd887 3 d
123 pick e860deea161a 4 e
123 pick e860deea161a 4 e
124 pick 652413bf663e 5 f
124 pick 652413bf663e 5 f
125
125
126 # Edit history between d2ae7f538514 and 652413bf663e
126 # Edit history between d2ae7f538514 and 652413bf663e
127 #
127 #
128 # Commits are listed from least to most recent
128 # Commits are listed from least to most recent
129 #
129 #
130 # You can reorder changesets by reordering the lines
130 # You can reorder changesets by reordering the lines
131 #
131 #
132 # Commands:
132 # Commands:
133 #
133 #
134 # e, edit = use commit, but stop for amending
134 # e, edit = use commit, but stop for amending
135 # m, mess = edit commit message without changing commit content
135 # m, mess = edit commit message without changing commit content
136 # p, pick = use commit
136 # p, pick = use commit
137 # d, drop = remove commit from history
137 # d, drop = remove commit from history
138 # f, fold = use commit, but combine it with the one above
138 # f, fold = use commit, but combine it with the one above
139 # r, roll = like fold, but discard this commit's description and date
139 # r, roll = like fold, but discard this commit's description and date
140 #
140 #
141 $ hg histedit 1 --commands - --verbose <<EOF | grep histedit
141 $ hg histedit 1 --commands - --verbose <<EOF | grep histedit
142 > pick 177f92b77385 2 c
142 > pick 177f92b77385 2 c
143 > drop d2ae7f538514 1 b
143 > drop d2ae7f538514 1 b
144 > pick 055a42cdd887 3 d
144 > pick 055a42cdd887 3 d
145 > fold e860deea161a 4 e
145 > fold e860deea161a 4 e
146 > pick 652413bf663e 5 f
146 > pick 652413bf663e 5 f
147 > EOF
147 > EOF
148 [1]
148 [1]
149 $ hg log --graph --hidden
149 $ hg log --graph --hidden
150 @ 10:cacdfd884a93 f
150 @ 10:cacdfd884a93 f
151 |
151 |
152 o 9:59d9f330561f d
152 o 9:59d9f330561f d
153 |
153 |
154 | x 8:b558abc46d09 fold-temp-revision e860deea161a
154 | x 8:b558abc46d09 fold-temp-revision e860deea161a
155 | |
155 | |
156 | x 7:96e494a2d553 d
156 | x 7:96e494a2d553 d
157 |/
157 |/
158 o 6:b346ab9a313d c
158 o 6:b346ab9a313d c
159 |
159 |
160 | x 5:652413bf663e f
160 | x 5:652413bf663e f
161 | |
161 | |
162 | x 4:e860deea161a e
162 | x 4:e860deea161a e
163 | |
163 | |
164 | x 3:055a42cdd887 d
164 | x 3:055a42cdd887 d
165 | |
165 | |
166 | x 2:177f92b77385 c
166 | x 2:177f92b77385 c
167 | |
167 | |
168 | x 1:d2ae7f538514 b
168 | x 1:d2ae7f538514 b
169 |/
169 |/
170 o 0:cb9a9f314b8b a
170 o 0:cb9a9f314b8b a
171
171
172 $ hg debugobsolete
172 $ hg debugobsolete
173 96e494a2d553dd05902ba1cee1d94d4cb7b8faed 0 {b346ab9a313db8537ecf96fca3ca3ca984ef3bd7} (*) {'operation': 'histedit', 'user': 'test'} (glob)
173 96e494a2d553dd05902ba1cee1d94d4cb7b8faed 0 {b346ab9a313db8537ecf96fca3ca3ca984ef3bd7} (*) {'user': 'test'} (glob)
174 b558abc46d09c30f57ac31e85a8a3d64d2e906e4 0 {96e494a2d553dd05902ba1cee1d94d4cb7b8faed} (*) {'operation': 'histedit', 'user': 'test'} (glob)
174 b558abc46d09c30f57ac31e85a8a3d64d2e906e4 0 {96e494a2d553dd05902ba1cee1d94d4cb7b8faed} (*) {'user': 'test'} (glob)
175 d2ae7f538514cd87c17547b0de4cea71fe1af9fb 0 {cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b} (*) {'operation': 'histedit', 'user': 'test'} (glob)
175 d2ae7f538514cd87c17547b0de4cea71fe1af9fb 0 {cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b} (*) {'user': 'test'} (glob)
176 177f92b773850b59254aa5e923436f921b55483b b346ab9a313db8537ecf96fca3ca3ca984ef3bd7 0 (*) {'operation': 'histedit', 'user': 'test'} (glob)
176 177f92b773850b59254aa5e923436f921b55483b b346ab9a313db8537ecf96fca3ca3ca984ef3bd7 0 (*) {'user': 'test'} (glob)
177 055a42cdd88768532f9cf79daa407fc8d138de9b 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 (*) {'operation': 'histedit', 'user': 'test'} (glob)
177 055a42cdd88768532f9cf79daa407fc8d138de9b 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 (*) {'user': 'test'} (glob)
178 e860deea161a2f77de56603b340ebbb4536308ae 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 (*) {'operation': 'histedit', 'user': 'test'} (glob)
178 e860deea161a2f77de56603b340ebbb4536308ae 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 (*) {'user': 'test'} (glob)
179 652413bf663ef2a641cab26574e46d5f5a64a55a cacdfd884a9321ec4e1de275ef3949fa953a1f83 0 (*) {'operation': 'histedit', 'user': 'test'} (glob)
179 652413bf663ef2a641cab26574e46d5f5a64a55a cacdfd884a9321ec4e1de275ef3949fa953a1f83 0 (*) {'user': 'test'} (glob)
180
180
181
181
182 Ensure hidden revision does not prevent histedit
182 Ensure hidden revision does not prevent histedit
183 -------------------------------------------------
183 -------------------------------------------------
184
184
185 create an hidden revision
185 create an hidden revision
186
186
187 $ hg histedit 6 --commands - << EOF
187 $ hg histedit 6 --commands - << EOF
188 > pick b346ab9a313d 6 c
188 > pick b346ab9a313d 6 c
189 > drop 59d9f330561f 7 d
189 > drop 59d9f330561f 7 d
190 > pick cacdfd884a93 8 f
190 > pick cacdfd884a93 8 f
191 > EOF
191 > EOF
192 $ hg log --graph
192 $ hg log --graph
193 @ 11:c13eb81022ca f
193 @ 11:c13eb81022ca f
194 |
194 |
195 o 6:b346ab9a313d c
195 o 6:b346ab9a313d c
196 |
196 |
197 o 0:cb9a9f314b8b a
197 o 0:cb9a9f314b8b a
198
198
199 check hidden revision are ignored (6 have hidden children 7 and 8)
199 check hidden revision are ignored (6 have hidden children 7 and 8)
200
200
201 $ hg histedit 6 --commands - << EOF
201 $ hg histedit 6 --commands - << EOF
202 > pick b346ab9a313d 6 c
202 > pick b346ab9a313d 6 c
203 > pick c13eb81022ca 8 f
203 > pick c13eb81022ca 8 f
204 > EOF
204 > EOF
205
205
206
206
207
207
208 Test that rewriting leaving instability behind is allowed
208 Test that rewriting leaving instability behind is allowed
209 ---------------------------------------------------------------------
209 ---------------------------------------------------------------------
210
210
211 $ hg up '.^'
211 $ hg up '.^'
212 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
212 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
213 $ hg log -r 'children(.)'
213 $ hg log -r 'children(.)'
214 11:c13eb81022ca f (no-eol)
214 11:c13eb81022ca f (no-eol)
215 $ hg histedit -r '.' --commands - <<EOF
215 $ hg histedit -r '.' --commands - <<EOF
216 > edit b346ab9a313d 6 c
216 > edit b346ab9a313d 6 c
217 > EOF
217 > EOF
218 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
218 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
219 adding c
219 adding c
220 Editing (b346ab9a313d), you may commit or record as needed now.
220 Editing (b346ab9a313d), you may commit or record as needed now.
221 (hg histedit --continue to resume)
221 (hg histedit --continue to resume)
222 [1]
222 [1]
223 $ echo c >> c
223 $ echo c >> c
224 $ hg histedit --continue
224 $ hg histedit --continue
225
225
226 $ hg log -r 'unstable()'
226 $ hg log -r 'unstable()'
227 11:c13eb81022ca f (no-eol)
227 11:c13eb81022ca f (no-eol)
228
228
229 stabilise
229 stabilise
230
230
231 $ hg rebase -r 'unstable()' -d .
231 $ hg rebase -r 'unstable()' -d .
232 rebasing 11:c13eb81022ca "f"
232 rebasing 11:c13eb81022ca "f"
233 $ hg up tip -q
233 $ hg up tip -q
234
234
235 Test dropping of changeset on the top of the stack
235 Test dropping of changeset on the top of the stack
236 -------------------------------------------------------
236 -------------------------------------------------------
237
237
238 Nothing is rewritten below, the working directory parent must be change for the
238 Nothing is rewritten below, the working directory parent must be change for the
239 dropped changeset to be hidden.
239 dropped changeset to be hidden.
240
240
241 $ cd ..
241 $ cd ..
242 $ hg clone base droplast
242 $ hg clone base droplast
243 updating to branch default
243 updating to branch default
244 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
244 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
245 $ cd droplast
245 $ cd droplast
246 $ hg histedit -r '40db8afa467b' --commands - << EOF
246 $ hg histedit -r '40db8afa467b' --commands - << EOF
247 > pick 40db8afa467b 10 c
247 > pick 40db8afa467b 10 c
248 > drop b449568bf7fc 11 f
248 > drop b449568bf7fc 11 f
249 > EOF
249 > EOF
250 $ hg log -G
250 $ hg log -G
251 @ 12:40db8afa467b c
251 @ 12:40db8afa467b c
252 |
252 |
253 o 0:cb9a9f314b8b a
253 o 0:cb9a9f314b8b a
254
254
255
255
256 With rewritten ancestors
256 With rewritten ancestors
257
257
258 $ echo e > e
258 $ echo e > e
259 $ hg add e
259 $ hg add e
260 $ hg commit -m g
260 $ hg commit -m g
261 $ echo f > f
261 $ echo f > f
262 $ hg add f
262 $ hg add f
263 $ hg commit -m h
263 $ hg commit -m h
264 $ hg histedit -r '40db8afa467b' --commands - << EOF
264 $ hg histedit -r '40db8afa467b' --commands - << EOF
265 > pick 47a8561c0449 12 g
265 > pick 47a8561c0449 12 g
266 > pick 40db8afa467b 10 c
266 > pick 40db8afa467b 10 c
267 > drop 1b3b05f35ff0 13 h
267 > drop 1b3b05f35ff0 13 h
268 > EOF
268 > EOF
269 $ hg log -G
269 $ hg log -G
270 @ 17:ee6544123ab8 c
270 @ 17:ee6544123ab8 c
271 |
271 |
272 o 16:269e713e9eae g
272 o 16:269e713e9eae g
273 |
273 |
274 o 0:cb9a9f314b8b a
274 o 0:cb9a9f314b8b a
275
275
276 $ cd ../base
276 $ cd ../base
277
277
278
278
279
279
280 Test phases support
280 Test phases support
281 ===========================================
281 ===========================================
282
282
283 Check that histedit respect immutability
283 Check that histedit respect immutability
284 -------------------------------------------
284 -------------------------------------------
285
285
286 $ cat >> $HGRCPATH << EOF
286 $ cat >> $HGRCPATH << EOF
287 > [ui]
287 > [ui]
288 > logtemplate= {rev}:{node|short} ({phase}) {desc|firstline}\n
288 > logtemplate= {rev}:{node|short} ({phase}) {desc|firstline}\n
289 > EOF
289 > EOF
290
290
291 $ hg ph -pv '.^'
291 $ hg ph -pv '.^'
292 phase changed for 2 changesets
292 phase changed for 2 changesets
293 $ hg log -G
293 $ hg log -G
294 @ 13:b449568bf7fc (draft) f
294 @ 13:b449568bf7fc (draft) f
295 |
295 |
296 o 12:40db8afa467b (public) c
296 o 12:40db8afa467b (public) c
297 |
297 |
298 o 0:cb9a9f314b8b (public) a
298 o 0:cb9a9f314b8b (public) a
299
299
300 $ hg histedit -r '.~2'
300 $ hg histedit -r '.~2'
301 abort: cannot edit public changeset: cb9a9f314b8b
301 abort: cannot edit public changeset: cb9a9f314b8b
302 (see 'hg help phases' for details)
302 (see 'hg help phases' for details)
303 [255]
303 [255]
304
304
305
305
306 Prepare further testing
306 Prepare further testing
307 -------------------------------------------
307 -------------------------------------------
308
308
309 $ for x in g h i j k ; do
309 $ for x in g h i j k ; do
310 > echo $x > $x
310 > echo $x > $x
311 > hg add $x
311 > hg add $x
312 > hg ci -m $x
312 > hg ci -m $x
313 > done
313 > done
314 $ hg phase --force --secret .~2
314 $ hg phase --force --secret .~2
315 $ hg log -G
315 $ hg log -G
316 @ 18:ee118ab9fa44 (secret) k
316 @ 18:ee118ab9fa44 (secret) k
317 |
317 |
318 o 17:3a6c53ee7f3d (secret) j
318 o 17:3a6c53ee7f3d (secret) j
319 |
319 |
320 o 16:b605fb7503f2 (secret) i
320 o 16:b605fb7503f2 (secret) i
321 |
321 |
322 o 15:7395e1ff83bd (draft) h
322 o 15:7395e1ff83bd (draft) h
323 |
323 |
324 o 14:6b70183d2492 (draft) g
324 o 14:6b70183d2492 (draft) g
325 |
325 |
326 o 13:b449568bf7fc (draft) f
326 o 13:b449568bf7fc (draft) f
327 |
327 |
328 o 12:40db8afa467b (public) c
328 o 12:40db8afa467b (public) c
329 |
329 |
330 o 0:cb9a9f314b8b (public) a
330 o 0:cb9a9f314b8b (public) a
331
331
332 $ cd ..
332 $ cd ..
333
333
334 simple phase conservation
334 simple phase conservation
335 -------------------------------------------
335 -------------------------------------------
336
336
337 Resulting changeset should conserve the phase of the original one whatever the
337 Resulting changeset should conserve the phase of the original one whatever the
338 phases.new-commit option is.
338 phases.new-commit option is.
339
339
340 New-commit as draft (default)
340 New-commit as draft (default)
341
341
342 $ cp -R base simple-draft
342 $ cp -R base simple-draft
343 $ cd simple-draft
343 $ cd simple-draft
344 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
344 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
345 > edit b449568bf7fc 11 f
345 > edit b449568bf7fc 11 f
346 > pick 6b70183d2492 12 g
346 > pick 6b70183d2492 12 g
347 > pick 7395e1ff83bd 13 h
347 > pick 7395e1ff83bd 13 h
348 > pick b605fb7503f2 14 i
348 > pick b605fb7503f2 14 i
349 > pick 3a6c53ee7f3d 15 j
349 > pick 3a6c53ee7f3d 15 j
350 > pick ee118ab9fa44 16 k
350 > pick ee118ab9fa44 16 k
351 > EOF
351 > EOF
352 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
352 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
353 adding f
353 adding f
354 Editing (b449568bf7fc), you may commit or record as needed now.
354 Editing (b449568bf7fc), you may commit or record as needed now.
355 (hg histedit --continue to resume)
355 (hg histedit --continue to resume)
356 [1]
356 [1]
357 $ echo f >> f
357 $ echo f >> f
358 $ hg histedit --continue
358 $ hg histedit --continue
359 $ hg log -G
359 $ hg log -G
360 @ 24:12e89af74238 (secret) k
360 @ 24:12e89af74238 (secret) k
361 |
361 |
362 o 23:636a8687b22e (secret) j
362 o 23:636a8687b22e (secret) j
363 |
363 |
364 o 22:ccaf0a38653f (secret) i
364 o 22:ccaf0a38653f (secret) i
365 |
365 |
366 o 21:11a89d1c2613 (draft) h
366 o 21:11a89d1c2613 (draft) h
367 |
367 |
368 o 20:c1dec7ca82ea (draft) g
368 o 20:c1dec7ca82ea (draft) g
369 |
369 |
370 o 19:087281e68428 (draft) f
370 o 19:087281e68428 (draft) f
371 |
371 |
372 o 12:40db8afa467b (public) c
372 o 12:40db8afa467b (public) c
373 |
373 |
374 o 0:cb9a9f314b8b (public) a
374 o 0:cb9a9f314b8b (public) a
375
375
376 $ cd ..
376 $ cd ..
377
377
378
378
379 New-commit as secret (config)
379 New-commit as secret (config)
380
380
381 $ cp -R base simple-secret
381 $ cp -R base simple-secret
382 $ cd simple-secret
382 $ cd simple-secret
383 $ cat >> .hg/hgrc << EOF
383 $ cat >> .hg/hgrc << EOF
384 > [phases]
384 > [phases]
385 > new-commit=secret
385 > new-commit=secret
386 > EOF
386 > EOF
387 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
387 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
388 > edit b449568bf7fc 11 f
388 > edit b449568bf7fc 11 f
389 > pick 6b70183d2492 12 g
389 > pick 6b70183d2492 12 g
390 > pick 7395e1ff83bd 13 h
390 > pick 7395e1ff83bd 13 h
391 > pick b605fb7503f2 14 i
391 > pick b605fb7503f2 14 i
392 > pick 3a6c53ee7f3d 15 j
392 > pick 3a6c53ee7f3d 15 j
393 > pick ee118ab9fa44 16 k
393 > pick ee118ab9fa44 16 k
394 > EOF
394 > EOF
395 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
395 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
396 adding f
396 adding f
397 Editing (b449568bf7fc), you may commit or record as needed now.
397 Editing (b449568bf7fc), you may commit or record as needed now.
398 (hg histedit --continue to resume)
398 (hg histedit --continue to resume)
399 [1]
399 [1]
400 $ echo f >> f
400 $ echo f >> f
401 $ hg histedit --continue
401 $ hg histedit --continue
402 $ hg log -G
402 $ hg log -G
403 @ 24:12e89af74238 (secret) k
403 @ 24:12e89af74238 (secret) k
404 |
404 |
405 o 23:636a8687b22e (secret) j
405 o 23:636a8687b22e (secret) j
406 |
406 |
407 o 22:ccaf0a38653f (secret) i
407 o 22:ccaf0a38653f (secret) i
408 |
408 |
409 o 21:11a89d1c2613 (draft) h
409 o 21:11a89d1c2613 (draft) h
410 |
410 |
411 o 20:c1dec7ca82ea (draft) g
411 o 20:c1dec7ca82ea (draft) g
412 |
412 |
413 o 19:087281e68428 (draft) f
413 o 19:087281e68428 (draft) f
414 |
414 |
415 o 12:40db8afa467b (public) c
415 o 12:40db8afa467b (public) c
416 |
416 |
417 o 0:cb9a9f314b8b (public) a
417 o 0:cb9a9f314b8b (public) a
418
418
419 $ cd ..
419 $ cd ..
420
420
421
421
422 Changeset reordering
422 Changeset reordering
423 -------------------------------------------
423 -------------------------------------------
424
424
425 If a secret changeset is put before a draft one, all descendant should be secret.
425 If a secret changeset is put before a draft one, all descendant should be secret.
426 It seems more important to present the secret phase.
426 It seems more important to present the secret phase.
427
427
428 $ cp -R base reorder
428 $ cp -R base reorder
429 $ cd reorder
429 $ cd reorder
430 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
430 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
431 > pick b449568bf7fc 11 f
431 > pick b449568bf7fc 11 f
432 > pick 3a6c53ee7f3d 15 j
432 > pick 3a6c53ee7f3d 15 j
433 > pick 6b70183d2492 12 g
433 > pick 6b70183d2492 12 g
434 > pick b605fb7503f2 14 i
434 > pick b605fb7503f2 14 i
435 > pick 7395e1ff83bd 13 h
435 > pick 7395e1ff83bd 13 h
436 > pick ee118ab9fa44 16 k
436 > pick ee118ab9fa44 16 k
437 > EOF
437 > EOF
438 $ hg log -G
438 $ hg log -G
439 @ 23:558246857888 (secret) k
439 @ 23:558246857888 (secret) k
440 |
440 |
441 o 22:28bd44768535 (secret) h
441 o 22:28bd44768535 (secret) h
442 |
442 |
443 o 21:d5395202aeb9 (secret) i
443 o 21:d5395202aeb9 (secret) i
444 |
444 |
445 o 20:21edda8e341b (secret) g
445 o 20:21edda8e341b (secret) g
446 |
446 |
447 o 19:5ab64f3a4832 (secret) j
447 o 19:5ab64f3a4832 (secret) j
448 |
448 |
449 o 13:b449568bf7fc (draft) f
449 o 13:b449568bf7fc (draft) f
450 |
450 |
451 o 12:40db8afa467b (public) c
451 o 12:40db8afa467b (public) c
452 |
452 |
453 o 0:cb9a9f314b8b (public) a
453 o 0:cb9a9f314b8b (public) a
454
454
455 $ cd ..
455 $ cd ..
456
456
457 Changeset folding
457 Changeset folding
458 -------------------------------------------
458 -------------------------------------------
459
459
460 Folding a secret changeset with a draft one turn the result secret (again,
460 Folding a secret changeset with a draft one turn the result secret (again,
461 better safe than sorry). Folding between same phase changeset still works
461 better safe than sorry). Folding between same phase changeset still works
462
462
463 Note that there is a few reordering in this series for more extensive test
463 Note that there is a few reordering in this series for more extensive test
464
464
465 $ cp -R base folding
465 $ cp -R base folding
466 $ cd folding
466 $ cd folding
467 $ cat >> .hg/hgrc << EOF
467 $ cat >> .hg/hgrc << EOF
468 > [phases]
468 > [phases]
469 > new-commit=secret
469 > new-commit=secret
470 > EOF
470 > EOF
471 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
471 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
472 > pick 7395e1ff83bd 13 h
472 > pick 7395e1ff83bd 13 h
473 > fold b449568bf7fc 11 f
473 > fold b449568bf7fc 11 f
474 > pick 6b70183d2492 12 g
474 > pick 6b70183d2492 12 g
475 > fold 3a6c53ee7f3d 15 j
475 > fold 3a6c53ee7f3d 15 j
476 > pick b605fb7503f2 14 i
476 > pick b605fb7503f2 14 i
477 > fold ee118ab9fa44 16 k
477 > fold ee118ab9fa44 16 k
478 > EOF
478 > EOF
479 $ hg log -G
479 $ hg log -G
480 @ 27:f9daec13fb98 (secret) i
480 @ 27:f9daec13fb98 (secret) i
481 |
481 |
482 o 24:49807617f46a (secret) g
482 o 24:49807617f46a (secret) g
483 |
483 |
484 o 21:050280826e04 (draft) h
484 o 21:050280826e04 (draft) h
485 |
485 |
486 o 12:40db8afa467b (public) c
486 o 12:40db8afa467b (public) c
487 |
487 |
488 o 0:cb9a9f314b8b (public) a
488 o 0:cb9a9f314b8b (public) a
489
489
490 $ hg co 49807617f46a
490 $ hg co 49807617f46a
491 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
491 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
492 $ echo wat >> wat
492 $ echo wat >> wat
493 $ hg add wat
493 $ hg add wat
494 $ hg ci -m 'add wat'
494 $ hg ci -m 'add wat'
495 created new head
495 created new head
496 $ hg merge f9daec13fb98
496 $ hg merge f9daec13fb98
497 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
497 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
498 (branch merge, don't forget to commit)
498 (branch merge, don't forget to commit)
499 $ hg ci -m 'merge'
499 $ hg ci -m 'merge'
500 $ echo not wat > wat
500 $ echo not wat > wat
501 $ hg ci -m 'modify wat'
501 $ hg ci -m 'modify wat'
502 $ hg histedit 050280826e04
502 $ hg histedit 050280826e04
503 abort: cannot edit history that contains merges
503 abort: cannot edit history that contains merges
504 [255]
504 [255]
505 $ cd ..
505 $ cd ..
506
506
507 Check abort behavior
507 Check abort behavior
508 -------------------------------------------
508 -------------------------------------------
509
509
510 We checks that abort properly clean the repository so the same histedit can be
510 We checks that abort properly clean the repository so the same histedit can be
511 attempted later.
511 attempted later.
512
512
513 $ cp -R base abort
513 $ cp -R base abort
514 $ cd abort
514 $ cd abort
515 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
515 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
516 > pick b449568bf7fc 13 f
516 > pick b449568bf7fc 13 f
517 > pick 7395e1ff83bd 15 h
517 > pick 7395e1ff83bd 15 h
518 > pick 6b70183d2492 14 g
518 > pick 6b70183d2492 14 g
519 > pick b605fb7503f2 16 i
519 > pick b605fb7503f2 16 i
520 > roll 3a6c53ee7f3d 17 j
520 > roll 3a6c53ee7f3d 17 j
521 > edit ee118ab9fa44 18 k
521 > edit ee118ab9fa44 18 k
522 > EOF
522 > EOF
523 Editing (ee118ab9fa44), you may commit or record as needed now.
523 Editing (ee118ab9fa44), you may commit or record as needed now.
524 (hg histedit --continue to resume)
524 (hg histedit --continue to resume)
525 [1]
525 [1]
526
526
527 $ hg histedit --abort
527 $ hg histedit --abort
528 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
528 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
529 saved backup bundle to $TESTTMP/abort/.hg/strip-backup/4dc06258baa6-dff4ef05-backup.hg (glob)
529 saved backup bundle to $TESTTMP/abort/.hg/strip-backup/4dc06258baa6-dff4ef05-backup.hg (glob)
530
530
531 $ hg log -G
531 $ hg log -G
532 @ 18:ee118ab9fa44 (secret) k
532 @ 18:ee118ab9fa44 (secret) k
533 |
533 |
534 o 17:3a6c53ee7f3d (secret) j
534 o 17:3a6c53ee7f3d (secret) j
535 |
535 |
536 o 16:b605fb7503f2 (secret) i
536 o 16:b605fb7503f2 (secret) i
537 |
537 |
538 o 15:7395e1ff83bd (draft) h
538 o 15:7395e1ff83bd (draft) h
539 |
539 |
540 o 14:6b70183d2492 (draft) g
540 o 14:6b70183d2492 (draft) g
541 |
541 |
542 o 13:b449568bf7fc (draft) f
542 o 13:b449568bf7fc (draft) f
543 |
543 |
544 o 12:40db8afa467b (public) c
544 o 12:40db8afa467b (public) c
545 |
545 |
546 o 0:cb9a9f314b8b (public) a
546 o 0:cb9a9f314b8b (public) a
547
547
548 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
548 $ hg histedit -r 'b449568bf7fc' --commands - << EOF --config experimental.evolution.track-operation=1
549 > pick b449568bf7fc 13 f
549 > pick b449568bf7fc 13 f
550 > pick 7395e1ff83bd 15 h
550 > pick 7395e1ff83bd 15 h
551 > pick 6b70183d2492 14 g
551 > pick 6b70183d2492 14 g
552 > pick b605fb7503f2 16 i
552 > pick b605fb7503f2 16 i
553 > pick 3a6c53ee7f3d 17 j
553 > pick 3a6c53ee7f3d 17 j
554 > edit ee118ab9fa44 18 k
554 > edit ee118ab9fa44 18 k
555 > EOF
555 > EOF
556 Editing (ee118ab9fa44), you may commit or record as needed now.
556 Editing (ee118ab9fa44), you may commit or record as needed now.
557 (hg histedit --continue to resume)
557 (hg histedit --continue to resume)
558 [1]
558 [1]
559 $ hg histedit --continue
559 $ hg histedit --continue --config experimental.evolution.track-operation=1
560 $ hg log -G
560 $ hg log -G
561 @ 23:175d6b286a22 (secret) k
561 @ 23:175d6b286a22 (secret) k
562 |
562 |
563 o 22:44ca09d59ae4 (secret) j
563 o 22:44ca09d59ae4 (secret) j
564 |
564 |
565 o 21:31747692a644 (secret) i
565 o 21:31747692a644 (secret) i
566 |
566 |
567 o 20:9985cd4f21fa (draft) g
567 o 20:9985cd4f21fa (draft) g
568 |
568 |
569 o 19:4dc06258baa6 (draft) h
569 o 19:4dc06258baa6 (draft) h
570 |
570 |
571 o 13:b449568bf7fc (draft) f
571 o 13:b449568bf7fc (draft) f
572 |
572 |
573 o 12:40db8afa467b (public) c
573 o 12:40db8afa467b (public) c
574 |
574 |
575 o 0:cb9a9f314b8b (public) a
575 o 0:cb9a9f314b8b (public) a
576
576
577 $ hg debugobsolete --rev .
578 ee118ab9fa44ebb86be85996548b5517a39e5093 175d6b286a224c23f192e79a581ce83131a53fa2 0 (*) {'operation': 'histedit', 'user': 'test'} (glob)
@@ -1,1284 +1,1284 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(troubles, ' {troubles}')}) [{tags} {bookmarks}] {desc|firstline}\n"
6 > logtemplate="{rev}:{node|short} ({phase}{if(obsolete, ' *{obsolete}*')}{if(troubles, ' {troubles}')}) [{tags} {bookmarks}] {desc|firstline}\n"
7 > EOF
7 > EOF
8 $ mkcommit() {
8 $ mkcommit() {
9 > echo "$1" > "$1"
9 > echo "$1" > "$1"
10 > hg add "$1"
10 > hg add "$1"
11 > hg ci -m "add $1"
11 > hg ci -m "add $1"
12 > }
12 > }
13 $ getid() {
13 $ getid() {
14 > hg log -T "{node}\n" --hidden -r "desc('$1')"
14 > hg log -T "{node}\n" --hidden -r "desc('$1')"
15 > }
15 > }
16
16
17 $ cat > debugkeys.py <<EOF
17 $ cat > debugkeys.py <<EOF
18 > def reposetup(ui, repo):
18 > def reposetup(ui, repo):
19 > class debugkeysrepo(repo.__class__):
19 > class debugkeysrepo(repo.__class__):
20 > def listkeys(self, namespace):
20 > def listkeys(self, namespace):
21 > ui.write('listkeys %s\n' % (namespace,))
21 > ui.write('listkeys %s\n' % (namespace,))
22 > return super(debugkeysrepo, self).listkeys(namespace)
22 > return super(debugkeysrepo, self).listkeys(namespace)
23 >
23 >
24 > if repo.local():
24 > if repo.local():
25 > repo.__class__ = debugkeysrepo
25 > repo.__class__ = debugkeysrepo
26 > EOF
26 > EOF
27
27
28 $ hg init tmpa
28 $ hg init tmpa
29 $ cd tmpa
29 $ cd tmpa
30 $ mkcommit kill_me
30 $ mkcommit kill_me
31
31
32 Checking that the feature is properly disabled
32 Checking that the feature is properly disabled
33
33
34 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
34 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
35 abort: creating obsolete markers is not enabled on this repo
35 abort: creating obsolete markers is not enabled on this repo
36 [255]
36 [255]
37
37
38 Enabling it
38 Enabling it
39
39
40 $ cat >> $HGRCPATH << EOF
40 $ cat >> $HGRCPATH << EOF
41 > [experimental]
41 > [experimental]
42 > evolution=createmarkers,exchange
42 > evolution=createmarkers,exchange
43 > EOF
43 > EOF
44
44
45 Killing a single changeset without replacement
45 Killing a single changeset without replacement
46
46
47 $ hg debugobsolete 0
47 $ hg debugobsolete 0
48 abort: changeset references must be full hexadecimal node identifiers
48 abort: changeset references must be full hexadecimal node identifiers
49 [255]
49 [255]
50 $ hg debugobsolete '00'
50 $ hg debugobsolete '00'
51 abort: changeset references must be full hexadecimal node identifiers
51 abort: changeset references must be full hexadecimal node identifiers
52 [255]
52 [255]
53 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
53 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
54 $ hg debugobsolete
54 $ hg debugobsolete
55 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'babar'}
55 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'babar'}
56
56
57 (test that mercurial is not confused)
57 (test that mercurial is not confused)
58
58
59 $ hg up null --quiet # having 0 as parent prevents it to be hidden
59 $ hg up null --quiet # having 0 as parent prevents it to be hidden
60 $ hg tip
60 $ hg tip
61 -1:000000000000 (public) [tip ]
61 -1:000000000000 (public) [tip ]
62 $ hg up --hidden tip --quiet
62 $ hg up --hidden tip --quiet
63
63
64 Killing a single changeset with itself should fail
64 Killing a single changeset with itself should fail
65 (simple local safeguard)
65 (simple local safeguard)
66
66
67 $ hg debugobsolete `getid kill_me` `getid kill_me`
67 $ hg debugobsolete `getid kill_me` `getid kill_me`
68 abort: bad obsmarker input: in-marker cycle with 97b7c2d76b1845ed3eb988cd612611e72406cef0
68 abort: bad obsmarker input: in-marker cycle with 97b7c2d76b1845ed3eb988cd612611e72406cef0
69 [255]
69 [255]
70
70
71 $ cd ..
71 $ cd ..
72
72
73 Killing a single changeset with replacement
73 Killing a single changeset with replacement
74 (and testing the format option)
74 (and testing the format option)
75
75
76 $ hg init tmpb
76 $ hg init tmpb
77 $ cd tmpb
77 $ cd tmpb
78 $ mkcommit a
78 $ mkcommit a
79 $ mkcommit b
79 $ mkcommit b
80 $ mkcommit original_c
80 $ mkcommit original_c
81 $ hg up "desc('b')"
81 $ hg up "desc('b')"
82 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
82 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
83 $ mkcommit new_c
83 $ mkcommit new_c
84 created new head
84 created new head
85 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
85 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
86 $ hg debugobsolete --config format.obsstore-version=0 --flag 12 `getid original_c` `getid new_c` -d '121 120'
86 $ hg debugobsolete --config format.obsstore-version=0 --flag 12 `getid original_c` `getid new_c` -d '121 120'
87 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
87 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
88 2:245bde4270cd add original_c
88 2:245bde4270cd add original_c
89 $ hg debugrevlog -cd
89 $ hg debugrevlog -cd
90 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
90 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
91 0 -1 -1 0 59 0 0 0 0 58 58 0 1 0
91 0 -1 -1 0 59 0 0 0 0 58 58 0 1 0
92 1 0 -1 59 118 59 59 0 0 58 116 0 1 0
92 1 0 -1 59 118 59 59 0 0 58 116 0 1 0
93 2 1 -1 118 193 118 118 59 0 76 192 0 1 0
93 2 1 -1 118 193 118 118 59 0 76 192 0 1 0
94 3 1 -1 193 260 193 193 59 0 66 258 0 2 0
94 3 1 -1 193 260 193 193 59 0 66 258 0 2 0
95 $ hg debugobsolete
95 $ hg debugobsolete
96 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
96 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
97
97
98 (check for version number of the obsstore)
98 (check for version number of the obsstore)
99
99
100 $ dd bs=1 count=1 if=.hg/store/obsstore 2>/dev/null
100 $ dd bs=1 count=1 if=.hg/store/obsstore 2>/dev/null
101 \x00 (no-eol) (esc)
101 \x00 (no-eol) (esc)
102
102
103 do it again (it read the obsstore before adding new changeset)
103 do it again (it read the obsstore before adding new changeset)
104
104
105 $ hg up '.^'
105 $ hg up '.^'
106 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
106 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
107 $ mkcommit new_2_c
107 $ mkcommit new_2_c
108 created new head
108 created new head
109 $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
109 $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
110 $ hg debugobsolete
110 $ hg debugobsolete
111 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
111 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
112 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
112 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
113
113
114 Register two markers with a missing node
114 Register two markers with a missing node
115
115
116 $ hg up '.^'
116 $ hg up '.^'
117 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
117 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
118 $ mkcommit new_3_c
118 $ mkcommit new_3_c
119 created new head
119 created new head
120 $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
120 $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
121 $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
121 $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
122 $ hg debugobsolete
122 $ hg debugobsolete
123 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
123 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
124 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
124 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
125 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
125 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
126 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
126 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
127
127
128 Test the --index option of debugobsolete command
128 Test the --index option of debugobsolete command
129 $ hg debugobsolete --index
129 $ hg debugobsolete --index
130 0 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
130 0 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
131 1 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
131 1 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
132 2 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
132 2 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
133 3 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
133 3 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
134
134
135 Refuse pathological nullid successors
135 Refuse pathological nullid successors
136 $ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
136 $ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
137 transaction abort!
137 transaction abort!
138 rollback completed
138 rollback completed
139 abort: bad obsolescence marker detected: invalid successors nullid
139 abort: bad obsolescence marker detected: invalid successors nullid
140 [255]
140 [255]
141
141
142 Check that graphlog detect that a changeset is obsolete:
142 Check that graphlog detect that a changeset is obsolete:
143
143
144 $ hg log -G
144 $ hg log -G
145 @ 5:5601fb93a350 (draft) [tip ] add new_3_c
145 @ 5:5601fb93a350 (draft) [tip ] add new_3_c
146 |
146 |
147 o 1:7c3bad9141dc (draft) [ ] add b
147 o 1:7c3bad9141dc (draft) [ ] add b
148 |
148 |
149 o 0:1f0dee641bb7 (draft) [ ] add a
149 o 0:1f0dee641bb7 (draft) [ ] add a
150
150
151
151
152 check that heads does not report them
152 check that heads does not report them
153
153
154 $ hg heads
154 $ hg heads
155 5:5601fb93a350 (draft) [tip ] add new_3_c
155 5:5601fb93a350 (draft) [tip ] add new_3_c
156 $ hg heads --hidden
156 $ hg heads --hidden
157 5:5601fb93a350 (draft) [tip ] add new_3_c
157 5:5601fb93a350 (draft) [tip ] add new_3_c
158 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c
158 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c
159 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c
159 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c
160 2:245bde4270cd (draft *obsolete*) [ ] add original_c
160 2:245bde4270cd (draft *obsolete*) [ ] add original_c
161
161
162
162
163 check that summary does not report them
163 check that summary does not report them
164
164
165 $ hg init ../sink
165 $ hg init ../sink
166 $ echo '[paths]' >> .hg/hgrc
166 $ echo '[paths]' >> .hg/hgrc
167 $ echo 'default=../sink' >> .hg/hgrc
167 $ echo 'default=../sink' >> .hg/hgrc
168 $ hg summary --remote
168 $ hg summary --remote
169 parent: 5:5601fb93a350 tip
169 parent: 5:5601fb93a350 tip
170 add new_3_c
170 add new_3_c
171 branch: default
171 branch: default
172 commit: (clean)
172 commit: (clean)
173 update: (current)
173 update: (current)
174 phases: 3 draft
174 phases: 3 draft
175 remote: 3 outgoing
175 remote: 3 outgoing
176
176
177 $ hg summary --remote --hidden
177 $ hg summary --remote --hidden
178 parent: 5:5601fb93a350 tip
178 parent: 5:5601fb93a350 tip
179 add new_3_c
179 add new_3_c
180 branch: default
180 branch: default
181 commit: (clean)
181 commit: (clean)
182 update: 3 new changesets, 4 branch heads (merge)
182 update: 3 new changesets, 4 branch heads (merge)
183 phases: 6 draft
183 phases: 6 draft
184 remote: 3 outgoing
184 remote: 3 outgoing
185
185
186 check that various commands work well with filtering
186 check that various commands work well with filtering
187
187
188 $ hg tip
188 $ hg tip
189 5:5601fb93a350 (draft) [tip ] add new_3_c
189 5:5601fb93a350 (draft) [tip ] add new_3_c
190 $ hg log -r 6
190 $ hg log -r 6
191 abort: unknown revision '6'!
191 abort: unknown revision '6'!
192 [255]
192 [255]
193 $ hg log -r 4
193 $ hg log -r 4
194 abort: hidden revision '4'!
194 abort: hidden revision '4'!
195 (use --hidden to access hidden revisions)
195 (use --hidden to access hidden revisions)
196 [255]
196 [255]
197 $ hg debugrevspec 'rev(6)'
197 $ hg debugrevspec 'rev(6)'
198 $ hg debugrevspec 'rev(4)'
198 $ hg debugrevspec 'rev(4)'
199 $ hg debugrevspec 'null'
199 $ hg debugrevspec 'null'
200 -1
200 -1
201
201
202 Check that public changeset are not accounted as obsolete:
202 Check that public changeset are not accounted as obsolete:
203
203
204 $ hg --hidden phase --public 2
204 $ hg --hidden phase --public 2
205 $ hg log -G
205 $ hg log -G
206 @ 5:5601fb93a350 (draft bumped) [tip ] add new_3_c
206 @ 5:5601fb93a350 (draft bumped) [tip ] add new_3_c
207 |
207 |
208 | o 2:245bde4270cd (public) [ ] add original_c
208 | o 2:245bde4270cd (public) [ ] add original_c
209 |/
209 |/
210 o 1:7c3bad9141dc (public) [ ] add b
210 o 1:7c3bad9141dc (public) [ ] add b
211 |
211 |
212 o 0:1f0dee641bb7 (public) [ ] add a
212 o 0:1f0dee641bb7 (public) [ ] add a
213
213
214
214
215 And that bumped changeset are detected
215 And that bumped changeset are detected
216 --------------------------------------
216 --------------------------------------
217
217
218 If we didn't filtered obsolete changesets out, 3 and 4 would show up too. Also
218 If we didn't filtered obsolete changesets out, 3 and 4 would show up too. Also
219 note that the bumped changeset (5:5601fb93a350) is not a direct successor of
219 note that the bumped changeset (5:5601fb93a350) is not a direct successor of
220 the public changeset
220 the public changeset
221
221
222 $ hg log --hidden -r 'bumped()'
222 $ hg log --hidden -r 'bumped()'
223 5:5601fb93a350 (draft bumped) [tip ] add new_3_c
223 5:5601fb93a350 (draft bumped) [tip ] add new_3_c
224
224
225 And that we can't push bumped changeset
225 And that we can't push bumped changeset
226
226
227 $ hg push ../tmpa -r 0 --force #(make repo related)
227 $ hg push ../tmpa -r 0 --force #(make repo related)
228 pushing to ../tmpa
228 pushing to ../tmpa
229 searching for changes
229 searching for changes
230 warning: repository is unrelated
230 warning: repository is unrelated
231 adding changesets
231 adding changesets
232 adding manifests
232 adding manifests
233 adding file changes
233 adding file changes
234 added 1 changesets with 1 changes to 1 files (+1 heads)
234 added 1 changesets with 1 changes to 1 files (+1 heads)
235 $ hg push ../tmpa
235 $ hg push ../tmpa
236 pushing to ../tmpa
236 pushing to ../tmpa
237 searching for changes
237 searching for changes
238 abort: push includes bumped changeset: 5601fb93a350!
238 abort: push includes bumped changeset: 5601fb93a350!
239 [255]
239 [255]
240
240
241 Fixing "bumped" situation
241 Fixing "bumped" situation
242 We need to create a clone of 5 and add a special marker with a flag
242 We need to create a clone of 5 and add a special marker with a flag
243
243
244 $ hg summary
244 $ hg summary
245 parent: 5:5601fb93a350 tip (bumped)
245 parent: 5:5601fb93a350 tip (bumped)
246 add new_3_c
246 add new_3_c
247 branch: default
247 branch: default
248 commit: (clean)
248 commit: (clean)
249 update: 1 new changesets, 2 branch heads (merge)
249 update: 1 new changesets, 2 branch heads (merge)
250 phases: 1 draft
250 phases: 1 draft
251 bumped: 1 changesets
251 bumped: 1 changesets
252 $ hg up '5^'
252 $ hg up '5^'
253 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
253 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
254 $ hg revert -ar 5
254 $ hg revert -ar 5
255 adding new_3_c
255 adding new_3_c
256 $ hg ci -m 'add n3w_3_c'
256 $ hg ci -m 'add n3w_3_c'
257 created new head
257 created new head
258 $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c`
258 $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c`
259 $ hg log -r 'bumped()'
259 $ hg log -r 'bumped()'
260 $ hg log -G
260 $ hg log -G
261 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
261 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
262 |
262 |
263 | o 2:245bde4270cd (public) [ ] add original_c
263 | o 2:245bde4270cd (public) [ ] add original_c
264 |/
264 |/
265 o 1:7c3bad9141dc (public) [ ] add b
265 o 1:7c3bad9141dc (public) [ ] add b
266 |
266 |
267 o 0:1f0dee641bb7 (public) [ ] add a
267 o 0:1f0dee641bb7 (public) [ ] add a
268
268
269
269
270 $ cd ..
270 $ cd ..
271
271
272 Revision 0 is hidden
272 Revision 0 is hidden
273 --------------------
273 --------------------
274
274
275 $ hg init rev0hidden
275 $ hg init rev0hidden
276 $ cd rev0hidden
276 $ cd rev0hidden
277
277
278 $ mkcommit kill0
278 $ mkcommit kill0
279 $ hg up -q null
279 $ hg up -q null
280 $ hg debugobsolete `getid kill0`
280 $ hg debugobsolete `getid kill0`
281 $ mkcommit a
281 $ mkcommit a
282 $ mkcommit b
282 $ mkcommit b
283
283
284 Should pick the first visible revision as "repo" node
284 Should pick the first visible revision as "repo" node
285
285
286 $ hg archive ../archive-null
286 $ hg archive ../archive-null
287 $ cat ../archive-null/.hg_archival.txt
287 $ cat ../archive-null/.hg_archival.txt
288 repo: 1f0dee641bb7258c56bd60e93edfa2405381c41e
288 repo: 1f0dee641bb7258c56bd60e93edfa2405381c41e
289 node: 7c3bad9141dcb46ff89abf5f61856facd56e476c
289 node: 7c3bad9141dcb46ff89abf5f61856facd56e476c
290 branch: default
290 branch: default
291 latesttag: null
291 latesttag: null
292 latesttagdistance: 2
292 latesttagdistance: 2
293 changessincelatesttag: 2
293 changessincelatesttag: 2
294
294
295
295
296 $ cd ..
296 $ cd ..
297
297
298 Exchange Test
298 Exchange Test
299 ============================
299 ============================
300
300
301 Destination repo does not have any data
301 Destination repo does not have any data
302 ---------------------------------------
302 ---------------------------------------
303
303
304 Simple incoming test
304 Simple incoming test
305
305
306 $ hg init tmpc
306 $ hg init tmpc
307 $ cd tmpc
307 $ cd tmpc
308 $ hg incoming ../tmpb
308 $ hg incoming ../tmpb
309 comparing with ../tmpb
309 comparing with ../tmpb
310 0:1f0dee641bb7 (public) [ ] add a
310 0:1f0dee641bb7 (public) [ ] add a
311 1:7c3bad9141dc (public) [ ] add b
311 1:7c3bad9141dc (public) [ ] add b
312 2:245bde4270cd (public) [ ] add original_c
312 2:245bde4270cd (public) [ ] add original_c
313 6:6f9641995072 (draft) [tip ] add n3w_3_c
313 6:6f9641995072 (draft) [tip ] add n3w_3_c
314
314
315 Try to pull markers
315 Try to pull markers
316 (extinct changeset are excluded but marker are pushed)
316 (extinct changeset are excluded but marker are pushed)
317
317
318 $ hg pull ../tmpb
318 $ hg pull ../tmpb
319 pulling from ../tmpb
319 pulling from ../tmpb
320 requesting all changes
320 requesting all changes
321 adding changesets
321 adding changesets
322 adding manifests
322 adding manifests
323 adding file changes
323 adding file changes
324 added 4 changesets with 4 changes to 4 files (+1 heads)
324 added 4 changesets with 4 changes to 4 files (+1 heads)
325 5 new obsolescence markers
325 5 new obsolescence markers
326 (run 'hg heads' to see heads, 'hg merge' to merge)
326 (run 'hg heads' to see heads, 'hg merge' to merge)
327 $ hg debugobsolete
327 $ hg debugobsolete
328 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
328 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
329 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
329 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
330 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
330 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
331 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
331 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
332 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
332 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
333
333
334 Rollback//Transaction support
334 Rollback//Transaction support
335
335
336 $ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
336 $ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
337 $ hg debugobsolete
337 $ hg debugobsolete
338 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
338 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
339 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
339 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
340 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
340 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
341 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
341 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
342 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
342 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
343 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:22:20 1970 +0000) {'user': 'test'}
343 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:22:20 1970 +0000) {'user': 'test'}
344 $ hg rollback -n
344 $ hg rollback -n
345 repository tip rolled back to revision 3 (undo debugobsolete)
345 repository tip rolled back to revision 3 (undo debugobsolete)
346 $ hg rollback
346 $ hg rollback
347 repository tip rolled back to revision 3 (undo debugobsolete)
347 repository tip rolled back to revision 3 (undo debugobsolete)
348 $ hg debugobsolete
348 $ hg debugobsolete
349 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
349 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
350 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
350 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
351 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
351 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
352 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
352 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
353 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
353 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
354
354
355 $ cd ..
355 $ cd ..
356
356
357 Try to push markers
357 Try to push markers
358
358
359 $ hg init tmpd
359 $ hg init tmpd
360 $ hg -R tmpb push tmpd
360 $ hg -R tmpb push tmpd
361 pushing to tmpd
361 pushing to tmpd
362 searching for changes
362 searching for changes
363 adding changesets
363 adding changesets
364 adding manifests
364 adding manifests
365 adding file changes
365 adding file changes
366 added 4 changesets with 4 changes to 4 files (+1 heads)
366 added 4 changesets with 4 changes to 4 files (+1 heads)
367 5 new obsolescence markers
367 5 new obsolescence markers
368 $ hg -R tmpd debugobsolete | sort
368 $ hg -R tmpd debugobsolete | sort
369 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
369 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
370 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
370 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
371 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
371 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
372 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
372 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
373 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
373 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
374
374
375 Check obsolete keys are exchanged only if source has an obsolete store
375 Check obsolete keys are exchanged only if source has an obsolete store
376
376
377 $ hg init empty
377 $ hg init empty
378 $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
378 $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
379 pushing to tmpd
379 pushing to tmpd
380 listkeys phases
380 listkeys phases
381 listkeys bookmarks
381 listkeys bookmarks
382 no changes found
382 no changes found
383 listkeys phases
383 listkeys phases
384 [1]
384 [1]
385
385
386 clone support
386 clone support
387 (markers are copied and extinct changesets are included to allow hardlinks)
387 (markers are copied and extinct changesets are included to allow hardlinks)
388
388
389 $ hg clone tmpb clone-dest
389 $ hg clone tmpb clone-dest
390 updating to branch default
390 updating to branch default
391 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
391 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
392 $ hg -R clone-dest log -G --hidden
392 $ hg -R clone-dest log -G --hidden
393 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
393 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
394 |
394 |
395 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c
395 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c
396 |/
396 |/
397 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c
397 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c
398 |/
398 |/
399 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c
399 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c
400 |/
400 |/
401 | o 2:245bde4270cd (public) [ ] add original_c
401 | o 2:245bde4270cd (public) [ ] add original_c
402 |/
402 |/
403 o 1:7c3bad9141dc (public) [ ] add b
403 o 1:7c3bad9141dc (public) [ ] add b
404 |
404 |
405 o 0:1f0dee641bb7 (public) [ ] add a
405 o 0:1f0dee641bb7 (public) [ ] add a
406
406
407 $ hg -R clone-dest debugobsolete
407 $ hg -R clone-dest debugobsolete
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 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
409 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 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 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
411 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
412 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
412 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
413
413
414
414
415 Destination repo have existing data
415 Destination repo have existing data
416 ---------------------------------------
416 ---------------------------------------
417
417
418 On pull
418 On pull
419
419
420 $ hg init tmpe
420 $ hg init tmpe
421 $ cd tmpe
421 $ cd tmpe
422 $ hg debugobsolete -d '1339 0' 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00
422 $ hg debugobsolete -d '1339 0' 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00
423 $ hg pull ../tmpb
423 $ hg pull ../tmpb
424 pulling from ../tmpb
424 pulling from ../tmpb
425 requesting all changes
425 requesting all changes
426 adding changesets
426 adding changesets
427 adding manifests
427 adding manifests
428 adding file changes
428 adding file changes
429 added 4 changesets with 4 changes to 4 files (+1 heads)
429 added 4 changesets with 4 changes to 4 files (+1 heads)
430 5 new obsolescence markers
430 5 new obsolescence markers
431 (run 'hg heads' to see heads, 'hg merge' to merge)
431 (run 'hg heads' to see heads, 'hg merge' to merge)
432 $ hg debugobsolete
432 $ hg debugobsolete
433 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
433 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
434 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
434 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
435 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
435 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
436 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
436 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
437 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
437 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
438 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
438 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
439
439
440
440
441 On push
441 On push
442
442
443 $ hg push ../tmpc
443 $ hg push ../tmpc
444 pushing to ../tmpc
444 pushing to ../tmpc
445 searching for changes
445 searching for changes
446 no changes found
446 no changes found
447 1 new obsolescence markers
447 1 new obsolescence markers
448 [1]
448 [1]
449 $ hg -R ../tmpc debugobsolete
449 $ hg -R ../tmpc debugobsolete
450 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
450 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
451 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
451 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
452 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
452 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
453 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
453 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
454 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
454 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
455 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
455 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
456
456
457 detect outgoing obsolete and unstable
457 detect outgoing obsolete and unstable
458 ---------------------------------------
458 ---------------------------------------
459
459
460
460
461 $ hg log -G
461 $ hg log -G
462 o 3:6f9641995072 (draft) [tip ] add n3w_3_c
462 o 3:6f9641995072 (draft) [tip ] add n3w_3_c
463 |
463 |
464 | o 2:245bde4270cd (public) [ ] add original_c
464 | o 2:245bde4270cd (public) [ ] add original_c
465 |/
465 |/
466 o 1:7c3bad9141dc (public) [ ] add b
466 o 1:7c3bad9141dc (public) [ ] add b
467 |
467 |
468 o 0:1f0dee641bb7 (public) [ ] add a
468 o 0:1f0dee641bb7 (public) [ ] add a
469
469
470 $ hg up 'desc("n3w_3_c")'
470 $ hg up 'desc("n3w_3_c")'
471 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
471 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
472 $ mkcommit original_d
472 $ mkcommit original_d
473 $ mkcommit original_e
473 $ mkcommit original_e
474 $ hg debugobsolete --record-parents `getid original_d` -d '0 0'
474 $ hg debugobsolete --record-parents `getid original_d` -d '0 0'
475 $ hg debugobsolete | grep `getid original_d`
475 $ hg debugobsolete | grep `getid original_d`
476 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
476 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
477 $ hg log -r 'obsolete()'
477 $ hg log -r 'obsolete()'
478 4:94b33453f93b (draft *obsolete*) [ ] add original_d
478 4:94b33453f93b (draft *obsolete*) [ ] add original_d
479 $ hg summary
479 $ hg summary
480 parent: 5:cda648ca50f5 tip (unstable)
480 parent: 5:cda648ca50f5 tip (unstable)
481 add original_e
481 add original_e
482 branch: default
482 branch: default
483 commit: (clean)
483 commit: (clean)
484 update: 1 new changesets, 2 branch heads (merge)
484 update: 1 new changesets, 2 branch heads (merge)
485 phases: 3 draft
485 phases: 3 draft
486 unstable: 1 changesets
486 unstable: 1 changesets
487 $ hg log -G -r '::unstable()'
487 $ hg log -G -r '::unstable()'
488 @ 5:cda648ca50f5 (draft unstable) [tip ] add original_e
488 @ 5:cda648ca50f5 (draft unstable) [tip ] add original_e
489 |
489 |
490 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d
490 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d
491 |
491 |
492 o 3:6f9641995072 (draft) [ ] add n3w_3_c
492 o 3:6f9641995072 (draft) [ ] add n3w_3_c
493 |
493 |
494 o 1:7c3bad9141dc (public) [ ] add b
494 o 1:7c3bad9141dc (public) [ ] add b
495 |
495 |
496 o 0:1f0dee641bb7 (public) [ ] add a
496 o 0:1f0dee641bb7 (public) [ ] add a
497
497
498
498
499 refuse to push obsolete changeset
499 refuse to push obsolete changeset
500
500
501 $ hg push ../tmpc/ -r 'desc("original_d")'
501 $ hg push ../tmpc/ -r 'desc("original_d")'
502 pushing to ../tmpc/
502 pushing to ../tmpc/
503 searching for changes
503 searching for changes
504 abort: push includes obsolete changeset: 94b33453f93b!
504 abort: push includes obsolete changeset: 94b33453f93b!
505 [255]
505 [255]
506
506
507 refuse to push unstable changeset
507 refuse to push unstable changeset
508
508
509 $ hg push ../tmpc/
509 $ hg push ../tmpc/
510 pushing to ../tmpc/
510 pushing to ../tmpc/
511 searching for changes
511 searching for changes
512 abort: push includes unstable changeset: cda648ca50f5!
512 abort: push includes unstable changeset: cda648ca50f5!
513 [255]
513 [255]
514
514
515 Test that extinct changeset are properly detected
515 Test that extinct changeset are properly detected
516
516
517 $ hg log -r 'extinct()'
517 $ hg log -r 'extinct()'
518
518
519 Don't try to push extinct changeset
519 Don't try to push extinct changeset
520
520
521 $ hg init ../tmpf
521 $ hg init ../tmpf
522 $ hg out ../tmpf
522 $ hg out ../tmpf
523 comparing with ../tmpf
523 comparing with ../tmpf
524 searching for changes
524 searching for changes
525 0:1f0dee641bb7 (public) [ ] add a
525 0:1f0dee641bb7 (public) [ ] add a
526 1:7c3bad9141dc (public) [ ] add b
526 1:7c3bad9141dc (public) [ ] add b
527 2:245bde4270cd (public) [ ] add original_c
527 2:245bde4270cd (public) [ ] add original_c
528 3:6f9641995072 (draft) [ ] add n3w_3_c
528 3:6f9641995072 (draft) [ ] add n3w_3_c
529 4:94b33453f93b (draft *obsolete*) [ ] add original_d
529 4:94b33453f93b (draft *obsolete*) [ ] add original_d
530 5:cda648ca50f5 (draft unstable) [tip ] add original_e
530 5:cda648ca50f5 (draft unstable) [tip ] add original_e
531 $ hg push ../tmpf -f # -f because be push unstable too
531 $ hg push ../tmpf -f # -f because be push unstable too
532 pushing to ../tmpf
532 pushing to ../tmpf
533 searching for changes
533 searching for changes
534 adding changesets
534 adding changesets
535 adding manifests
535 adding manifests
536 adding file changes
536 adding file changes
537 added 6 changesets with 6 changes to 6 files (+1 heads)
537 added 6 changesets with 6 changes to 6 files (+1 heads)
538 7 new obsolescence markers
538 7 new obsolescence markers
539
539
540 no warning displayed
540 no warning displayed
541
541
542 $ hg push ../tmpf
542 $ hg push ../tmpf
543 pushing to ../tmpf
543 pushing to ../tmpf
544 searching for changes
544 searching for changes
545 no changes found
545 no changes found
546 [1]
546 [1]
547
547
548 Do not warn about new head when the new head is a successors of a remote one
548 Do not warn about new head when the new head is a successors of a remote one
549
549
550 $ hg log -G
550 $ hg log -G
551 @ 5:cda648ca50f5 (draft unstable) [tip ] add original_e
551 @ 5:cda648ca50f5 (draft unstable) [tip ] add original_e
552 |
552 |
553 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d
553 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d
554 |
554 |
555 o 3:6f9641995072 (draft) [ ] add n3w_3_c
555 o 3:6f9641995072 (draft) [ ] add n3w_3_c
556 |
556 |
557 | o 2:245bde4270cd (public) [ ] add original_c
557 | o 2:245bde4270cd (public) [ ] add original_c
558 |/
558 |/
559 o 1:7c3bad9141dc (public) [ ] add b
559 o 1:7c3bad9141dc (public) [ ] add b
560 |
560 |
561 o 0:1f0dee641bb7 (public) [ ] add a
561 o 0:1f0dee641bb7 (public) [ ] add a
562
562
563 $ hg up -q 'desc(n3w_3_c)'
563 $ hg up -q 'desc(n3w_3_c)'
564 $ mkcommit obsolete_e
564 $ mkcommit obsolete_e
565 created new head
565 created new head
566 $ hg debugobsolete `getid 'original_e'` `getid 'obsolete_e'`
566 $ hg debugobsolete `getid 'original_e'` `getid 'obsolete_e'`
567 $ hg outgoing ../tmpf # parasite hg outgoing testin
567 $ hg outgoing ../tmpf # parasite hg outgoing testin
568 comparing with ../tmpf
568 comparing with ../tmpf
569 searching for changes
569 searching for changes
570 6:3de5eca88c00 (draft) [tip ] add obsolete_e
570 6:3de5eca88c00 (draft) [tip ] add obsolete_e
571 $ hg push ../tmpf
571 $ hg push ../tmpf
572 pushing to ../tmpf
572 pushing to ../tmpf
573 searching for changes
573 searching for changes
574 adding changesets
574 adding changesets
575 adding manifests
575 adding manifests
576 adding file changes
576 adding file changes
577 added 1 changesets with 1 changes to 1 files (+1 heads)
577 added 1 changesets with 1 changes to 1 files (+1 heads)
578 1 new obsolescence markers
578 1 new obsolescence markers
579
579
580 test relevance computation
580 test relevance computation
581 ---------------------------------------
581 ---------------------------------------
582
582
583 Checking simple case of "marker relevance".
583 Checking simple case of "marker relevance".
584
584
585
585
586 Reminder of the repo situation
586 Reminder of the repo situation
587
587
588 $ hg log --hidden --graph
588 $ hg log --hidden --graph
589 @ 6:3de5eca88c00 (draft) [tip ] add obsolete_e
589 @ 6:3de5eca88c00 (draft) [tip ] add obsolete_e
590 |
590 |
591 | x 5:cda648ca50f5 (draft *obsolete*) [ ] add original_e
591 | x 5:cda648ca50f5 (draft *obsolete*) [ ] add original_e
592 | |
592 | |
593 | x 4:94b33453f93b (draft *obsolete*) [ ] add original_d
593 | x 4:94b33453f93b (draft *obsolete*) [ ] add original_d
594 |/
594 |/
595 o 3:6f9641995072 (draft) [ ] add n3w_3_c
595 o 3:6f9641995072 (draft) [ ] add n3w_3_c
596 |
596 |
597 | o 2:245bde4270cd (public) [ ] add original_c
597 | o 2:245bde4270cd (public) [ ] add original_c
598 |/
598 |/
599 o 1:7c3bad9141dc (public) [ ] add b
599 o 1:7c3bad9141dc (public) [ ] add b
600 |
600 |
601 o 0:1f0dee641bb7 (public) [ ] add a
601 o 0:1f0dee641bb7 (public) [ ] add a
602
602
603
603
604 List of all markers
604 List of all markers
605
605
606 $ hg debugobsolete
606 $ hg debugobsolete
607 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
607 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
608 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
608 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
609 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
609 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
610 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
610 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
611 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
611 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
612 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
612 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
613 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
613 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
614 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test'} (glob)
614 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test'} (glob)
615
615
616 List of changesets with no chain
616 List of changesets with no chain
617
617
618 $ hg debugobsolete --hidden --rev ::2
618 $ hg debugobsolete --hidden --rev ::2
619
619
620 List of changesets that are included on marker chain
620 List of changesets that are included on marker chain
621
621
622 $ hg debugobsolete --hidden --rev 6
622 $ hg debugobsolete --hidden --rev 6
623 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test'} (glob)
623 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test'} (glob)
624
624
625 List of changesets with a longer chain, (including a pruned children)
625 List of changesets with a longer chain, (including a pruned children)
626
626
627 $ hg debugobsolete --hidden --rev 3
627 $ hg debugobsolete --hidden --rev 3
628 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
628 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
629 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
629 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
630 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
630 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
631 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
631 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
632 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
632 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
633 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
633 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
634 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
634 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
635
635
636 List of both
636 List of both
637
637
638 $ hg debugobsolete --hidden --rev 3::6
638 $ hg debugobsolete --hidden --rev 3::6
639 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
639 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
640 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
640 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
641 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
641 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
642 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
642 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
643 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
643 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
644 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
644 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
645 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test'} (glob)
645 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test'} (glob)
646 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
646 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
647
647
648 List of all markers in JSON
648 List of all markers in JSON
649
649
650 $ hg debugobsolete -Tjson
650 $ hg debugobsolete -Tjson
651 [
651 [
652 {
652 {
653 "date": [1339.0, 0],
653 "date": [1339.0, 0],
654 "flag": 0,
654 "flag": 0,
655 "metadata": {"user": "test"},
655 "metadata": {"user": "test"},
656 "precnode": "1339133913391339133913391339133913391339",
656 "precnode": "1339133913391339133913391339133913391339",
657 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
657 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
658 },
658 },
659 {
659 {
660 "date": [1339.0, 0],
660 "date": [1339.0, 0],
661 "flag": 0,
661 "flag": 0,
662 "metadata": {"user": "test"},
662 "metadata": {"user": "test"},
663 "precnode": "1337133713371337133713371337133713371337",
663 "precnode": "1337133713371337133713371337133713371337",
664 "succnodes": ["5601fb93a350734d935195fee37f4054c529ff39"]
664 "succnodes": ["5601fb93a350734d935195fee37f4054c529ff39"]
665 },
665 },
666 {
666 {
667 "date": [121.0, 120],
667 "date": [121.0, 120],
668 "flag": 12,
668 "flag": 12,
669 "metadata": {"user": "test"},
669 "metadata": {"user": "test"},
670 "precnode": "245bde4270cd1072a27757984f9cda8ba26f08ca",
670 "precnode": "245bde4270cd1072a27757984f9cda8ba26f08ca",
671 "succnodes": ["cdbce2fbb16313928851e97e0d85413f3f7eb77f"]
671 "succnodes": ["cdbce2fbb16313928851e97e0d85413f3f7eb77f"]
672 },
672 },
673 {
673 {
674 "date": [1338.0, 0],
674 "date": [1338.0, 0],
675 "flag": 1,
675 "flag": 1,
676 "metadata": {"user": "test"},
676 "metadata": {"user": "test"},
677 "precnode": "5601fb93a350734d935195fee37f4054c529ff39",
677 "precnode": "5601fb93a350734d935195fee37f4054c529ff39",
678 "succnodes": ["6f96419950729f3671185b847352890f074f7557"]
678 "succnodes": ["6f96419950729f3671185b847352890f074f7557"]
679 },
679 },
680 {
680 {
681 "date": [1338.0, 0],
681 "date": [1338.0, 0],
682 "flag": 0,
682 "flag": 0,
683 "metadata": {"user": "test"},
683 "metadata": {"user": "test"},
684 "precnode": "ca819180edb99ed25ceafb3e9584ac287e240b00",
684 "precnode": "ca819180edb99ed25ceafb3e9584ac287e240b00",
685 "succnodes": ["1337133713371337133713371337133713371337"]
685 "succnodes": ["1337133713371337133713371337133713371337"]
686 },
686 },
687 {
687 {
688 "date": [1337.0, 0],
688 "date": [1337.0, 0],
689 "flag": 0,
689 "flag": 0,
690 "metadata": {"user": "test"},
690 "metadata": {"user": "test"},
691 "precnode": "cdbce2fbb16313928851e97e0d85413f3f7eb77f",
691 "precnode": "cdbce2fbb16313928851e97e0d85413f3f7eb77f",
692 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
692 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
693 },
693 },
694 {
694 {
695 "date": [0.0, 0],
695 "date": [0.0, 0],
696 "flag": 0,
696 "flag": 0,
697 "metadata": {"user": "test"},
697 "metadata": {"user": "test"},
698 "parentnodes": ["6f96419950729f3671185b847352890f074f7557"],
698 "parentnodes": ["6f96419950729f3671185b847352890f074f7557"],
699 "precnode": "94b33453f93bdb8d457ef9b770851a618bf413e1",
699 "precnode": "94b33453f93bdb8d457ef9b770851a618bf413e1",
700 "succnodes": []
700 "succnodes": []
701 },
701 },
702 {
702 {
703 "date": *, (glob)
703 "date": *, (glob)
704 "flag": 0,
704 "flag": 0,
705 "metadata": {"user": "test"},
705 "metadata": {"user": "test"},
706 "precnode": "cda648ca50f50482b7055c0b0c4c117bba6733d9",
706 "precnode": "cda648ca50f50482b7055c0b0c4c117bba6733d9",
707 "succnodes": ["3de5eca88c00aa039da7399a220f4a5221faa585"]
707 "succnodes": ["3de5eca88c00aa039da7399a220f4a5221faa585"]
708 }
708 }
709 ]
709 ]
710
710
711 Template keywords
711 Template keywords
712
712
713 $ hg debugobsolete -r6 -T '{succnodes % "{node|short}"} {date|shortdate}\n'
713 $ hg debugobsolete -r6 -T '{succnodes % "{node|short}"} {date|shortdate}\n'
714 3de5eca88c00 ????-??-?? (glob)
714 3de5eca88c00 ????-??-?? (glob)
715 $ hg debugobsolete -r6 -T '{join(metadata % "{key}={value}", " ")}\n'
715 $ hg debugobsolete -r6 -T '{join(metadata % "{key}={value}", " ")}\n'
716 user=test
716 user=test
717 $ hg debugobsolete -r6 -T '{metadata}\n'
717 $ hg debugobsolete -r6 -T '{metadata}\n'
718 'user': 'test'
718 'user': 'test'
719 $ hg debugobsolete -r6 -T '{flag} {get(metadata, "user")}\n'
719 $ hg debugobsolete -r6 -T '{flag} {get(metadata, "user")}\n'
720 0 test
720 0 test
721
721
722 Test the debug output for exchange
722 Test the debug output for exchange
723 ----------------------------------
723 ----------------------------------
724
724
725 $ hg pull ../tmpb --config 'experimental.obsmarkers-exchange-debug=True' # bundle2
725 $ hg pull ../tmpb --config 'experimental.obsmarkers-exchange-debug=True' # bundle2
726 pulling from ../tmpb
726 pulling from ../tmpb
727 searching for changes
727 searching for changes
728 no changes found
728 no changes found
729 obsmarker-exchange: 346 bytes received
729 obsmarker-exchange: 346 bytes received
730
730
731 check hgweb does not explode
731 check hgweb does not explode
732 ====================================
732 ====================================
733
733
734 $ hg unbundle $TESTDIR/bundles/hgweb+obs.hg
734 $ hg unbundle $TESTDIR/bundles/hgweb+obs.hg
735 adding changesets
735 adding changesets
736 adding manifests
736 adding manifests
737 adding file changes
737 adding file changes
738 added 62 changesets with 63 changes to 9 files (+60 heads)
738 added 62 changesets with 63 changes to 9 files (+60 heads)
739 (run 'hg heads .' to see heads, 'hg merge' to merge)
739 (run 'hg heads .' to see heads, 'hg merge' to merge)
740 $ for node in `hg log -r 'desc(babar_)' --template '{node}\n'`;
740 $ for node in `hg log -r 'desc(babar_)' --template '{node}\n'`;
741 > do
741 > do
742 > hg debugobsolete $node
742 > hg debugobsolete $node
743 > done
743 > done
744 $ hg up tip
744 $ hg up tip
745 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
745 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
746
746
747 #if serve
747 #if serve
748
748
749 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
749 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
750 $ cat hg.pid >> $DAEMON_PIDS
750 $ cat hg.pid >> $DAEMON_PIDS
751
751
752 check changelog view
752 check changelog view
753
753
754 $ get-with-headers.py --headeronly localhost:$HGPORT 'shortlog/'
754 $ get-with-headers.py --headeronly localhost:$HGPORT 'shortlog/'
755 200 Script output follows
755 200 Script output follows
756
756
757 check graph view
757 check graph view
758
758
759 $ get-with-headers.py --headeronly localhost:$HGPORT 'graph'
759 $ get-with-headers.py --headeronly localhost:$HGPORT 'graph'
760 200 Script output follows
760 200 Script output follows
761
761
762 check filelog view
762 check filelog view
763
763
764 $ get-with-headers.py --headeronly localhost:$HGPORT 'log/'`hg log -r . -T "{node}"`/'babar'
764 $ get-with-headers.py --headeronly localhost:$HGPORT 'log/'`hg log -r . -T "{node}"`/'babar'
765 200 Script output follows
765 200 Script output follows
766
766
767 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/68'
767 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/68'
768 200 Script output follows
768 200 Script output follows
769 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
769 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
770 404 Not Found
770 404 Not Found
771 [1]
771 [1]
772
772
773 check that web.view config option:
773 check that web.view config option:
774
774
775 $ killdaemons.py hg.pid
775 $ killdaemons.py hg.pid
776 $ cat >> .hg/hgrc << EOF
776 $ cat >> .hg/hgrc << EOF
777 > [web]
777 > [web]
778 > view=all
778 > view=all
779 > EOF
779 > EOF
780 $ wait
780 $ wait
781 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
781 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
782 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
782 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
783 200 Script output follows
783 200 Script output follows
784 $ killdaemons.py hg.pid
784 $ killdaemons.py hg.pid
785
785
786 Checking _enable=False warning if obsolete marker exists
786 Checking _enable=False warning if obsolete marker exists
787
787
788 $ echo '[experimental]' >> $HGRCPATH
788 $ echo '[experimental]' >> $HGRCPATH
789 $ echo "evolution=" >> $HGRCPATH
789 $ echo "evolution=" >> $HGRCPATH
790 $ hg log -r tip
790 $ hg log -r tip
791 obsolete feature not enabled but 68 markers found!
791 obsolete feature not enabled but 68 markers found!
792 68:c15e9edfca13 (draft) [tip ] add celestine
792 68:c15e9edfca13 (draft) [tip ] add celestine
793
793
794 reenable for later test
794 reenable for later test
795
795
796 $ echo '[experimental]' >> $HGRCPATH
796 $ echo '[experimental]' >> $HGRCPATH
797 $ echo "evolution=createmarkers,exchange" >> $HGRCPATH
797 $ echo "evolution=createmarkers,exchange" >> $HGRCPATH
798
798
799 $ rm hg.pid access.log errors.log
799 $ rm hg.pid access.log errors.log
800 #endif
800 #endif
801
801
802 Several troubles on the same changeset (create an unstable and bumped changeset)
802 Several troubles on the same changeset (create an unstable and bumped changeset)
803
803
804 $ hg debugobsolete `getid obsolete_e`
804 $ hg debugobsolete `getid obsolete_e`
805 $ hg debugobsolete `getid original_c` `getid babar`
805 $ hg debugobsolete `getid original_c` `getid babar`
806 $ hg log --config ui.logtemplate= -r 'bumped() and unstable()'
806 $ hg log --config ui.logtemplate= -r 'bumped() and unstable()'
807 changeset: 7:50c51b361e60
807 changeset: 7:50c51b361e60
808 user: test
808 user: test
809 date: Thu Jan 01 00:00:00 1970 +0000
809 date: Thu Jan 01 00:00:00 1970 +0000
810 trouble: unstable, bumped
810 trouble: unstable, bumped
811 summary: add babar
811 summary: add babar
812
812
813
813
814 test the "obsolete" templatekw
814 test the "obsolete" templatekw
815
815
816 $ hg log -r 'obsolete()'
816 $ hg log -r 'obsolete()'
817 6:3de5eca88c00 (draft *obsolete*) [ ] add obsolete_e
817 6:3de5eca88c00 (draft *obsolete*) [ ] add obsolete_e
818
818
819 test the "troubles" templatekw
819 test the "troubles" templatekw
820
820
821 $ hg log -r 'bumped() and unstable()'
821 $ hg log -r 'bumped() and unstable()'
822 7:50c51b361e60 (draft unstable bumped) [ ] add babar
822 7:50c51b361e60 (draft unstable bumped) [ ] add babar
823
823
824 test the default cmdline template
824 test the default cmdline template
825
825
826 $ hg log -T default -r 'bumped()'
826 $ hg log -T default -r 'bumped()'
827 changeset: 7:50c51b361e60
827 changeset: 7:50c51b361e60
828 user: test
828 user: test
829 date: Thu Jan 01 00:00:00 1970 +0000
829 date: Thu Jan 01 00:00:00 1970 +0000
830 trouble: unstable, bumped
830 trouble: unstable, bumped
831 summary: add babar
831 summary: add babar
832
832
833 $ hg log -T default -r 'obsolete()'
833 $ hg log -T default -r 'obsolete()'
834 changeset: 6:3de5eca88c00
834 changeset: 6:3de5eca88c00
835 parent: 3:6f9641995072
835 parent: 3:6f9641995072
836 user: test
836 user: test
837 date: Thu Jan 01 00:00:00 1970 +0000
837 date: Thu Jan 01 00:00:00 1970 +0000
838 summary: add obsolete_e
838 summary: add obsolete_e
839
839
840
840
841 test summary output
841 test summary output
842
842
843 $ hg up -r 'bumped() and unstable()'
843 $ hg up -r 'bumped() and unstable()'
844 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
844 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
845 $ hg summary
845 $ hg summary
846 parent: 7:50c51b361e60 (unstable, bumped)
846 parent: 7:50c51b361e60 (unstable, bumped)
847 add babar
847 add babar
848 branch: default
848 branch: default
849 commit: (clean)
849 commit: (clean)
850 update: 2 new changesets (update)
850 update: 2 new changesets (update)
851 phases: 4 draft
851 phases: 4 draft
852 unstable: 2 changesets
852 unstable: 2 changesets
853 bumped: 1 changesets
853 bumped: 1 changesets
854 $ hg up -r 'obsolete()'
854 $ hg up -r 'obsolete()'
855 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
855 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
856 $ hg summary
856 $ hg summary
857 parent: 6:3de5eca88c00 (obsolete)
857 parent: 6:3de5eca88c00 (obsolete)
858 add obsolete_e
858 add obsolete_e
859 branch: default
859 branch: default
860 commit: (clean)
860 commit: (clean)
861 update: 3 new changesets (update)
861 update: 3 new changesets (update)
862 phases: 4 draft
862 phases: 4 draft
863 unstable: 2 changesets
863 unstable: 2 changesets
864 bumped: 1 changesets
864 bumped: 1 changesets
865
865
866 Test incoming/outcoming with changesets obsoleted remotely, known locally
866 Test incoming/outcoming with changesets obsoleted remotely, known locally
867 ===============================================================================
867 ===============================================================================
868
868
869 This test issue 3805
869 This test issue 3805
870
870
871 $ hg init repo-issue3805
871 $ hg init repo-issue3805
872 $ cd repo-issue3805
872 $ cd repo-issue3805
873 $ echo "base" > base
873 $ echo "base" > base
874 $ hg ci -Am "base"
874 $ hg ci -Am "base"
875 adding base
875 adding base
876 $ echo "foo" > foo
876 $ echo "foo" > foo
877 $ hg ci -Am "A"
877 $ hg ci -Am "A"
878 adding foo
878 adding foo
879 $ hg clone . ../other-issue3805
879 $ hg clone . ../other-issue3805
880 updating to branch default
880 updating to branch default
881 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
881 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
882 $ echo "bar" >> foo
882 $ echo "bar" >> foo
883 $ hg ci --amend
883 $ hg ci --amend
884 $ cd ../other-issue3805
884 $ cd ../other-issue3805
885 $ hg log -G
885 $ hg log -G
886 @ 1:29f0c6921ddd (draft) [tip ] A
886 @ 1:29f0c6921ddd (draft) [tip ] A
887 |
887 |
888 o 0:d20a80d4def3 (draft) [ ] base
888 o 0:d20a80d4def3 (draft) [ ] base
889
889
890 $ hg log -G -R ../repo-issue3805
890 $ hg log -G -R ../repo-issue3805
891 @ 3:323a9c3ddd91 (draft) [tip ] A
891 @ 3:323a9c3ddd91 (draft) [tip ] A
892 |
892 |
893 o 0:d20a80d4def3 (draft) [ ] base
893 o 0:d20a80d4def3 (draft) [ ] base
894
894
895 $ hg incoming
895 $ hg incoming
896 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
896 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
897 searching for changes
897 searching for changes
898 3:323a9c3ddd91 (draft) [tip ] A
898 3:323a9c3ddd91 (draft) [tip ] A
899 $ hg incoming --bundle ../issue3805.hg
899 $ hg incoming --bundle ../issue3805.hg
900 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
900 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
901 searching for changes
901 searching for changes
902 3:323a9c3ddd91 (draft) [tip ] A
902 3:323a9c3ddd91 (draft) [tip ] A
903 $ hg outgoing
903 $ hg outgoing
904 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
904 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
905 searching for changes
905 searching for changes
906 1:29f0c6921ddd (draft) [tip ] A
906 1:29f0c6921ddd (draft) [tip ] A
907
907
908 #if serve
908 #if serve
909
909
910 $ hg serve -R ../repo-issue3805 -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
910 $ hg serve -R ../repo-issue3805 -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
911 $ cat hg.pid >> $DAEMON_PIDS
911 $ cat hg.pid >> $DAEMON_PIDS
912
912
913 $ hg incoming http://localhost:$HGPORT
913 $ hg incoming http://localhost:$HGPORT
914 comparing with http://localhost:$HGPORT/
914 comparing with http://localhost:$HGPORT/
915 searching for changes
915 searching for changes
916 2:323a9c3ddd91 (draft) [tip ] A
916 2:323a9c3ddd91 (draft) [tip ] A
917 $ hg outgoing http://localhost:$HGPORT
917 $ hg outgoing http://localhost:$HGPORT
918 comparing with http://localhost:$HGPORT/
918 comparing with http://localhost:$HGPORT/
919 searching for changes
919 searching for changes
920 1:29f0c6921ddd (draft) [tip ] A
920 1:29f0c6921ddd (draft) [tip ] A
921
921
922 $ killdaemons.py
922 $ killdaemons.py
923
923
924 #endif
924 #endif
925
925
926 This test issue 3814
926 This test issue 3814
927
927
928 (nothing to push but locally hidden changeset)
928 (nothing to push but locally hidden changeset)
929
929
930 $ cd ..
930 $ cd ..
931 $ hg init repo-issue3814
931 $ hg init repo-issue3814
932 $ cd repo-issue3805
932 $ cd repo-issue3805
933 $ hg push -r 323a9c3ddd91 ../repo-issue3814
933 $ hg push -r 323a9c3ddd91 ../repo-issue3814
934 pushing to ../repo-issue3814
934 pushing to ../repo-issue3814
935 searching for changes
935 searching for changes
936 adding changesets
936 adding changesets
937 adding manifests
937 adding manifests
938 adding file changes
938 adding file changes
939 added 2 changesets with 2 changes to 2 files
939 added 2 changesets with 2 changes to 2 files
940 2 new obsolescence markers
940 2 new obsolescence markers
941 $ hg out ../repo-issue3814
941 $ hg out ../repo-issue3814
942 comparing with ../repo-issue3814
942 comparing with ../repo-issue3814
943 searching for changes
943 searching for changes
944 no changes found
944 no changes found
945 [1]
945 [1]
946
946
947 Test that a local tag blocks a changeset from being hidden
947 Test that a local tag blocks a changeset from being hidden
948
948
949 $ hg tag -l visible -r 1 --hidden
949 $ hg tag -l visible -r 1 --hidden
950 $ hg log -G
950 $ hg log -G
951 @ 3:323a9c3ddd91 (draft) [tip ] A
951 @ 3:323a9c3ddd91 (draft) [tip ] A
952 |
952 |
953 | x 1:29f0c6921ddd (draft *obsolete*) [visible ] A
953 | x 1:29f0c6921ddd (draft *obsolete*) [visible ] A
954 |/
954 |/
955 o 0:d20a80d4def3 (draft) [ ] base
955 o 0:d20a80d4def3 (draft) [ ] base
956
956
957 Test that removing a local tag does not cause some commands to fail
957 Test that removing a local tag does not cause some commands to fail
958
958
959 $ hg tag -l -r tip tiptag
959 $ hg tag -l -r tip tiptag
960 $ hg tags
960 $ hg tags
961 tiptag 3:323a9c3ddd91
961 tiptag 3:323a9c3ddd91
962 tip 3:323a9c3ddd91
962 tip 3:323a9c3ddd91
963 visible 1:29f0c6921ddd
963 visible 1:29f0c6921ddd
964 $ hg --config extensions.strip= strip -r tip --no-backup
964 $ hg --config extensions.strip= strip -r tip --no-backup
965 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
965 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
966 $ hg tags
966 $ hg tags
967 visible 1:29f0c6921ddd
967 visible 1:29f0c6921ddd
968 tip 1:29f0c6921ddd
968 tip 1:29f0c6921ddd
969
969
970 Test bundle overlay onto hidden revision
970 Test bundle overlay onto hidden revision
971
971
972 $ cd ..
972 $ cd ..
973 $ hg init repo-bundleoverlay
973 $ hg init repo-bundleoverlay
974 $ cd repo-bundleoverlay
974 $ cd repo-bundleoverlay
975 $ echo "A" > foo
975 $ echo "A" > foo
976 $ hg ci -Am "A"
976 $ hg ci -Am "A"
977 adding foo
977 adding foo
978 $ echo "B" >> foo
978 $ echo "B" >> foo
979 $ hg ci -m "B"
979 $ hg ci -m "B"
980 $ hg up 0
980 $ hg up 0
981 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
981 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
982 $ echo "C" >> foo
982 $ echo "C" >> foo
983 $ hg ci -m "C"
983 $ hg ci -m "C"
984 created new head
984 created new head
985 $ hg log -G
985 $ hg log -G
986 @ 2:c186d7714947 (draft) [tip ] C
986 @ 2:c186d7714947 (draft) [tip ] C
987 |
987 |
988 | o 1:44526ebb0f98 (draft) [ ] B
988 | o 1:44526ebb0f98 (draft) [ ] B
989 |/
989 |/
990 o 0:4b34ecfb0d56 (draft) [ ] A
990 o 0:4b34ecfb0d56 (draft) [ ] A
991
991
992
992
993 $ hg clone -r1 . ../other-bundleoverlay
993 $ hg clone -r1 . ../other-bundleoverlay
994 adding changesets
994 adding changesets
995 adding manifests
995 adding manifests
996 adding file changes
996 adding file changes
997 added 2 changesets with 2 changes to 1 files
997 added 2 changesets with 2 changes to 1 files
998 updating to branch default
998 updating to branch default
999 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
999 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1000 $ cd ../other-bundleoverlay
1000 $ cd ../other-bundleoverlay
1001 $ echo "B+" >> foo
1001 $ echo "B+" >> foo
1002 $ hg ci --amend -m "B+"
1002 $ hg ci --amend -m "B+"
1003 $ hg log -G --hidden
1003 $ hg log -G --hidden
1004 @ 3:b7d587542d40 (draft) [tip ] B+
1004 @ 3:b7d587542d40 (draft) [tip ] B+
1005 |
1005 |
1006 | x 2:eb95e9297e18 (draft *obsolete*) [ ] temporary amend commit for 44526ebb0f98
1006 | x 2:eb95e9297e18 (draft *obsolete*) [ ] temporary amend commit for 44526ebb0f98
1007 | |
1007 | |
1008 | x 1:44526ebb0f98 (draft *obsolete*) [ ] B
1008 | x 1:44526ebb0f98 (draft *obsolete*) [ ] B
1009 |/
1009 |/
1010 o 0:4b34ecfb0d56 (draft) [ ] A
1010 o 0:4b34ecfb0d56 (draft) [ ] A
1011
1011
1012
1012
1013 $ hg incoming ../repo-bundleoverlay --bundle ../bundleoverlay.hg
1013 $ hg incoming ../repo-bundleoverlay --bundle ../bundleoverlay.hg
1014 comparing with ../repo-bundleoverlay
1014 comparing with ../repo-bundleoverlay
1015 searching for changes
1015 searching for changes
1016 1:44526ebb0f98 (draft) [ ] B
1016 1:44526ebb0f98 (draft) [ ] B
1017 2:c186d7714947 (draft) [tip ] C
1017 2:c186d7714947 (draft) [tip ] C
1018 $ hg log -G -R ../bundleoverlay.hg
1018 $ hg log -G -R ../bundleoverlay.hg
1019 o 4:c186d7714947 (draft) [tip ] C
1019 o 4:c186d7714947 (draft) [tip ] C
1020 |
1020 |
1021 | @ 3:b7d587542d40 (draft) [ ] B+
1021 | @ 3:b7d587542d40 (draft) [ ] B+
1022 |/
1022 |/
1023 o 0:4b34ecfb0d56 (draft) [ ] A
1023 o 0:4b34ecfb0d56 (draft) [ ] A
1024
1024
1025
1025
1026 #if serve
1026 #if serve
1027
1027
1028 Test issue 4506
1028 Test issue 4506
1029
1029
1030 $ cd ..
1030 $ cd ..
1031 $ hg init repo-issue4506
1031 $ hg init repo-issue4506
1032 $ cd repo-issue4506
1032 $ cd repo-issue4506
1033 $ echo "0" > foo
1033 $ echo "0" > foo
1034 $ hg add foo
1034 $ hg add foo
1035 $ hg ci -m "content-0"
1035 $ hg ci -m "content-0"
1036
1036
1037 $ hg up null
1037 $ hg up null
1038 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1038 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1039 $ echo "1" > bar
1039 $ echo "1" > bar
1040 $ hg add bar
1040 $ hg add bar
1041 $ hg ci -m "content-1"
1041 $ hg ci -m "content-1"
1042 created new head
1042 created new head
1043 $ hg up 0
1043 $ hg up 0
1044 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1044 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1045 $ hg graft 1
1045 $ hg graft 1
1046 grafting 1:1c9eddb02162 "content-1" (tip)
1046 grafting 1:1c9eddb02162 "content-1" (tip)
1047
1047
1048 $ hg debugobsolete `hg log -r1 -T'{node}'` `hg log -r2 -T'{node}'`
1048 $ hg debugobsolete `hg log -r1 -T'{node}'` `hg log -r2 -T'{node}'`
1049
1049
1050 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1050 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1051 $ cat hg.pid >> $DAEMON_PIDS
1051 $ cat hg.pid >> $DAEMON_PIDS
1052
1052
1053 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/1'
1053 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/1'
1054 404 Not Found
1054 404 Not Found
1055 [1]
1055 [1]
1056 $ get-with-headers.py --headeronly localhost:$HGPORT 'file/tip/bar'
1056 $ get-with-headers.py --headeronly localhost:$HGPORT 'file/tip/bar'
1057 200 Script output follows
1057 200 Script output follows
1058 $ get-with-headers.py --headeronly localhost:$HGPORT 'annotate/tip/bar'
1058 $ get-with-headers.py --headeronly localhost:$HGPORT 'annotate/tip/bar'
1059 200 Script output follows
1059 200 Script output follows
1060
1060
1061 $ killdaemons.py
1061 $ killdaemons.py
1062
1062
1063 #endif
1063 #endif
1064
1064
1065 Test heads computation on pending index changes with obsolescence markers
1065 Test heads computation on pending index changes with obsolescence markers
1066 $ cd ..
1066 $ cd ..
1067 $ cat >$TESTTMP/test_extension.py << EOF
1067 $ cat >$TESTTMP/test_extension.py << EOF
1068 > from mercurial import cmdutil, registrar
1068 > from mercurial import cmdutil, registrar
1069 > from mercurial.i18n import _
1069 > from mercurial.i18n import _
1070 >
1070 >
1071 > cmdtable = {}
1071 > cmdtable = {}
1072 > command = registrar.command(cmdtable)
1072 > command = registrar.command(cmdtable)
1073 > @command("amendtransient",[], _('hg amendtransient [rev]'))
1073 > @command("amendtransient",[], _('hg amendtransient [rev]'))
1074 > def amend(ui, repo, *pats, **opts):
1074 > def amend(ui, repo, *pats, **opts):
1075 > def commitfunc(ui, repo, message, match, opts):
1075 > def commitfunc(ui, repo, message, match, opts):
1076 > return repo.commit(message, repo['.'].user(), repo['.'].date(), match)
1076 > return repo.commit(message, repo['.'].user(), repo['.'].date(), match)
1077 > opts['message'] = 'Test'
1077 > opts['message'] = 'Test'
1078 > opts['logfile'] = None
1078 > opts['logfile'] = None
1079 > cmdutil.amend(ui, repo, commitfunc, repo['.'], {}, pats, opts)
1079 > cmdutil.amend(ui, repo, commitfunc, repo['.'], {}, pats, opts)
1080 > ui.write('%s\n' % repo.changelog.headrevs())
1080 > ui.write('%s\n' % repo.changelog.headrevs())
1081 > EOF
1081 > EOF
1082 $ cat >> $HGRCPATH << EOF
1082 $ cat >> $HGRCPATH << EOF
1083 > [extensions]
1083 > [extensions]
1084 > testextension=$TESTTMP/test_extension.py
1084 > testextension=$TESTTMP/test_extension.py
1085 > EOF
1085 > EOF
1086 $ hg init repo-issue-nativerevs-pending-changes
1086 $ hg init repo-issue-nativerevs-pending-changes
1087 $ cd repo-issue-nativerevs-pending-changes
1087 $ cd repo-issue-nativerevs-pending-changes
1088 $ mkcommit a
1088 $ mkcommit a
1089 $ mkcommit b
1089 $ mkcommit b
1090 $ hg up ".^"
1090 $ hg up ".^"
1091 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1091 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1092 $ echo aa > a
1092 $ echo aa > a
1093 $ hg amendtransient
1093 $ hg amendtransient
1094 [1, 3]
1094 [1, 3]
1095
1095
1096 Check that corrupted hidden cache does not crash
1096 Check that corrupted hidden cache does not crash
1097
1097
1098 $ printf "" > .hg/cache/hidden
1098 $ printf "" > .hg/cache/hidden
1099 $ hg log -r . -T '{node}' --debug
1099 $ hg log -r . -T '{node}' --debug
1100 corrupted hidden cache
1100 corrupted hidden cache
1101 8fd96dfc63e51ed5a8af1bec18eb4b19dbf83812 (no-eol)
1101 8fd96dfc63e51ed5a8af1bec18eb4b19dbf83812 (no-eol)
1102 $ hg log -r . -T '{node}' --debug
1102 $ hg log -r . -T '{node}' --debug
1103 8fd96dfc63e51ed5a8af1bec18eb4b19dbf83812 (no-eol)
1103 8fd96dfc63e51ed5a8af1bec18eb4b19dbf83812 (no-eol)
1104
1104
1105 #if unix-permissions
1105 #if unix-permissions
1106 Check that wrong hidden cache permission does not crash
1106 Check that wrong hidden cache permission does not crash
1107
1107
1108 $ chmod 000 .hg/cache/hidden
1108 $ chmod 000 .hg/cache/hidden
1109 $ hg log -r . -T '{node}' --debug
1109 $ hg log -r . -T '{node}' --debug
1110 cannot read hidden cache
1110 cannot read hidden cache
1111 error writing hidden changesets cache
1111 error writing hidden changesets cache
1112 8fd96dfc63e51ed5a8af1bec18eb4b19dbf83812 (no-eol)
1112 8fd96dfc63e51ed5a8af1bec18eb4b19dbf83812 (no-eol)
1113 #endif
1113 #endif
1114
1114
1115 Test cache consistency for the visible filter
1115 Test cache consistency for the visible filter
1116 1) We want to make sure that the cached filtered revs are invalidated when
1116 1) We want to make sure that the cached filtered revs are invalidated when
1117 bookmarks change
1117 bookmarks change
1118 $ cd ..
1118 $ cd ..
1119 $ cat >$TESTTMP/test_extension.py << EOF
1119 $ cat >$TESTTMP/test_extension.py << EOF
1120 > import weakref
1120 > import weakref
1121 > from mercurial import cmdutil, extensions, bookmarks, repoview
1121 > from mercurial import cmdutil, extensions, bookmarks, repoview
1122 > def _bookmarkchanged(orig, bkmstoreinst, *args, **kwargs):
1122 > def _bookmarkchanged(orig, bkmstoreinst, *args, **kwargs):
1123 > reporef = weakref.ref(bkmstoreinst._repo)
1123 > reporef = weakref.ref(bkmstoreinst._repo)
1124 > def trhook(tr):
1124 > def trhook(tr):
1125 > repo = reporef()
1125 > repo = reporef()
1126 > hidden1 = repoview.computehidden(repo)
1126 > hidden1 = repoview.computehidden(repo)
1127 > hidden = repoview.filterrevs(repo, 'visible')
1127 > hidden = repoview.filterrevs(repo, 'visible')
1128 > if sorted(hidden1) != sorted(hidden):
1128 > if sorted(hidden1) != sorted(hidden):
1129 > print "cache inconsistency"
1129 > print "cache inconsistency"
1130 > bkmstoreinst._repo.currenttransaction().addpostclose('test_extension', trhook)
1130 > bkmstoreinst._repo.currenttransaction().addpostclose('test_extension', trhook)
1131 > orig(bkmstoreinst, *args, **kwargs)
1131 > orig(bkmstoreinst, *args, **kwargs)
1132 > def extsetup(ui):
1132 > def extsetup(ui):
1133 > extensions.wrapfunction(bookmarks.bmstore, 'recordchange',
1133 > extensions.wrapfunction(bookmarks.bmstore, 'recordchange',
1134 > _bookmarkchanged)
1134 > _bookmarkchanged)
1135 > EOF
1135 > EOF
1136
1136
1137 $ hg init repo-cache-inconsistency
1137 $ hg init repo-cache-inconsistency
1138 $ cd repo-issue-nativerevs-pending-changes
1138 $ cd repo-issue-nativerevs-pending-changes
1139 $ mkcommit a
1139 $ mkcommit a
1140 a already tracked!
1140 a already tracked!
1141 $ mkcommit b
1141 $ mkcommit b
1142 $ hg id
1142 $ hg id
1143 13bedc178fce tip
1143 13bedc178fce tip
1144 $ echo "hello" > b
1144 $ echo "hello" > b
1145 $ hg commit --amend -m "message"
1145 $ hg commit --amend -m "message"
1146 $ hg book bookb -r 13bedc178fce --hidden
1146 $ hg book bookb -r 13bedc178fce --hidden
1147 $ hg log -r 13bedc178fce
1147 $ hg log -r 13bedc178fce
1148 5:13bedc178fce (draft *obsolete*) [ bookb] add b
1148 5:13bedc178fce (draft *obsolete*) [ bookb] add b
1149 $ hg book -d bookb
1149 $ hg book -d bookb
1150 $ hg log -r 13bedc178fce
1150 $ hg log -r 13bedc178fce
1151 abort: hidden revision '13bedc178fce'!
1151 abort: hidden revision '13bedc178fce'!
1152 (use --hidden to access hidden revisions)
1152 (use --hidden to access hidden revisions)
1153 [255]
1153 [255]
1154
1154
1155 Empty out the test extension, as it isn't compatible with later parts
1155 Empty out the test extension, as it isn't compatible with later parts
1156 of the test.
1156 of the test.
1157 $ echo > $TESTTMP/test_extension.py
1157 $ echo > $TESTTMP/test_extension.py
1158
1158
1159 Test ability to pull changeset with locally applying obsolescence markers
1159 Test ability to pull changeset with locally applying obsolescence markers
1160 (issue4945)
1160 (issue4945)
1161
1161
1162 $ cd ..
1162 $ cd ..
1163 $ hg init issue4845
1163 $ hg init issue4845
1164 $ cd issue4845
1164 $ cd issue4845
1165
1165
1166 $ echo foo > f0
1166 $ echo foo > f0
1167 $ hg add f0
1167 $ hg add f0
1168 $ hg ci -m '0'
1168 $ hg ci -m '0'
1169 $ echo foo > f1
1169 $ echo foo > f1
1170 $ hg add f1
1170 $ hg add f1
1171 $ hg ci -m '1'
1171 $ hg ci -m '1'
1172 $ echo foo > f2
1172 $ echo foo > f2
1173 $ hg add f2
1173 $ hg add f2
1174 $ hg ci -m '2'
1174 $ hg ci -m '2'
1175
1175
1176 $ echo bar > f2
1176 $ echo bar > f2
1177 $ hg commit --amend --config experimetnal.evolution=createmarkers
1177 $ hg commit --amend --config experimetnal.evolution=createmarkers
1178 $ hg log -G
1178 $ hg log -G
1179 @ 4:b0551702f918 (draft) [tip ] 2
1179 @ 4:b0551702f918 (draft) [tip ] 2
1180 |
1180 |
1181 o 1:e016b03fd86f (draft) [ ] 1
1181 o 1:e016b03fd86f (draft) [ ] 1
1182 |
1182 |
1183 o 0:a78f55e5508c (draft) [ ] 0
1183 o 0:a78f55e5508c (draft) [ ] 0
1184
1184
1185 $ hg log -G --hidden
1185 $ hg log -G --hidden
1186 @ 4:b0551702f918 (draft) [tip ] 2
1186 @ 4:b0551702f918 (draft) [tip ] 2
1187 |
1187 |
1188 | x 3:f27abbcc1f77 (draft *obsolete*) [ ] temporary amend commit for e008cf283490
1188 | x 3:f27abbcc1f77 (draft *obsolete*) [ ] temporary amend commit for e008cf283490
1189 | |
1189 | |
1190 | x 2:e008cf283490 (draft *obsolete*) [ ] 2
1190 | x 2:e008cf283490 (draft *obsolete*) [ ] 2
1191 |/
1191 |/
1192 o 1:e016b03fd86f (draft) [ ] 1
1192 o 1:e016b03fd86f (draft) [ ] 1
1193 |
1193 |
1194 o 0:a78f55e5508c (draft) [ ] 0
1194 o 0:a78f55e5508c (draft) [ ] 0
1195
1195
1196
1196
1197 $ hg strip -r 1 --config extensions.strip=
1197 $ hg strip -r 1 --config extensions.strip=
1198 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1198 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1199 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e016b03fd86f-c41c6bcc-backup.hg (glob)
1199 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e016b03fd86f-c41c6bcc-backup.hg (glob)
1200 $ hg log -G
1200 $ hg log -G
1201 @ 0:a78f55e5508c (draft) [tip ] 0
1201 @ 0:a78f55e5508c (draft) [tip ] 0
1202
1202
1203 $ hg log -G --hidden
1203 $ hg log -G --hidden
1204 @ 0:a78f55e5508c (draft) [tip ] 0
1204 @ 0:a78f55e5508c (draft) [tip ] 0
1205
1205
1206
1206
1207 $ hg pull .hg/strip-backup/*
1207 $ hg pull .hg/strip-backup/*
1208 pulling from .hg/strip-backup/e016b03fd86f-c41c6bcc-backup.hg
1208 pulling from .hg/strip-backup/e016b03fd86f-c41c6bcc-backup.hg
1209 searching for changes
1209 searching for changes
1210 adding changesets
1210 adding changesets
1211 adding manifests
1211 adding manifests
1212 adding file changes
1212 adding file changes
1213 added 2 changesets with 2 changes to 2 files
1213 added 2 changesets with 2 changes to 2 files
1214 (run 'hg update' to get a working copy)
1214 (run 'hg update' to get a working copy)
1215 $ hg log -G
1215 $ hg log -G
1216 o 2:b0551702f918 (draft) [tip ] 2
1216 o 2:b0551702f918 (draft) [tip ] 2
1217 |
1217 |
1218 o 1:e016b03fd86f (draft) [ ] 1
1218 o 1:e016b03fd86f (draft) [ ] 1
1219 |
1219 |
1220 @ 0:a78f55e5508c (draft) [ ] 0
1220 @ 0:a78f55e5508c (draft) [ ] 0
1221
1221
1222 $ hg log -G --hidden
1222 $ hg log -G --hidden
1223 o 2:b0551702f918 (draft) [tip ] 2
1223 o 2:b0551702f918 (draft) [tip ] 2
1224 |
1224 |
1225 o 1:e016b03fd86f (draft) [ ] 1
1225 o 1:e016b03fd86f (draft) [ ] 1
1226 |
1226 |
1227 @ 0:a78f55e5508c (draft) [ ] 0
1227 @ 0:a78f55e5508c (draft) [ ] 0
1228
1228
1229 Test that 'hg debugobsolete --index --rev' can show indices of obsmarkers when
1229 Test that 'hg debugobsolete --index --rev' can show indices of obsmarkers when
1230 only a subset of those are displayed (because of --rev option)
1230 only a subset of those are displayed (because of --rev option)
1231 $ hg init doindexrev
1231 $ hg init doindexrev
1232 $ cd doindexrev
1232 $ cd doindexrev
1233 $ echo a > a
1233 $ echo a > a
1234 $ hg ci -Am a
1234 $ hg ci -Am a
1235 adding a
1235 adding a
1236 $ hg ci --amend -m aa
1236 $ hg ci --amend -m aa
1237 $ echo b > b
1237 $ echo b > b
1238 $ hg ci -Am b
1238 $ hg ci -Am b
1239 adding b
1239 adding b
1240 $ hg ci --amend -m bb
1240 $ hg ci --amend -m bb
1241 $ echo c > c
1241 $ echo c > c
1242 $ hg ci -Am c
1242 $ hg ci -Am c
1243 adding c
1243 adding c
1244 $ hg ci --amend -m cc
1244 $ hg ci --amend -m cc
1245 $ echo d > d
1245 $ echo d > d
1246 $ hg ci -Am d
1246 $ hg ci -Am d
1247 adding d
1247 adding d
1248 $ hg ci --amend -m dd
1248 $ hg ci --amend -m dd --config experimental.evolution.track-operation=1
1249 $ hg debugobsolete --index --rev "3+7"
1249 $ hg debugobsolete --index --rev "3+7"
1250 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 \(.*\) {'operation': 'amend', 'user': 'test'} (re)
1250 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 \(.*\) {'user': 'test'} (re)
1251 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 \(.*\) {'operation': 'amend', 'user': 'test'} (re)
1251 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 \(.*\) {'operation': 'amend', 'user': 'test'} (re)
1252 $ hg debugobsolete --index --rev "3+7" -Tjson
1252 $ hg debugobsolete --index --rev "3+7" -Tjson
1253 [
1253 [
1254 {
1254 {
1255 "date": *, (glob)
1255 "date": *, (glob)
1256 "flag": 0,
1256 "flag": 0,
1257 "index": 1,
1257 "index": 1,
1258 "metadata": {"operation": "amend", "user": "test"},
1258 "metadata": {"user": "test"},
1259 "precnode": "6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1",
1259 "precnode": "6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1",
1260 "succnodes": ["d27fb9b066076fd921277a4b9e8b9cb48c95bc6a"]
1260 "succnodes": ["d27fb9b066076fd921277a4b9e8b9cb48c95bc6a"]
1261 },
1261 },
1262 {
1262 {
1263 "date": *, (glob)
1263 "date": *, (glob)
1264 "flag": 0,
1264 "flag": 0,
1265 "index": 3,
1265 "index": 3,
1266 "metadata": {"operation": "amend", "user": "test"},
1266 "metadata": {"operation": "amend", "user": "test"},
1267 "precnode": "4715cf767440ed891755448016c2b8cf70760c30",
1267 "precnode": "4715cf767440ed891755448016c2b8cf70760c30",
1268 "succnodes": ["7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d"]
1268 "succnodes": ["7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d"]
1269 }
1269 }
1270 ]
1270 ]
1271
1271
1272 Test the --delete option of debugobsolete command
1272 Test the --delete option of debugobsolete command
1273 $ hg debugobsolete --index
1273 $ hg debugobsolete --index
1274 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 \(.*\) {'operation': 'amend', 'user': 'test'} (re)
1274 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 \(.*\) {'user': 'test'} (re)
1275 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 \(.*\) {'operation': 'amend', 'user': 'test'} (re)
1275 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 \(.*\) {'user': 'test'} (re)
1276 2 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 \(.*\) {'operation': 'amend', 'user': 'test'} (re)
1276 2 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 \(.*\) {'user': 'test'} (re)
1277 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 \(.*\) {'operation': 'amend', 'user': 'test'} (re)
1277 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 (*) {'operation': 'amend', 'user': 'test'} (glob)
1278 $ hg debugobsolete --delete 1 --delete 3
1278 $ hg debugobsolete --delete 1 --delete 3
1279 deleted 2 obsolescence markers
1279 deleted 2 obsolescence markers
1280 $ hg debugobsolete
1280 $ hg debugobsolete
1281 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 \(.*\) {'operation': 'amend', 'user': 'test'} (re)
1281 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 \(.*\) {'user': 'test'} (re)
1282 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 \(.*\) {'operation': 'amend', 'user': 'test'} (re)
1282 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 \(.*\) {'user': 'test'} (re)
1283 $ cd ..
1283 $ cd ..
1284
1284
@@ -1,980 +1,982 b''
1 ==========================
1 ==========================
2 Test rebase with obsolete
2 Test rebase with obsolete
3 ==========================
3 ==========================
4
4
5 Enable obsolete
5 Enable obsolete
6
6
7 $ cat >> $HGRCPATH << EOF
7 $ cat >> $HGRCPATH << EOF
8 > [ui]
8 > [ui]
9 > logtemplate= {rev}:{node|short} {desc|firstline}
9 > logtemplate= {rev}:{node|short} {desc|firstline}
10 > [experimental]
10 > [experimental]
11 > evolution=createmarkers,allowunstable
11 > evolution=createmarkers,allowunstable
12 > [phases]
12 > [phases]
13 > publish=False
13 > publish=False
14 > [extensions]
14 > [extensions]
15 > rebase=
15 > rebase=
16 > EOF
16 > EOF
17
17
18 Setup rebase canonical repo
18 Setup rebase canonical repo
19
19
20 $ hg init base
20 $ hg init base
21 $ cd base
21 $ cd base
22 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
22 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
23 adding changesets
23 adding changesets
24 adding manifests
24 adding manifests
25 adding file changes
25 adding file changes
26 added 8 changesets with 7 changes to 7 files (+2 heads)
26 added 8 changesets with 7 changes to 7 files (+2 heads)
27 (run 'hg heads' to see heads, 'hg merge' to merge)
27 (run 'hg heads' to see heads, 'hg merge' to merge)
28 $ hg up tip
28 $ hg up tip
29 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
29 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
30 $ hg log -G
30 $ hg log -G
31 @ 7:02de42196ebe H
31 @ 7:02de42196ebe H
32 |
32 |
33 | o 6:eea13746799a G
33 | o 6:eea13746799a G
34 |/|
34 |/|
35 o | 5:24b6387c8c8c F
35 o | 5:24b6387c8c8c F
36 | |
36 | |
37 | o 4:9520eea781bc E
37 | o 4:9520eea781bc E
38 |/
38 |/
39 | o 3:32af7686d403 D
39 | o 3:32af7686d403 D
40 | |
40 | |
41 | o 2:5fddd98957c8 C
41 | o 2:5fddd98957c8 C
42 | |
42 | |
43 | o 1:42ccdea3bb16 B
43 | o 1:42ccdea3bb16 B
44 |/
44 |/
45 o 0:cd010b8cd998 A
45 o 0:cd010b8cd998 A
46
46
47 $ cd ..
47 $ cd ..
48
48
49 simple rebase
49 simple rebase
50 ---------------------------------
50 ---------------------------------
51
51
52 $ hg clone base simple
52 $ hg clone base simple
53 updating to branch default
53 updating to branch default
54 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
54 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 $ cd simple
55 $ cd simple
56 $ hg up 32af7686d403
56 $ hg up 32af7686d403
57 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
57 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
58 $ hg rebase -d eea13746799a
58 $ hg rebase -d eea13746799a
59 rebasing 1:42ccdea3bb16 "B"
59 rebasing 1:42ccdea3bb16 "B"
60 rebasing 2:5fddd98957c8 "C"
60 rebasing 2:5fddd98957c8 "C"
61 rebasing 3:32af7686d403 "D"
61 rebasing 3:32af7686d403 "D"
62 $ hg log -G
62 $ hg log -G
63 @ 10:8eeb3c33ad33 D
63 @ 10:8eeb3c33ad33 D
64 |
64 |
65 o 9:2327fea05063 C
65 o 9:2327fea05063 C
66 |
66 |
67 o 8:e4e5be0395b2 B
67 o 8:e4e5be0395b2 B
68 |
68 |
69 | o 7:02de42196ebe H
69 | o 7:02de42196ebe H
70 | |
70 | |
71 o | 6:eea13746799a G
71 o | 6:eea13746799a G
72 |\|
72 |\|
73 | o 5:24b6387c8c8c F
73 | o 5:24b6387c8c8c F
74 | |
74 | |
75 o | 4:9520eea781bc E
75 o | 4:9520eea781bc E
76 |/
76 |/
77 o 0:cd010b8cd998 A
77 o 0:cd010b8cd998 A
78
78
79 $ hg log --hidden -G
79 $ hg log --hidden -G
80 @ 10:8eeb3c33ad33 D
80 @ 10:8eeb3c33ad33 D
81 |
81 |
82 o 9:2327fea05063 C
82 o 9:2327fea05063 C
83 |
83 |
84 o 8:e4e5be0395b2 B
84 o 8:e4e5be0395b2 B
85 |
85 |
86 | o 7:02de42196ebe H
86 | o 7:02de42196ebe H
87 | |
87 | |
88 o | 6:eea13746799a G
88 o | 6:eea13746799a G
89 |\|
89 |\|
90 | o 5:24b6387c8c8c F
90 | o 5:24b6387c8c8c F
91 | |
91 | |
92 o | 4:9520eea781bc E
92 o | 4:9520eea781bc E
93 |/
93 |/
94 | x 3:32af7686d403 D
94 | x 3:32af7686d403 D
95 | |
95 | |
96 | x 2:5fddd98957c8 C
96 | x 2:5fddd98957c8 C
97 | |
97 | |
98 | x 1:42ccdea3bb16 B
98 | x 1:42ccdea3bb16 B
99 |/
99 |/
100 o 0:cd010b8cd998 A
100 o 0:cd010b8cd998 A
101
101
102 $ hg debugobsolete
102 $ hg debugobsolete
103 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 e4e5be0395b2cbd471ed22a26b1b6a1a0658a794 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
103 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 e4e5be0395b2cbd471ed22a26b1b6a1a0658a794 0 (*) {'user': 'test'} (glob)
104 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 2327fea05063f39961b14cb69435a9898dc9a245 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
104 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 2327fea05063f39961b14cb69435a9898dc9a245 0 (*) {'user': 'test'} (glob)
105 32af7686d403cf45b5d95f2d70cebea587ac806a 8eeb3c33ad33d452c89e5dcf611c347f978fb42b 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
105 32af7686d403cf45b5d95f2d70cebea587ac806a 8eeb3c33ad33d452c89e5dcf611c347f978fb42b 0 (*) {'user': 'test'} (glob)
106
106
107
107
108 $ cd ..
108 $ cd ..
109
109
110 empty changeset
110 empty changeset
111 ---------------------------------
111 ---------------------------------
112
112
113 $ hg clone base empty
113 $ hg clone base empty
114 updating to branch default
114 updating to branch default
115 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
115 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
116 $ cd empty
116 $ cd empty
117 $ hg up eea13746799a
117 $ hg up eea13746799a
118 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
118 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
119
119
120 We make a copy of both the first changeset in the rebased and some other in the
120 We make a copy of both the first changeset in the rebased and some other in the
121 set.
121 set.
122
122
123 $ hg graft 42ccdea3bb16 32af7686d403
123 $ hg graft 42ccdea3bb16 32af7686d403
124 grafting 1:42ccdea3bb16 "B"
124 grafting 1:42ccdea3bb16 "B"
125 grafting 3:32af7686d403 "D"
125 grafting 3:32af7686d403 "D"
126 $ hg rebase -s 42ccdea3bb16 -d .
126 $ hg rebase -s 42ccdea3bb16 -d .
127 rebasing 1:42ccdea3bb16 "B"
127 rebasing 1:42ccdea3bb16 "B"
128 note: rebase of 1:42ccdea3bb16 created no changes to commit
128 note: rebase of 1:42ccdea3bb16 created no changes to commit
129 rebasing 2:5fddd98957c8 "C"
129 rebasing 2:5fddd98957c8 "C"
130 rebasing 3:32af7686d403 "D"
130 rebasing 3:32af7686d403 "D"
131 note: rebase of 3:32af7686d403 created no changes to commit
131 note: rebase of 3:32af7686d403 created no changes to commit
132 $ hg log -G
132 $ hg log -G
133 o 10:5ae4c968c6ac C
133 o 10:5ae4c968c6ac C
134 |
134 |
135 @ 9:08483444fef9 D
135 @ 9:08483444fef9 D
136 |
136 |
137 o 8:8877864f1edb B
137 o 8:8877864f1edb B
138 |
138 |
139 | o 7:02de42196ebe H
139 | o 7:02de42196ebe H
140 | |
140 | |
141 o | 6:eea13746799a G
141 o | 6:eea13746799a G
142 |\|
142 |\|
143 | o 5:24b6387c8c8c F
143 | o 5:24b6387c8c8c F
144 | |
144 | |
145 o | 4:9520eea781bc E
145 o | 4:9520eea781bc E
146 |/
146 |/
147 o 0:cd010b8cd998 A
147 o 0:cd010b8cd998 A
148
148
149 $ hg log --hidden -G
149 $ hg log --hidden -G
150 o 10:5ae4c968c6ac C
150 o 10:5ae4c968c6ac C
151 |
151 |
152 @ 9:08483444fef9 D
152 @ 9:08483444fef9 D
153 |
153 |
154 o 8:8877864f1edb B
154 o 8:8877864f1edb B
155 |
155 |
156 | o 7:02de42196ebe H
156 | o 7:02de42196ebe H
157 | |
157 | |
158 o | 6:eea13746799a G
158 o | 6:eea13746799a G
159 |\|
159 |\|
160 | o 5:24b6387c8c8c F
160 | o 5:24b6387c8c8c F
161 | |
161 | |
162 o | 4:9520eea781bc E
162 o | 4:9520eea781bc E
163 |/
163 |/
164 | x 3:32af7686d403 D
164 | x 3:32af7686d403 D
165 | |
165 | |
166 | x 2:5fddd98957c8 C
166 | x 2:5fddd98957c8 C
167 | |
167 | |
168 | x 1:42ccdea3bb16 B
168 | x 1:42ccdea3bb16 B
169 |/
169 |/
170 o 0:cd010b8cd998 A
170 o 0:cd010b8cd998 A
171
171
172 $ hg debugobsolete
172 $ hg debugobsolete
173 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (*) {'operation': 'rebase', 'user': 'test'} (glob)
173 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (*) {'user': 'test'} (glob)
174 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
174 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (*) {'user': 'test'} (glob)
175 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (*) {'operation': 'rebase', 'user': 'test'} (glob)
175 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (*) {'user': 'test'} (glob)
176
176
177
177
178 More complex case where part of the rebase set were already rebased
178 More complex case where part of the rebase set were already rebased
179
179
180 $ hg rebase --rev 'desc(D)' --dest 'desc(H)'
180 $ hg rebase --rev 'desc(D)' --dest 'desc(H)'
181 rebasing 9:08483444fef9 "D"
181 rebasing 9:08483444fef9 "D"
182 $ hg debugobsolete
182 $ hg debugobsolete
183 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (*) {'operation': 'rebase', 'user': 'test'} (glob)
183 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (*) {'user': 'test'} (glob)
184 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
184 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (*) {'user': 'test'} (glob)
185 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (*) {'operation': 'rebase', 'user': 'test'} (glob)
185 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (*) {'user': 'test'} (glob)
186 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
186 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (*) {'user': 'test'} (glob)
187 $ hg log -G
187 $ hg log -G
188 @ 11:4596109a6a43 D
188 @ 11:4596109a6a43 D
189 |
189 |
190 | o 10:5ae4c968c6ac C
190 | o 10:5ae4c968c6ac C
191 | |
191 | |
192 | x 9:08483444fef9 D
192 | x 9:08483444fef9 D
193 | |
193 | |
194 | o 8:8877864f1edb B
194 | o 8:8877864f1edb B
195 | |
195 | |
196 o | 7:02de42196ebe H
196 o | 7:02de42196ebe H
197 | |
197 | |
198 | o 6:eea13746799a G
198 | o 6:eea13746799a G
199 |/|
199 |/|
200 o | 5:24b6387c8c8c F
200 o | 5:24b6387c8c8c F
201 | |
201 | |
202 | o 4:9520eea781bc E
202 | o 4:9520eea781bc E
203 |/
203 |/
204 o 0:cd010b8cd998 A
204 o 0:cd010b8cd998 A
205
205
206 $ hg rebase --source 'desc(B)' --dest 'tip' --config experimental.rebaseskipobsolete=True
206 $ hg rebase --source 'desc(B)' --dest 'tip' --config experimental.rebaseskipobsolete=True
207 rebasing 8:8877864f1edb "B"
207 rebasing 8:8877864f1edb "B"
208 note: not rebasing 9:08483444fef9 "D", already in destination as 11:4596109a6a43 "D"
208 note: not rebasing 9:08483444fef9 "D", already in destination as 11:4596109a6a43 "D"
209 rebasing 10:5ae4c968c6ac "C"
209 rebasing 10:5ae4c968c6ac "C"
210 $ hg debugobsolete
210 $ hg debugobsolete
211 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (*) {'operation': 'rebase', 'user': 'test'} (glob)
211 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (*) {'user': 'test'} (glob)
212 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
212 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (*) {'user': 'test'} (glob)
213 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (*) {'operation': 'rebase', 'user': 'test'} (glob)
213 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (*) {'user': 'test'} (glob)
214 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
214 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (*) {'user': 'test'} (glob)
215 8877864f1edb05d0e07dc4ba77b67a80a7b86672 462a34d07e599b87ea08676a449373fe4e2e1347 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
215 8877864f1edb05d0e07dc4ba77b67a80a7b86672 462a34d07e599b87ea08676a449373fe4e2e1347 0 (*) {'user': 'test'} (glob)
216 5ae4c968c6aca831df823664e706c9d4aa34473d 98f6af4ee9539e14da4465128f894c274900b6e5 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
216 5ae4c968c6aca831df823664e706c9d4aa34473d 98f6af4ee9539e14da4465128f894c274900b6e5 0 (*) {'user': 'test'} (glob)
217 $ hg log --rev 'divergent()'
217 $ hg log --rev 'divergent()'
218 $ hg log -G
218 $ hg log -G
219 o 13:98f6af4ee953 C
219 o 13:98f6af4ee953 C
220 |
220 |
221 o 12:462a34d07e59 B
221 o 12:462a34d07e59 B
222 |
222 |
223 @ 11:4596109a6a43 D
223 @ 11:4596109a6a43 D
224 |
224 |
225 o 7:02de42196ebe H
225 o 7:02de42196ebe H
226 |
226 |
227 | o 6:eea13746799a G
227 | o 6:eea13746799a G
228 |/|
228 |/|
229 o | 5:24b6387c8c8c F
229 o | 5:24b6387c8c8c F
230 | |
230 | |
231 | o 4:9520eea781bc E
231 | o 4:9520eea781bc E
232 |/
232 |/
233 o 0:cd010b8cd998 A
233 o 0:cd010b8cd998 A
234
234
235 $ hg log --style default --debug -r 4596109a6a4328c398bde3a4a3b6737cfade3003
235 $ hg log --style default --debug -r 4596109a6a4328c398bde3a4a3b6737cfade3003
236 changeset: 11:4596109a6a4328c398bde3a4a3b6737cfade3003
236 changeset: 11:4596109a6a4328c398bde3a4a3b6737cfade3003
237 phase: draft
237 phase: draft
238 parent: 7:02de42196ebee42ef284b6780a87cdc96e8eaab6
238 parent: 7:02de42196ebee42ef284b6780a87cdc96e8eaab6
239 parent: -1:0000000000000000000000000000000000000000
239 parent: -1:0000000000000000000000000000000000000000
240 manifest: 11:a91006e3a02f1edf631f7018e6e5684cf27dd905
240 manifest: 11:a91006e3a02f1edf631f7018e6e5684cf27dd905
241 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
241 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
242 date: Sat Apr 30 15:24:48 2011 +0200
242 date: Sat Apr 30 15:24:48 2011 +0200
243 files+: D
243 files+: D
244 extra: branch=default
244 extra: branch=default
245 extra: rebase_source=08483444fef91d6224f6655ee586a65d263ad34c
245 extra: rebase_source=08483444fef91d6224f6655ee586a65d263ad34c
246 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
246 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
247 description:
247 description:
248 D
248 D
249
249
250
250
251 $ hg up -qr 'desc(G)'
251 $ hg up -qr 'desc(G)'
252 $ hg graft 4596109a6a4328c398bde3a4a3b6737cfade3003
252 $ hg graft 4596109a6a4328c398bde3a4a3b6737cfade3003
253 grafting 11:4596109a6a43 "D"
253 grafting 11:4596109a6a43 "D"
254 $ hg up -qr 'desc(E)'
254 $ hg up -qr 'desc(E)'
255 $ hg rebase -s tip -d .
255 $ hg rebase -s tip -d .
256 rebasing 14:9e36056a46e3 "D" (tip)
256 rebasing 14:9e36056a46e3 "D" (tip)
257 $ hg log --style default --debug -r tip
257 $ hg log --style default --debug -r tip
258 changeset: 15:627d4614809036ba22b9e7cb31638ddc06ab99ab
258 changeset: 15:627d4614809036ba22b9e7cb31638ddc06ab99ab
259 tag: tip
259 tag: tip
260 phase: draft
260 phase: draft
261 parent: 4:9520eea781bcca16c1e15acc0ba14335a0e8e5ba
261 parent: 4:9520eea781bcca16c1e15acc0ba14335a0e8e5ba
262 parent: -1:0000000000000000000000000000000000000000
262 parent: -1:0000000000000000000000000000000000000000
263 manifest: 15:648e8ede73ae3e497d093d3a4c8fcc2daa864f42
263 manifest: 15:648e8ede73ae3e497d093d3a4c8fcc2daa864f42
264 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
264 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
265 date: Sat Apr 30 15:24:48 2011 +0200
265 date: Sat Apr 30 15:24:48 2011 +0200
266 files+: D
266 files+: D
267 extra: branch=default
267 extra: branch=default
268 extra: intermediate-source=4596109a6a4328c398bde3a4a3b6737cfade3003
268 extra: intermediate-source=4596109a6a4328c398bde3a4a3b6737cfade3003
269 extra: rebase_source=9e36056a46e37c9776168c7375734eebc70e294f
269 extra: rebase_source=9e36056a46e37c9776168c7375734eebc70e294f
270 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
270 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
271 description:
271 description:
272 D
272 D
273
273
274
274
275 Start rebase from a commit that is obsolete but not hidden only because it's
275 Start rebase from a commit that is obsolete but not hidden only because it's
276 a working copy parent. We should be moved back to the starting commit as usual
276 a working copy parent. We should be moved back to the starting commit as usual
277 even though it is hidden (until we're moved there).
277 even though it is hidden (until we're moved there).
278
278
279 $ hg --hidden up -qr 'first(hidden())'
279 $ hg --hidden up -qr 'first(hidden())'
280 $ hg rebase --rev 13 --dest 15
280 $ hg rebase --rev 13 --dest 15
281 rebasing 13:98f6af4ee953 "C"
281 rebasing 13:98f6af4ee953 "C"
282 $ hg log -G
282 $ hg log -G
283 o 16:294a2b93eb4d C
283 o 16:294a2b93eb4d C
284 |
284 |
285 o 15:627d46148090 D
285 o 15:627d46148090 D
286 |
286 |
287 | o 12:462a34d07e59 B
287 | o 12:462a34d07e59 B
288 | |
288 | |
289 | o 11:4596109a6a43 D
289 | o 11:4596109a6a43 D
290 | |
290 | |
291 | o 7:02de42196ebe H
291 | o 7:02de42196ebe H
292 | |
292 | |
293 +---o 6:eea13746799a G
293 +---o 6:eea13746799a G
294 | |/
294 | |/
295 | o 5:24b6387c8c8c F
295 | o 5:24b6387c8c8c F
296 | |
296 | |
297 o | 4:9520eea781bc E
297 o | 4:9520eea781bc E
298 |/
298 |/
299 | @ 1:42ccdea3bb16 B
299 | @ 1:42ccdea3bb16 B
300 |/
300 |/
301 o 0:cd010b8cd998 A
301 o 0:cd010b8cd998 A
302
302
303
303
304 $ cd ..
304 $ cd ..
305
305
306 collapse rebase
306 collapse rebase
307 ---------------------------------
307 ---------------------------------
308
308
309 $ hg clone base collapse
309 $ hg clone base collapse
310 updating to branch default
310 updating to branch default
311 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
311 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
312 $ cd collapse
312 $ cd collapse
313 $ hg rebase -s 42ccdea3bb16 -d eea13746799a --collapse
313 $ hg rebase -s 42ccdea3bb16 -d eea13746799a --collapse
314 rebasing 1:42ccdea3bb16 "B"
314 rebasing 1:42ccdea3bb16 "B"
315 rebasing 2:5fddd98957c8 "C"
315 rebasing 2:5fddd98957c8 "C"
316 rebasing 3:32af7686d403 "D"
316 rebasing 3:32af7686d403 "D"
317 $ hg log -G
317 $ hg log -G
318 o 8:4dc2197e807b Collapsed revision
318 o 8:4dc2197e807b Collapsed revision
319 |
319 |
320 | @ 7:02de42196ebe H
320 | @ 7:02de42196ebe H
321 | |
321 | |
322 o | 6:eea13746799a G
322 o | 6:eea13746799a G
323 |\|
323 |\|
324 | o 5:24b6387c8c8c F
324 | o 5:24b6387c8c8c F
325 | |
325 | |
326 o | 4:9520eea781bc E
326 o | 4:9520eea781bc E
327 |/
327 |/
328 o 0:cd010b8cd998 A
328 o 0:cd010b8cd998 A
329
329
330 $ hg log --hidden -G
330 $ hg log --hidden -G
331 o 8:4dc2197e807b Collapsed revision
331 o 8:4dc2197e807b Collapsed revision
332 |
332 |
333 | @ 7:02de42196ebe H
333 | @ 7:02de42196ebe H
334 | |
334 | |
335 o | 6:eea13746799a G
335 o | 6:eea13746799a G
336 |\|
336 |\|
337 | o 5:24b6387c8c8c F
337 | o 5:24b6387c8c8c F
338 | |
338 | |
339 o | 4:9520eea781bc E
339 o | 4:9520eea781bc E
340 |/
340 |/
341 | x 3:32af7686d403 D
341 | x 3:32af7686d403 D
342 | |
342 | |
343 | x 2:5fddd98957c8 C
343 | x 2:5fddd98957c8 C
344 | |
344 | |
345 | x 1:42ccdea3bb16 B
345 | x 1:42ccdea3bb16 B
346 |/
346 |/
347 o 0:cd010b8cd998 A
347 o 0:cd010b8cd998 A
348
348
349 $ hg id --debug -r tip
349 $ hg id --debug -r tip
350 4dc2197e807bae9817f09905b50ab288be2dbbcf tip
350 4dc2197e807bae9817f09905b50ab288be2dbbcf tip
351 $ hg debugobsolete
351 $ hg debugobsolete
352 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
352 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (*) {'user': 'test'} (glob)
353 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
353 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (*) {'user': 'test'} (glob)
354 32af7686d403cf45b5d95f2d70cebea587ac806a 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
354 32af7686d403cf45b5d95f2d70cebea587ac806a 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (*) {'user': 'test'} (glob)
355
355
356 $ cd ..
356 $ cd ..
357
357
358 Rebase set has hidden descendants
358 Rebase set has hidden descendants
359 ---------------------------------
359 ---------------------------------
360
360
361 We rebase a changeset which has a hidden changeset. The hidden changeset must
361 We rebase a changeset which has a hidden changeset. The hidden changeset must
362 not be rebased.
362 not be rebased.
363
363
364 $ hg clone base hidden
364 $ hg clone base hidden
365 updating to branch default
365 updating to branch default
366 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
366 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
367 $ cd hidden
367 $ cd hidden
368 $ hg rebase -s 5fddd98957c8 -d eea13746799a
368 $ hg rebase -s 5fddd98957c8 -d eea13746799a
369 rebasing 2:5fddd98957c8 "C"
369 rebasing 2:5fddd98957c8 "C"
370 rebasing 3:32af7686d403 "D"
370 rebasing 3:32af7686d403 "D"
371 $ hg rebase -s 42ccdea3bb16 -d 02de42196ebe
371 $ hg rebase -s 42ccdea3bb16 -d 02de42196ebe
372 rebasing 1:42ccdea3bb16 "B"
372 rebasing 1:42ccdea3bb16 "B"
373 $ hg log -G
373 $ hg log -G
374 o 10:7c6027df6a99 B
374 o 10:7c6027df6a99 B
375 |
375 |
376 | o 9:cf44d2f5a9f4 D
376 | o 9:cf44d2f5a9f4 D
377 | |
377 | |
378 | o 8:e273c5e7d2d2 C
378 | o 8:e273c5e7d2d2 C
379 | |
379 | |
380 @ | 7:02de42196ebe H
380 @ | 7:02de42196ebe H
381 | |
381 | |
382 | o 6:eea13746799a G
382 | o 6:eea13746799a G
383 |/|
383 |/|
384 o | 5:24b6387c8c8c F
384 o | 5:24b6387c8c8c F
385 | |
385 | |
386 | o 4:9520eea781bc E
386 | o 4:9520eea781bc E
387 |/
387 |/
388 o 0:cd010b8cd998 A
388 o 0:cd010b8cd998 A
389
389
390 $ hg log --hidden -G
390 $ hg log --hidden -G
391 o 10:7c6027df6a99 B
391 o 10:7c6027df6a99 B
392 |
392 |
393 | o 9:cf44d2f5a9f4 D
393 | o 9:cf44d2f5a9f4 D
394 | |
394 | |
395 | o 8:e273c5e7d2d2 C
395 | o 8:e273c5e7d2d2 C
396 | |
396 | |
397 @ | 7:02de42196ebe H
397 @ | 7:02de42196ebe H
398 | |
398 | |
399 | o 6:eea13746799a G
399 | o 6:eea13746799a G
400 |/|
400 |/|
401 o | 5:24b6387c8c8c F
401 o | 5:24b6387c8c8c F
402 | |
402 | |
403 | o 4:9520eea781bc E
403 | o 4:9520eea781bc E
404 |/
404 |/
405 | x 3:32af7686d403 D
405 | x 3:32af7686d403 D
406 | |
406 | |
407 | x 2:5fddd98957c8 C
407 | x 2:5fddd98957c8 C
408 | |
408 | |
409 | x 1:42ccdea3bb16 B
409 | x 1:42ccdea3bb16 B
410 |/
410 |/
411 o 0:cd010b8cd998 A
411 o 0:cd010b8cd998 A
412
412
413 $ hg debugobsolete
413 $ hg debugobsolete
414 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b e273c5e7d2d29df783dce9f9eaa3ac4adc69c15d 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
414 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b e273c5e7d2d29df783dce9f9eaa3ac4adc69c15d 0 (*) {'user': 'test'} (glob)
415 32af7686d403cf45b5d95f2d70cebea587ac806a cf44d2f5a9f4297a62be94cbdd3dff7c7dc54258 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
415 32af7686d403cf45b5d95f2d70cebea587ac806a cf44d2f5a9f4297a62be94cbdd3dff7c7dc54258 0 (*) {'user': 'test'} (glob)
416 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 7c6027df6a99d93f461868e5433f63bde20b6dfb 0 (*) {'operation': 'rebase', 'user': 'test'} (glob)
416 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 7c6027df6a99d93f461868e5433f63bde20b6dfb 0 (*) {'user': 'test'} (glob)
417
417
418 Test that rewriting leaving instability behind is allowed
418 Test that rewriting leaving instability behind is allowed
419 ---------------------------------------------------------------------
419 ---------------------------------------------------------------------
420
420
421 $ hg log -r 'children(8)'
421 $ hg log -r 'children(8)'
422 9:cf44d2f5a9f4 D (no-eol)
422 9:cf44d2f5a9f4 D (no-eol)
423 $ hg rebase -r 8
423 $ hg rebase -r 8
424 rebasing 8:e273c5e7d2d2 "C"
424 rebasing 8:e273c5e7d2d2 "C"
425 $ hg log -G
425 $ hg log -G
426 o 11:0d8f238b634c C
426 o 11:0d8f238b634c C
427 |
427 |
428 o 10:7c6027df6a99 B
428 o 10:7c6027df6a99 B
429 |
429 |
430 | o 9:cf44d2f5a9f4 D
430 | o 9:cf44d2f5a9f4 D
431 | |
431 | |
432 | x 8:e273c5e7d2d2 C
432 | x 8:e273c5e7d2d2 C
433 | |
433 | |
434 @ | 7:02de42196ebe H
434 @ | 7:02de42196ebe H
435 | |
435 | |
436 | o 6:eea13746799a G
436 | o 6:eea13746799a G
437 |/|
437 |/|
438 o | 5:24b6387c8c8c F
438 o | 5:24b6387c8c8c F
439 | |
439 | |
440 | o 4:9520eea781bc E
440 | o 4:9520eea781bc E
441 |/
441 |/
442 o 0:cd010b8cd998 A
442 o 0:cd010b8cd998 A
443
443
444
444
445
445
446 Test multiple root handling
446 Test multiple root handling
447 ------------------------------------
447 ------------------------------------
448
448
449 $ hg rebase --dest 4 --rev '7+11+9'
449 $ hg rebase --dest 4 --rev '7+11+9'
450 rebasing 9:cf44d2f5a9f4 "D"
450 rebasing 9:cf44d2f5a9f4 "D"
451 rebasing 7:02de42196ebe "H"
451 rebasing 7:02de42196ebe "H"
452 not rebasing ignored 10:7c6027df6a99 "B"
452 not rebasing ignored 10:7c6027df6a99 "B"
453 rebasing 11:0d8f238b634c "C" (tip)
453 rebasing 11:0d8f238b634c "C" (tip)
454 $ hg log -G
454 $ hg log -G
455 o 14:1e8370e38cca C
455 o 14:1e8370e38cca C
456 |
456 |
457 @ 13:bfe264faf697 H
457 @ 13:bfe264faf697 H
458 |
458 |
459 | o 12:102b4c1d889b D
459 | o 12:102b4c1d889b D
460 |/
460 |/
461 | o 10:7c6027df6a99 B
461 | o 10:7c6027df6a99 B
462 | |
462 | |
463 | x 7:02de42196ebe H
463 | x 7:02de42196ebe H
464 | |
464 | |
465 +---o 6:eea13746799a G
465 +---o 6:eea13746799a G
466 | |/
466 | |/
467 | o 5:24b6387c8c8c F
467 | o 5:24b6387c8c8c F
468 | |
468 | |
469 o | 4:9520eea781bc E
469 o | 4:9520eea781bc E
470 |/
470 |/
471 o 0:cd010b8cd998 A
471 o 0:cd010b8cd998 A
472
472
473 $ cd ..
473 $ cd ..
474
474
475 test on rebase dropping a merge
475 test on rebase dropping a merge
476
476
477 (setup)
477 (setup)
478
478
479 $ hg init dropmerge
479 $ hg init dropmerge
480 $ cd dropmerge
480 $ cd dropmerge
481 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
481 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
482 adding changesets
482 adding changesets
483 adding manifests
483 adding manifests
484 adding file changes
484 adding file changes
485 added 8 changesets with 7 changes to 7 files (+2 heads)
485 added 8 changesets with 7 changes to 7 files (+2 heads)
486 (run 'hg heads' to see heads, 'hg merge' to merge)
486 (run 'hg heads' to see heads, 'hg merge' to merge)
487 $ hg up 3
487 $ hg up 3
488 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
488 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
489 $ hg merge 7
489 $ hg merge 7
490 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
490 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
491 (branch merge, don't forget to commit)
491 (branch merge, don't forget to commit)
492 $ hg ci -m 'M'
492 $ hg ci -m 'M'
493 $ echo I > I
493 $ echo I > I
494 $ hg add I
494 $ hg add I
495 $ hg ci -m I
495 $ hg ci -m I
496 $ hg log -G
496 $ hg log -G
497 @ 9:4bde274eefcf I
497 @ 9:4bde274eefcf I
498 |
498 |
499 o 8:53a6a128b2b7 M
499 o 8:53a6a128b2b7 M
500 |\
500 |\
501 | o 7:02de42196ebe H
501 | o 7:02de42196ebe H
502 | |
502 | |
503 | | o 6:eea13746799a G
503 | | o 6:eea13746799a G
504 | |/|
504 | |/|
505 | o | 5:24b6387c8c8c F
505 | o | 5:24b6387c8c8c F
506 | | |
506 | | |
507 | | o 4:9520eea781bc E
507 | | o 4:9520eea781bc E
508 | |/
508 | |/
509 o | 3:32af7686d403 D
509 o | 3:32af7686d403 D
510 | |
510 | |
511 o | 2:5fddd98957c8 C
511 o | 2:5fddd98957c8 C
512 | |
512 | |
513 o | 1:42ccdea3bb16 B
513 o | 1:42ccdea3bb16 B
514 |/
514 |/
515 o 0:cd010b8cd998 A
515 o 0:cd010b8cd998 A
516
516
517 (actual test)
517 (actual test)
518
518
519 $ hg rebase --dest 6 --rev '((desc(H) + desc(D))::) - desc(M)'
519 $ hg rebase --dest 6 --rev '((desc(H) + desc(D))::) - desc(M)'
520 rebasing 3:32af7686d403 "D"
520 rebasing 3:32af7686d403 "D"
521 rebasing 7:02de42196ebe "H"
521 rebasing 7:02de42196ebe "H"
522 not rebasing ignored 8:53a6a128b2b7 "M"
522 not rebasing ignored 8:53a6a128b2b7 "M"
523 rebasing 9:4bde274eefcf "I" (tip)
523 rebasing 9:4bde274eefcf "I" (tip)
524 $ hg log -G
524 $ hg log -G
525 @ 12:acd174b7ab39 I
525 @ 12:acd174b7ab39 I
526 |
526 |
527 o 11:6c11a6218c97 H
527 o 11:6c11a6218c97 H
528 |
528 |
529 | o 10:b5313c85b22e D
529 | o 10:b5313c85b22e D
530 |/
530 |/
531 | o 8:53a6a128b2b7 M
531 | o 8:53a6a128b2b7 M
532 | |\
532 | |\
533 | | x 7:02de42196ebe H
533 | | x 7:02de42196ebe H
534 | | |
534 | | |
535 o---+ 6:eea13746799a G
535 o---+ 6:eea13746799a G
536 | | |
536 | | |
537 | | o 5:24b6387c8c8c F
537 | | o 5:24b6387c8c8c F
538 | | |
538 | | |
539 o---+ 4:9520eea781bc E
539 o---+ 4:9520eea781bc E
540 / /
540 / /
541 x | 3:32af7686d403 D
541 x | 3:32af7686d403 D
542 | |
542 | |
543 o | 2:5fddd98957c8 C
543 o | 2:5fddd98957c8 C
544 | |
544 | |
545 o | 1:42ccdea3bb16 B
545 o | 1:42ccdea3bb16 B
546 |/
546 |/
547 o 0:cd010b8cd998 A
547 o 0:cd010b8cd998 A
548
548
549
549
550 Test hidden changesets in the rebase set (issue4504)
550 Test hidden changesets in the rebase set (issue4504)
551
551
552 $ hg up --hidden 9
552 $ hg up --hidden 9
553 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
553 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
554 $ echo J > J
554 $ echo J > J
555 $ hg add J
555 $ hg add J
556 $ hg commit -m J
556 $ hg commit -m J
557 $ hg debugobsolete `hg log --rev . -T '{node}'`
557 $ hg debugobsolete `hg log --rev . -T '{node}'`
558
558
559 $ hg rebase --rev .~1::. --dest 'max(desc(D))' --traceback --config experimental.rebaseskipobsolete=off
559 $ hg rebase --rev .~1::. --dest 'max(desc(D))' --traceback --config experimental.rebaseskipobsolete=off
560 rebasing 9:4bde274eefcf "I"
560 rebasing 9:4bde274eefcf "I"
561 rebasing 13:06edfc82198f "J" (tip)
561 rebasing 13:06edfc82198f "J" (tip)
562 $ hg log -G
562 $ hg log -G
563 @ 15:5ae8a643467b J
563 @ 15:5ae8a643467b J
564 |
564 |
565 o 14:9ad579b4a5de I
565 o 14:9ad579b4a5de I
566 |
566 |
567 | o 12:acd174b7ab39 I
567 | o 12:acd174b7ab39 I
568 | |
568 | |
569 | o 11:6c11a6218c97 H
569 | o 11:6c11a6218c97 H
570 | |
570 | |
571 o | 10:b5313c85b22e D
571 o | 10:b5313c85b22e D
572 |/
572 |/
573 | o 8:53a6a128b2b7 M
573 | o 8:53a6a128b2b7 M
574 | |\
574 | |\
575 | | x 7:02de42196ebe H
575 | | x 7:02de42196ebe H
576 | | |
576 | | |
577 o---+ 6:eea13746799a G
577 o---+ 6:eea13746799a G
578 | | |
578 | | |
579 | | o 5:24b6387c8c8c F
579 | | o 5:24b6387c8c8c F
580 | | |
580 | | |
581 o---+ 4:9520eea781bc E
581 o---+ 4:9520eea781bc E
582 / /
582 / /
583 x | 3:32af7686d403 D
583 x | 3:32af7686d403 D
584 | |
584 | |
585 o | 2:5fddd98957c8 C
585 o | 2:5fddd98957c8 C
586 | |
586 | |
587 o | 1:42ccdea3bb16 B
587 o | 1:42ccdea3bb16 B
588 |/
588 |/
589 o 0:cd010b8cd998 A
589 o 0:cd010b8cd998 A
590
590
591 $ hg up 14 -C
591 $ hg up 14 -C
592 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
592 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
593 $ echo "K" > K
593 $ echo "K" > K
594 $ hg add K
594 $ hg add K
595 $ hg commit --amend -m "K"
595 $ hg commit --amend -m "K"
596 $ echo "L" > L
596 $ echo "L" > L
597 $ hg add L
597 $ hg add L
598 $ hg commit -m "L"
598 $ hg commit -m "L"
599 $ hg up '.^'
599 $ hg up '.^'
600 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
600 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
601 $ echo "M" > M
601 $ echo "M" > M
602 $ hg add M
602 $ hg add M
603 $ hg commit --amend -m "M"
603 $ hg commit --amend -m "M"
604 $ hg log -G
604 $ hg log -G
605 @ 20:bfaedf8eb73b M
605 @ 20:bfaedf8eb73b M
606 |
606 |
607 | o 18:97219452e4bd L
607 | o 18:97219452e4bd L
608 | |
608 | |
609 | x 17:fc37a630c901 K
609 | x 17:fc37a630c901 K
610 |/
610 |/
611 | o 15:5ae8a643467b J
611 | o 15:5ae8a643467b J
612 | |
612 | |
613 | x 14:9ad579b4a5de I
613 | x 14:9ad579b4a5de I
614 |/
614 |/
615 | o 12:acd174b7ab39 I
615 | o 12:acd174b7ab39 I
616 | |
616 | |
617 | o 11:6c11a6218c97 H
617 | o 11:6c11a6218c97 H
618 | |
618 | |
619 o | 10:b5313c85b22e D
619 o | 10:b5313c85b22e D
620 |/
620 |/
621 | o 8:53a6a128b2b7 M
621 | o 8:53a6a128b2b7 M
622 | |\
622 | |\
623 | | x 7:02de42196ebe H
623 | | x 7:02de42196ebe H
624 | | |
624 | | |
625 o---+ 6:eea13746799a G
625 o---+ 6:eea13746799a G
626 | | |
626 | | |
627 | | o 5:24b6387c8c8c F
627 | | o 5:24b6387c8c8c F
628 | | |
628 | | |
629 o---+ 4:9520eea781bc E
629 o---+ 4:9520eea781bc E
630 / /
630 / /
631 x | 3:32af7686d403 D
631 x | 3:32af7686d403 D
632 | |
632 | |
633 o | 2:5fddd98957c8 C
633 o | 2:5fddd98957c8 C
634 | |
634 | |
635 o | 1:42ccdea3bb16 B
635 o | 1:42ccdea3bb16 B
636 |/
636 |/
637 o 0:cd010b8cd998 A
637 o 0:cd010b8cd998 A
638
638
639 $ hg rebase -s 14 -d 18 --config experimental.rebaseskipobsolete=True
639 $ hg rebase -s 14 -d 18 --config experimental.rebaseskipobsolete=True
640 note: not rebasing 14:9ad579b4a5de "I", already in destination as 17:fc37a630c901 "K"
640 note: not rebasing 14:9ad579b4a5de "I", already in destination as 17:fc37a630c901 "K"
641 rebasing 15:5ae8a643467b "J"
641 rebasing 15:5ae8a643467b "J"
642
642
643 $ cd ..
643 $ cd ..
644
644
645 Skip obsolete changeset even with multiple hops
645 Skip obsolete changeset even with multiple hops
646 -----------------------------------------------
646 -----------------------------------------------
647
647
648 setup
648 setup
649
649
650 $ hg init obsskip
650 $ hg init obsskip
651 $ cd obsskip
651 $ cd obsskip
652 $ cat << EOF >> .hg/hgrc
652 $ cat << EOF >> .hg/hgrc
653 > [experimental]
653 > [experimental]
654 > rebaseskipobsolete = True
654 > rebaseskipobsolete = True
655 > [extensions]
655 > [extensions]
656 > strip =
656 > strip =
657 > EOF
657 > EOF
658 $ echo A > A
658 $ echo A > A
659 $ hg add A
659 $ hg add A
660 $ hg commit -m A
660 $ hg commit -m A
661 $ echo B > B
661 $ echo B > B
662 $ hg add B
662 $ hg add B
663 $ hg commit -m B0
663 $ hg commit -m B0
664 $ hg commit --amend -m B1
664 $ hg commit --amend -m B1
665 $ hg commit --amend -m B2
665 $ hg commit --amend -m B2
666 $ hg up --hidden 'desc(B0)'
666 $ hg up --hidden 'desc(B0)'
667 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
667 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
668 $ echo C > C
668 $ echo C > C
669 $ hg add C
669 $ hg add C
670 $ hg commit -m C
670 $ hg commit -m C
671
671
672 Rebase finds its way in a chain of marker
672 Rebase finds its way in a chain of marker
673
673
674 $ hg rebase -d 'desc(B2)'
674 $ hg rebase -d 'desc(B2)'
675 note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 3:261e70097290 "B2"
675 note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 3:261e70097290 "B2"
676 rebasing 4:212cb178bcbb "C" (tip)
676 rebasing 4:212cb178bcbb "C" (tip)
677
677
678 Even when the chain include missing node
678 Even when the chain include missing node
679
679
680 $ hg up --hidden 'desc(B0)'
680 $ hg up --hidden 'desc(B0)'
681 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
681 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
682 $ echo D > D
682 $ echo D > D
683 $ hg add D
683 $ hg add D
684 $ hg commit -m D
684 $ hg commit -m D
685 $ hg --hidden strip -r 'desc(B1)'
685 $ hg --hidden strip -r 'desc(B1)'
686 saved backup bundle to $TESTTMP/obsskip/.hg/strip-backup/86f6414ccda7-b1c452ee-backup.hg (glob)
686 saved backup bundle to $TESTTMP/obsskip/.hg/strip-backup/86f6414ccda7-b1c452ee-backup.hg (glob)
687
687
688 $ hg rebase -d 'desc(B2)'
688 $ hg rebase -d 'desc(B2)'
689 note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 2:261e70097290 "B2"
689 note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 2:261e70097290 "B2"
690 rebasing 5:1a79b7535141 "D" (tip)
690 rebasing 5:1a79b7535141 "D" (tip)
691 $ hg up 4
691 $ hg up 4
692 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
692 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
693 $ echo "O" > O
693 $ echo "O" > O
694 $ hg add O
694 $ hg add O
695 $ hg commit -m O
695 $ hg commit -m O
696 $ echo "P" > P
696 $ echo "P" > P
697 $ hg add P
697 $ hg add P
698 $ hg commit -m P
698 $ hg commit -m P
699 $ hg log -G
699 $ hg log -G
700 @ 8:8d47583e023f P
700 @ 8:8d47583e023f P
701 |
701 |
702 o 7:360bbaa7d3ce O
702 o 7:360bbaa7d3ce O
703 |
703 |
704 | o 6:9c48361117de D
704 | o 6:9c48361117de D
705 | |
705 | |
706 o | 4:ff2c4d47b71d C
706 o | 4:ff2c4d47b71d C
707 |/
707 |/
708 o 2:261e70097290 B2
708 o 2:261e70097290 B2
709 |
709 |
710 o 0:4a2df7238c3b A
710 o 0:4a2df7238c3b A
711
711
712 $ hg debugobsolete `hg log -r 7 -T '{node}\n'` --config experimental.evolution=all
712 $ hg debugobsolete `hg log -r 7 -T '{node}\n'` --config experimental.evolution=all
713 $ hg rebase -d 6 -r "4::"
713 $ hg rebase -d 6 -r "4::"
714 rebasing 4:ff2c4d47b71d "C"
714 rebasing 4:ff2c4d47b71d "C"
715 note: not rebasing 7:360bbaa7d3ce "O", it has no successor
715 note: not rebasing 7:360bbaa7d3ce "O", it has no successor
716 rebasing 8:8d47583e023f "P" (tip)
716 rebasing 8:8d47583e023f "P" (tip)
717
717
718 If all the changeset to be rebased are obsolete and present in the destination, we
718 If all the changeset to be rebased are obsolete and present in the destination, we
719 should display a friendly error message
719 should display a friendly error message
720
720
721 $ hg log -G
721 $ hg log -G
722 @ 10:121d9e3bc4c6 P
722 @ 10:121d9e3bc4c6 P
723 |
723 |
724 o 9:4be60e099a77 C
724 o 9:4be60e099a77 C
725 |
725 |
726 o 6:9c48361117de D
726 o 6:9c48361117de D
727 |
727 |
728 o 2:261e70097290 B2
728 o 2:261e70097290 B2
729 |
729 |
730 o 0:4a2df7238c3b A
730 o 0:4a2df7238c3b A
731
731
732
732
733 $ hg up 9
733 $ hg up 9
734 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
734 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
735 $ echo "non-relevant change" > nonrelevant
735 $ echo "non-relevant change" > nonrelevant
736 $ hg add nonrelevant
736 $ hg add nonrelevant
737 $ hg commit -m nonrelevant
737 $ hg commit -m nonrelevant
738 created new head
738 created new head
739 $ hg debugobsolete `hg log -r 11 -T '{node}\n'` --config experimental.evolution=all
739 $ hg debugobsolete `hg log -r 11 -T '{node}\n'` --config experimental.evolution=all
740 $ hg rebase -r . -d 10
740 $ hg rebase -r . -d 10
741 note: not rebasing 11:f44da1f4954c "nonrelevant" (tip), it has no successor
741 note: not rebasing 11:f44da1f4954c "nonrelevant" (tip), it has no successor
742
742
743 If a rebase is going to create divergence, it should abort
743 If a rebase is going to create divergence, it should abort
744
744
745 $ hg log -G
745 $ hg log -G
746 @ 11:f44da1f4954c nonrelevant
746 @ 11:f44da1f4954c nonrelevant
747 |
747 |
748 | o 10:121d9e3bc4c6 P
748 | o 10:121d9e3bc4c6 P
749 |/
749 |/
750 o 9:4be60e099a77 C
750 o 9:4be60e099a77 C
751 |
751 |
752 o 6:9c48361117de D
752 o 6:9c48361117de D
753 |
753 |
754 o 2:261e70097290 B2
754 o 2:261e70097290 B2
755 |
755 |
756 o 0:4a2df7238c3b A
756 o 0:4a2df7238c3b A
757
757
758
758
759 $ hg up 9
759 $ hg up 9
760 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
760 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
761 $ echo "john" > doe
761 $ echo "john" > doe
762 $ hg add doe
762 $ hg add doe
763 $ hg commit -m "john doe"
763 $ hg commit -m "john doe"
764 created new head
764 created new head
765 $ hg up 10
765 $ hg up 10
766 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
766 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
767 $ echo "foo" > bar
767 $ echo "foo" > bar
768 $ hg add bar
768 $ hg add bar
769 $ hg commit --amend -m "10'"
769 $ hg commit --amend -m "10'"
770 $ hg up 10 --hidden
770 $ hg up 10 --hidden
771 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
771 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
772 $ echo "bar" > foo
772 $ echo "bar" > foo
773 $ hg add foo
773 $ hg add foo
774 $ hg commit -m "bar foo"
774 $ hg commit -m "bar foo"
775 $ hg log -G
775 $ hg log -G
776 @ 15:73568ab6879d bar foo
776 @ 15:73568ab6879d bar foo
777 |
777 |
778 | o 14:77d874d096a2 10'
778 | o 14:77d874d096a2 10'
779 | |
779 | |
780 | | o 12:3eb461388009 john doe
780 | | o 12:3eb461388009 john doe
781 | |/
781 | |/
782 x | 10:121d9e3bc4c6 P
782 x | 10:121d9e3bc4c6 P
783 |/
783 |/
784 o 9:4be60e099a77 C
784 o 9:4be60e099a77 C
785 |
785 |
786 o 6:9c48361117de D
786 o 6:9c48361117de D
787 |
787 |
788 o 2:261e70097290 B2
788 o 2:261e70097290 B2
789 |
789 |
790 o 0:4a2df7238c3b A
790 o 0:4a2df7238c3b A
791
791
792 $ hg summary
792 $ hg summary
793 parent: 15:73568ab6879d tip (unstable)
793 parent: 15:73568ab6879d tip (unstable)
794 bar foo
794 bar foo
795 branch: default
795 branch: default
796 commit: (clean)
796 commit: (clean)
797 update: 2 new changesets, 3 branch heads (merge)
797 update: 2 new changesets, 3 branch heads (merge)
798 phases: 8 draft
798 phases: 8 draft
799 unstable: 1 changesets
799 unstable: 1 changesets
800 $ hg rebase -s 10 -d 12
800 $ hg rebase -s 10 -d 12
801 abort: this rebase will cause divergences from: 121d9e3bc4c6
801 abort: this rebase will cause divergences from: 121d9e3bc4c6
802 (to force the rebase please set experimental.allowdivergence=True)
802 (to force the rebase please set experimental.allowdivergence=True)
803 [255]
803 [255]
804 $ hg log -G
804 $ hg log -G
805 @ 15:73568ab6879d bar foo
805 @ 15:73568ab6879d bar foo
806 |
806 |
807 | o 14:77d874d096a2 10'
807 | o 14:77d874d096a2 10'
808 | |
808 | |
809 | | o 12:3eb461388009 john doe
809 | | o 12:3eb461388009 john doe
810 | |/
810 | |/
811 x | 10:121d9e3bc4c6 P
811 x | 10:121d9e3bc4c6 P
812 |/
812 |/
813 o 9:4be60e099a77 C
813 o 9:4be60e099a77 C
814 |
814 |
815 o 6:9c48361117de D
815 o 6:9c48361117de D
816 |
816 |
817 o 2:261e70097290 B2
817 o 2:261e70097290 B2
818 |
818 |
819 o 0:4a2df7238c3b A
819 o 0:4a2df7238c3b A
820
820
821 With experimental.allowdivergence=True, rebase can create divergence
821 With experimental.allowdivergence=True, rebase can create divergence
822
822
823 $ hg rebase -s 10 -d 12 --config experimental.allowdivergence=True
823 $ hg rebase -s 10 -d 12 --config experimental.allowdivergence=True
824 rebasing 10:121d9e3bc4c6 "P"
824 rebasing 10:121d9e3bc4c6 "P"
825 rebasing 15:73568ab6879d "bar foo" (tip)
825 rebasing 15:73568ab6879d "bar foo" (tip)
826 $ hg summary
826 $ hg summary
827 parent: 17:61bd55f69bc4 tip
827 parent: 17:61bd55f69bc4 tip
828 bar foo
828 bar foo
829 branch: default
829 branch: default
830 commit: (clean)
830 commit: (clean)
831 update: 1 new changesets, 2 branch heads (merge)
831 update: 1 new changesets, 2 branch heads (merge)
832 phases: 8 draft
832 phases: 8 draft
833 divergent: 2 changesets
833 divergent: 2 changesets
834
834
835 rebase --continue + skipped rev because their successors are in destination
835 rebase --continue + skipped rev because their successors are in destination
836 we make a change in trunk and work on conflicting changes to make rebase abort.
836 we make a change in trunk and work on conflicting changes to make rebase abort.
837
837
838 $ hg log -G -r 17::
838 $ hg log -G -r 17::
839 @ 17:61bd55f69bc4 bar foo
839 @ 17:61bd55f69bc4 bar foo
840 |
840 |
841 ~
841 ~
842
842
843 Create the two changes in trunk
843 Create the two changes in trunk
844 $ printf "a" > willconflict
844 $ printf "a" > willconflict
845 $ hg add willconflict
845 $ hg add willconflict
846 $ hg commit -m "willconflict first version"
846 $ hg commit -m "willconflict first version"
847
847
848 $ printf "dummy" > C
848 $ printf "dummy" > C
849 $ hg commit -m "dummy change successor"
849 $ hg commit -m "dummy change successor"
850
850
851 Create the changes that we will rebase
851 Create the changes that we will rebase
852 $ hg update -C 17 -q
852 $ hg update -C 17 -q
853 $ printf "b" > willconflict
853 $ printf "b" > willconflict
854 $ hg add willconflict
854 $ hg add willconflict
855 $ hg commit -m "willconflict second version"
855 $ hg commit -m "willconflict second version"
856 created new head
856 created new head
857 $ printf "dummy" > K
857 $ printf "dummy" > K
858 $ hg add K
858 $ hg add K
859 $ hg commit -m "dummy change"
859 $ hg commit -m "dummy change"
860 $ printf "dummy" > L
860 $ printf "dummy" > L
861 $ hg add L
861 $ hg add L
862 $ hg commit -m "dummy change"
862 $ hg commit -m "dummy change"
863 $ hg debugobsolete `hg log -r ".^" -T '{node}'` `hg log -r 19 -T '{node}'` --config experimental.evolution=all
863 $ hg debugobsolete `hg log -r ".^" -T '{node}'` `hg log -r 19 -T '{node}'` --config experimental.evolution=all
864
864
865 $ hg log -G -r 17::
865 $ hg log -G -r 17::
866 @ 22:7bdc8a87673d dummy change
866 @ 22:7bdc8a87673d dummy change
867 |
867 |
868 x 21:8b31da3c4919 dummy change
868 x 21:8b31da3c4919 dummy change
869 |
869 |
870 o 20:b82fb57ea638 willconflict second version
870 o 20:b82fb57ea638 willconflict second version
871 |
871 |
872 | o 19:601db7a18f51 dummy change successor
872 | o 19:601db7a18f51 dummy change successor
873 | |
873 | |
874 | o 18:357ddf1602d5 willconflict first version
874 | o 18:357ddf1602d5 willconflict first version
875 |/
875 |/
876 o 17:61bd55f69bc4 bar foo
876 o 17:61bd55f69bc4 bar foo
877 |
877 |
878 ~
878 ~
879 $ hg rebase -r ".^^ + .^ + ." -d 19
879 $ hg rebase -r ".^^ + .^ + ." -d 19
880 rebasing 20:b82fb57ea638 "willconflict second version"
880 rebasing 20:b82fb57ea638 "willconflict second version"
881 merging willconflict
881 merging willconflict
882 warning: conflicts while merging willconflict! (edit, then use 'hg resolve --mark')
882 warning: conflicts while merging willconflict! (edit, then use 'hg resolve --mark')
883 unresolved conflicts (see hg resolve, then hg rebase --continue)
883 unresolved conflicts (see hg resolve, then hg rebase --continue)
884 [1]
884 [1]
885
885
886 $ hg resolve --mark willconflict
886 $ hg resolve --mark willconflict
887 (no more unresolved files)
887 (no more unresolved files)
888 continue: hg rebase --continue
888 continue: hg rebase --continue
889 $ hg rebase --continue
889 $ hg rebase --continue
890 rebasing 20:b82fb57ea638 "willconflict second version"
890 rebasing 20:b82fb57ea638 "willconflict second version"
891 note: not rebasing 21:8b31da3c4919 "dummy change", already in destination as 19:601db7a18f51 "dummy change successor"
891 note: not rebasing 21:8b31da3c4919 "dummy change", already in destination as 19:601db7a18f51 "dummy change successor"
892 rebasing 22:7bdc8a87673d "dummy change" (tip)
892 rebasing 22:7bdc8a87673d "dummy change" (tip)
893 $ cd ..
893 $ cd ..
894
894
895 rebase source is obsoleted (issue5198)
895 rebase source is obsoleted (issue5198)
896 ---------------------------------
896 ---------------------------------
897
897
898 $ hg clone base amended
898 $ hg clone base amended
899 updating to branch default
899 updating to branch default
900 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
900 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
901 $ cd amended
901 $ cd amended
902 $ hg up 9520eea781bc
902 $ hg up 9520eea781bc
903 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
903 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
904 $ echo 1 >> E
904 $ echo 1 >> E
905 $ hg commit --amend -m "E'"
905 $ hg commit --amend -m "E'"
906 $ hg log -G
906 $ hg log -G
907 @ 9:69abe8906104 E'
907 @ 9:69abe8906104 E'
908 |
908 |
909 | o 7:02de42196ebe H
909 | o 7:02de42196ebe H
910 | |
910 | |
911 | | o 6:eea13746799a G
911 | | o 6:eea13746799a G
912 | |/|
912 | |/|
913 | o | 5:24b6387c8c8c F
913 | o | 5:24b6387c8c8c F
914 |/ /
914 |/ /
915 | x 4:9520eea781bc E
915 | x 4:9520eea781bc E
916 |/
916 |/
917 | o 3:32af7686d403 D
917 | o 3:32af7686d403 D
918 | |
918 | |
919 | o 2:5fddd98957c8 C
919 | o 2:5fddd98957c8 C
920 | |
920 | |
921 | o 1:42ccdea3bb16 B
921 | o 1:42ccdea3bb16 B
922 |/
922 |/
923 o 0:cd010b8cd998 A
923 o 0:cd010b8cd998 A
924
924
925 $ hg rebase -d . -s 9520eea781bc
925 $ hg rebase -d . -s 9520eea781bc
926 note: not rebasing 4:9520eea781bc "E", already in destination as 9:69abe8906104 "E'"
926 note: not rebasing 4:9520eea781bc "E", already in destination as 9:69abe8906104 "E'"
927 rebasing 6:eea13746799a "G"
927 rebasing 6:eea13746799a "G"
928 $ hg log -G
928 $ hg log -G
929 o 10:17be06e82e95 G
929 o 10:17be06e82e95 G
930 |\
930 |\
931 | @ 9:69abe8906104 E'
931 | @ 9:69abe8906104 E'
932 | |
932 | |
933 +---o 7:02de42196ebe H
933 +---o 7:02de42196ebe H
934 | |
934 | |
935 o | 5:24b6387c8c8c F
935 o | 5:24b6387c8c8c F
936 |/
936 |/
937 | o 3:32af7686d403 D
937 | o 3:32af7686d403 D
938 | |
938 | |
939 | o 2:5fddd98957c8 C
939 | o 2:5fddd98957c8 C
940 | |
940 | |
941 | o 1:42ccdea3bb16 B
941 | o 1:42ccdea3bb16 B
942 |/
942 |/
943 o 0:cd010b8cd998 A
943 o 0:cd010b8cd998 A
944
944
945 $ cd ..
945 $ cd ..
946
946
947 Test that bookmark is moved and working dir is updated when all changesets have
947 Test that bookmark is moved and working dir is updated when all changesets have
948 equivalents in destination
948 equivalents in destination
949 $ hg init rbsrepo && cd rbsrepo
949 $ hg init rbsrepo && cd rbsrepo
950 $ echo "[experimental]" > .hg/hgrc
950 $ echo "[experimental]" > .hg/hgrc
951 $ echo "evolution=all" >> .hg/hgrc
951 $ echo "evolution=all" >> .hg/hgrc
952 $ echo "rebaseskipobsolete=on" >> .hg/hgrc
952 $ echo "rebaseskipobsolete=on" >> .hg/hgrc
953 $ echo root > root && hg ci -Am root
953 $ echo root > root && hg ci -Am root
954 adding root
954 adding root
955 $ echo a > a && hg ci -Am a
955 $ echo a > a && hg ci -Am a
956 adding a
956 adding a
957 $ hg up 0
957 $ hg up 0
958 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
958 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
959 $ echo b > b && hg ci -Am b
959 $ echo b > b && hg ci -Am b
960 adding b
960 adding b
961 created new head
961 created new head
962 $ hg rebase -r 2 -d 1
962 $ hg rebase -r 2 -d 1
963 rebasing 2:1e9a3c00cbe9 "b" (tip)
963 rebasing 2:1e9a3c00cbe9 "b" (tip)
964 $ hg log -r . # working dir is at rev 3 (successor of 2)
964 $ hg log -r . # working dir is at rev 3 (successor of 2)
965 3:be1832deae9a b (no-eol)
965 3:be1832deae9a b (no-eol)
966 $ hg book -r 2 mybook --hidden # rev 2 has a bookmark on it now
966 $ hg book -r 2 mybook --hidden # rev 2 has a bookmark on it now
967 $ hg up 2 && hg log -r . # working dir is at rev 2 again
967 $ hg up 2 && hg log -r . # working dir is at rev 2 again
968 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
968 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
969 2:1e9a3c00cbe9 b (no-eol)
969 2:1e9a3c00cbe9 b (no-eol)
970 $ hg rebase -r 2 -d 3
970 $ hg rebase -r 2 -d 3 --config experimental.evolution.track-operation=1
971 note: not rebasing 2:1e9a3c00cbe9 "b" (mybook), already in destination as 3:be1832deae9a "b"
971 note: not rebasing 2:1e9a3c00cbe9 "b" (mybook), already in destination as 3:be1832deae9a "b"
972 Check that working directory was updated to rev 3 although rev 2 was skipped
972 Check that working directory was updated to rev 3 although rev 2 was skipped
973 during the rebase operation
973 during the rebase operation
974 $ hg log -r .
974 $ hg log -r .
975 3:be1832deae9a b (no-eol)
975 3:be1832deae9a b (no-eol)
976
976
977 Check that bookmark was moved to rev 3 although rev 2 was skipped
977 Check that bookmark was moved to rev 3 although rev 2 was skipped
978 during the rebase operation
978 during the rebase operation
979 $ hg bookmarks
979 $ hg bookmarks
980 mybook 3:be1832deae9a
980 mybook 3:be1832deae9a
981 $ hg debugobsolete --rev tip
982 1e9a3c00cbe90d236ac05ef61efcc5e40b7412bc be1832deae9ac531caa7438b8dcf6055a122cd8e 0 (*) {'user': 'test'} (glob)
General Comments 0
You need to be logged in to leave comments. Login now