##// END OF EJS Templates
transaction: quietly rollback if no other changes than temporary files...
marmoute -
r50890:27fd12ec default
parent child Browse files
Show More
@@ -1,786 +1,795 b''
1 # transaction.py - simple journaling scheme for mercurial
1 # transaction.py - simple journaling scheme for mercurial
2 #
2 #
3 # This transaction scheme is intended to gracefully handle program
3 # This transaction scheme is intended to gracefully handle program
4 # errors and interruptions. More serious failures like system crashes
4 # errors and interruptions. More serious failures like system crashes
5 # can be recovered with an fsck-like tool. As the whole repository is
5 # can be recovered with an fsck-like tool. As the whole repository is
6 # effectively log-structured, this should amount to simply truncating
6 # effectively log-structured, this should amount to simply truncating
7 # anything that isn't referenced in the changelog.
7 # anything that isn't referenced in the changelog.
8 #
8 #
9 # Copyright 2005, 2006 Olivia Mackall <olivia@selenic.com>
9 # Copyright 2005, 2006 Olivia Mackall <olivia@selenic.com>
10 #
10 #
11 # This software may be used and distributed according to the terms of the
11 # This software may be used and distributed according to the terms of the
12 # GNU General Public License version 2 or any later version.
12 # GNU General Public License version 2 or any later version.
13
13
14
14
15 from .i18n import _
15 from .i18n import _
16 from . import (
16 from . import (
17 error,
17 error,
18 pycompat,
18 pycompat,
19 util,
19 util,
20 )
20 )
21 from .utils import stringutil
21 from .utils import stringutil
22
22
23 version = 2
23 version = 2
24
24
25 GEN_GROUP_ALL = b'all'
25 GEN_GROUP_ALL = b'all'
26 GEN_GROUP_PRE_FINALIZE = b'prefinalize'
26 GEN_GROUP_PRE_FINALIZE = b'prefinalize'
27 GEN_GROUP_POST_FINALIZE = b'postfinalize'
27 GEN_GROUP_POST_FINALIZE = b'postfinalize'
28
28
29
29
30 def active(func):
30 def active(func):
31 def _active(self, *args, **kwds):
31 def _active(self, *args, **kwds):
32 if self._count == 0:
32 if self._count == 0:
33 raise error.ProgrammingError(
33 raise error.ProgrammingError(
34 b'cannot use transaction when it is already committed/aborted'
34 b'cannot use transaction when it is already committed/aborted'
35 )
35 )
36 return func(self, *args, **kwds)
36 return func(self, *args, **kwds)
37
37
38 return _active
38 return _active
39
39
40
40
41 def _playback(
41 def _playback(
42 journal,
42 journal,
43 report,
43 report,
44 opener,
44 opener,
45 vfsmap,
45 vfsmap,
46 entries,
46 entries,
47 backupentries,
47 backupentries,
48 unlink=True,
48 unlink=True,
49 checkambigfiles=None,
49 checkambigfiles=None,
50 ):
50 ):
51 for f, o in sorted(dict(entries).items()):
51 for f, o in sorted(dict(entries).items()):
52 if o or not unlink:
52 if o or not unlink:
53 checkambig = checkambigfiles and (f, b'') in checkambigfiles
53 checkambig = checkambigfiles and (f, b'') in checkambigfiles
54 try:
54 try:
55 fp = opener(f, b'a', checkambig=checkambig)
55 fp = opener(f, b'a', checkambig=checkambig)
56 if fp.tell() < o:
56 if fp.tell() < o:
57 raise error.Abort(
57 raise error.Abort(
58 _(
58 _(
59 b"attempted to truncate %s to %d bytes, but it was "
59 b"attempted to truncate %s to %d bytes, but it was "
60 b"already %d bytes\n"
60 b"already %d bytes\n"
61 )
61 )
62 % (f, o, fp.tell())
62 % (f, o, fp.tell())
63 )
63 )
64 fp.truncate(o)
64 fp.truncate(o)
65 fp.close()
65 fp.close()
66 except IOError:
66 except IOError:
67 report(_(b"failed to truncate %s\n") % f)
67 report(_(b"failed to truncate %s\n") % f)
68 raise
68 raise
69 else:
69 else:
70 try:
70 try:
71 opener.unlink(f)
71 opener.unlink(f)
72 except FileNotFoundError:
72 except FileNotFoundError:
73 pass
73 pass
74
74
75 backupfiles = []
75 backupfiles = []
76 for l, f, b, c in backupentries:
76 for l, f, b, c in backupentries:
77 if l not in vfsmap and c:
77 if l not in vfsmap and c:
78 report(b"couldn't handle %s: unknown cache location %s\n" % (b, l))
78 report(b"couldn't handle %s: unknown cache location %s\n" % (b, l))
79 vfs = vfsmap[l]
79 vfs = vfsmap[l]
80 try:
80 try:
81 if f and b:
81 if f and b:
82 filepath = vfs.join(f)
82 filepath = vfs.join(f)
83 backuppath = vfs.join(b)
83 backuppath = vfs.join(b)
84 checkambig = checkambigfiles and (f, l) in checkambigfiles
84 checkambig = checkambigfiles and (f, l) in checkambigfiles
85 try:
85 try:
86 util.copyfile(backuppath, filepath, checkambig=checkambig)
86 util.copyfile(backuppath, filepath, checkambig=checkambig)
87 backupfiles.append(b)
87 backupfiles.append(b)
88 except IOError as exc:
88 except IOError as exc:
89 e_msg = stringutil.forcebytestr(exc)
89 e_msg = stringutil.forcebytestr(exc)
90 report(_(b"failed to recover %s (%s)\n") % (f, e_msg))
90 report(_(b"failed to recover %s (%s)\n") % (f, e_msg))
91 else:
91 else:
92 target = f or b
92 target = f or b
93 try:
93 try:
94 vfs.unlink(target)
94 vfs.unlink(target)
95 except FileNotFoundError:
95 except FileNotFoundError:
96 pass
96 pass
97 except (IOError, OSError, error.Abort):
97 except (IOError, OSError, error.Abort):
98 if not c:
98 if not c:
99 raise
99 raise
100
100
101 backuppath = b"%s.backupfiles" % journal
101 backuppath = b"%s.backupfiles" % journal
102 if opener.exists(backuppath):
102 if opener.exists(backuppath):
103 opener.unlink(backuppath)
103 opener.unlink(backuppath)
104 opener.unlink(journal)
104 opener.unlink(journal)
105 try:
105 try:
106 for f in backupfiles:
106 for f in backupfiles:
107 if opener.exists(f):
107 if opener.exists(f):
108 opener.unlink(f)
108 opener.unlink(f)
109 except (IOError, OSError, error.Abort):
109 except (IOError, OSError, error.Abort):
110 # only pure backup file remains, it is sage to ignore any error
110 # only pure backup file remains, it is sage to ignore any error
111 pass
111 pass
112
112
113
113
114 class transaction(util.transactional):
114 class transaction(util.transactional):
115 def __init__(
115 def __init__(
116 self,
116 self,
117 report,
117 report,
118 opener,
118 opener,
119 vfsmap,
119 vfsmap,
120 journalname,
120 journalname,
121 undoname=None,
121 undoname=None,
122 after=None,
122 after=None,
123 createmode=None,
123 createmode=None,
124 validator=None,
124 validator=None,
125 releasefn=None,
125 releasefn=None,
126 checkambigfiles=None,
126 checkambigfiles=None,
127 name='<unnamed>',
127 name='<unnamed>',
128 ):
128 ):
129 """Begin a new transaction
129 """Begin a new transaction
130
130
131 Begins a new transaction that allows rolling back writes in the event of
131 Begins a new transaction that allows rolling back writes in the event of
132 an exception.
132 an exception.
133
133
134 * `after`: called after the transaction has been committed
134 * `after`: called after the transaction has been committed
135 * `createmode`: the mode of the journal file that will be created
135 * `createmode`: the mode of the journal file that will be created
136 * `releasefn`: called after releasing (with transaction and result)
136 * `releasefn`: called after releasing (with transaction and result)
137
137
138 `checkambigfiles` is a set of (path, vfs-location) tuples,
138 `checkambigfiles` is a set of (path, vfs-location) tuples,
139 which determine whether file stat ambiguity should be avoided
139 which determine whether file stat ambiguity should be avoided
140 for corresponded files.
140 for corresponded files.
141 """
141 """
142 self._count = 1
142 self._count = 1
143 self._usages = 1
143 self._usages = 1
144 self._report = report
144 self._report = report
145 # a vfs to the store content
145 # a vfs to the store content
146 self._opener = opener
146 self._opener = opener
147 # a map to access file in various {location -> vfs}
147 # a map to access file in various {location -> vfs}
148 vfsmap = vfsmap.copy()
148 vfsmap = vfsmap.copy()
149 vfsmap[b''] = opener # set default value
149 vfsmap[b''] = opener # set default value
150 self._vfsmap = vfsmap
150 self._vfsmap = vfsmap
151 self._after = after
151 self._after = after
152 self._offsetmap = {}
152 self._offsetmap = {}
153 self._newfiles = set()
153 self._newfiles = set()
154 self._journal = journalname
154 self._journal = journalname
155 self._undoname = undoname
155 self._undoname = undoname
156 self._queue = []
156 self._queue = []
157 # A callback to do something just after releasing transaction.
157 # A callback to do something just after releasing transaction.
158 if releasefn is None:
158 if releasefn is None:
159 releasefn = lambda tr, success: None
159 releasefn = lambda tr, success: None
160 self._releasefn = releasefn
160 self._releasefn = releasefn
161
161
162 self._checkambigfiles = set()
162 self._checkambigfiles = set()
163 if checkambigfiles:
163 if checkambigfiles:
164 self._checkambigfiles.update(checkambigfiles)
164 self._checkambigfiles.update(checkambigfiles)
165
165
166 self._names = [name]
166 self._names = [name]
167
167
168 # A dict dedicated to precisely tracking the changes introduced in the
168 # A dict dedicated to precisely tracking the changes introduced in the
169 # transaction.
169 # transaction.
170 self.changes = {}
170 self.changes = {}
171
171
172 # a dict of arguments to be passed to hooks
172 # a dict of arguments to be passed to hooks
173 self.hookargs = {}
173 self.hookargs = {}
174 self._file = opener.open(self._journal, b"w+")
174 self._file = opener.open(self._journal, b"w+")
175
175
176 # a list of ('location', 'path', 'backuppath', cache) entries.
176 # a list of ('location', 'path', 'backuppath', cache) entries.
177 # - if 'backuppath' is empty, no file existed at backup time
177 # - if 'backuppath' is empty, no file existed at backup time
178 # - if 'path' is empty, this is a temporary transaction file
178 # - if 'path' is empty, this is a temporary transaction file
179 # - if 'location' is not empty, the path is outside main opener reach.
179 # - if 'location' is not empty, the path is outside main opener reach.
180 # use 'location' value as a key in a vfsmap to find the right 'vfs'
180 # use 'location' value as a key in a vfsmap to find the right 'vfs'
181 # (cache is currently unused)
181 # (cache is currently unused)
182 self._backupentries = []
182 self._backupentries = []
183 self._backupmap = {}
183 self._backupmap = {}
184 self._backupjournal = b"%s.backupfiles" % self._journal
184 self._backupjournal = b"%s.backupfiles" % self._journal
185 self._backupsfile = opener.open(self._backupjournal, b'w')
185 self._backupsfile = opener.open(self._backupjournal, b'w')
186 self._backupsfile.write(b'%d\n' % version)
186 self._backupsfile.write(b'%d\n' % version)
187
187
188 if createmode is not None:
188 if createmode is not None:
189 opener.chmod(self._journal, createmode & 0o666)
189 opener.chmod(self._journal, createmode & 0o666)
190 opener.chmod(self._backupjournal, createmode & 0o666)
190 opener.chmod(self._backupjournal, createmode & 0o666)
191
191
192 # hold file generations to be performed on commit
192 # hold file generations to be performed on commit
193 self._filegenerators = {}
193 self._filegenerators = {}
194 # hold callback to write pending data for hooks
194 # hold callback to write pending data for hooks
195 self._pendingcallback = {}
195 self._pendingcallback = {}
196 # True is any pending data have been written ever
196 # True is any pending data have been written ever
197 self._anypending = False
197 self._anypending = False
198 # holds callback to call when writing the transaction
198 # holds callback to call when writing the transaction
199 self._finalizecallback = {}
199 self._finalizecallback = {}
200 # holds callback to call when validating the transaction
200 # holds callback to call when validating the transaction
201 # should raise exception if anything is wrong
201 # should raise exception if anything is wrong
202 self._validatecallback = {}
202 self._validatecallback = {}
203 if validator is not None:
203 if validator is not None:
204 self._validatecallback[b'001-userhooks'] = validator
204 self._validatecallback[b'001-userhooks'] = validator
205 # hold callback for post transaction close
205 # hold callback for post transaction close
206 self._postclosecallback = {}
206 self._postclosecallback = {}
207 # holds callbacks to call during abort
207 # holds callbacks to call during abort
208 self._abortcallback = {}
208 self._abortcallback = {}
209
209
210 def __repr__(self):
210 def __repr__(self):
211 name = '/'.join(self._names)
211 name = '/'.join(self._names)
212 return '<transaction name=%s, count=%d, usages=%d>' % (
212 return '<transaction name=%s, count=%d, usages=%d>' % (
213 name,
213 name,
214 self._count,
214 self._count,
215 self._usages,
215 self._usages,
216 )
216 )
217
217
218 def __del__(self):
218 def __del__(self):
219 if self._journal:
219 if self._journal:
220 self._abort()
220 self._abort()
221
221
222 @property
222 @property
223 def finalized(self):
223 def finalized(self):
224 return self._finalizecallback is None
224 return self._finalizecallback is None
225
225
226 @active
226 @active
227 def startgroup(self):
227 def startgroup(self):
228 """delay registration of file entry
228 """delay registration of file entry
229
229
230 This is used by strip to delay vision of strip offset. The transaction
230 This is used by strip to delay vision of strip offset. The transaction
231 sees either none or all of the strip actions to be done."""
231 sees either none or all of the strip actions to be done."""
232 self._queue.append([])
232 self._queue.append([])
233
233
234 @active
234 @active
235 def endgroup(self):
235 def endgroup(self):
236 """apply delayed registration of file entry.
236 """apply delayed registration of file entry.
237
237
238 This is used by strip to delay vision of strip offset. The transaction
238 This is used by strip to delay vision of strip offset. The transaction
239 sees either none or all of the strip actions to be done."""
239 sees either none or all of the strip actions to be done."""
240 q = self._queue.pop()
240 q = self._queue.pop()
241 for f, o in q:
241 for f, o in q:
242 self._addentry(f, o)
242 self._addentry(f, o)
243
243
244 @active
244 @active
245 def add(self, file, offset):
245 def add(self, file, offset):
246 """record the state of an append-only file before update"""
246 """record the state of an append-only file before update"""
247 if (
247 if (
248 file in self._newfiles
248 file in self._newfiles
249 or file in self._offsetmap
249 or file in self._offsetmap
250 or file in self._backupmap
250 or file in self._backupmap
251 ):
251 ):
252 return
252 return
253 if self._queue:
253 if self._queue:
254 self._queue[-1].append((file, offset))
254 self._queue[-1].append((file, offset))
255 return
255 return
256
256
257 self._addentry(file, offset)
257 self._addentry(file, offset)
258
258
259 def _addentry(self, file, offset):
259 def _addentry(self, file, offset):
260 """add a append-only entry to memory and on-disk state"""
260 """add a append-only entry to memory and on-disk state"""
261 if (
261 if (
262 file in self._newfiles
262 file in self._newfiles
263 or file in self._offsetmap
263 or file in self._offsetmap
264 or file in self._backupmap
264 or file in self._backupmap
265 ):
265 ):
266 return
266 return
267 if offset:
267 if offset:
268 self._offsetmap[file] = offset
268 self._offsetmap[file] = offset
269 else:
269 else:
270 self._newfiles.add(file)
270 self._newfiles.add(file)
271 # add enough data to the journal to do the truncate
271 # add enough data to the journal to do the truncate
272 self._file.write(b"%s\0%d\n" % (file, offset))
272 self._file.write(b"%s\0%d\n" % (file, offset))
273 self._file.flush()
273 self._file.flush()
274
274
275 @active
275 @active
276 def addbackup(self, file, hardlink=True, location=b''):
276 def addbackup(self, file, hardlink=True, location=b''):
277 """Adds a backup of the file to the transaction
277 """Adds a backup of the file to the transaction
278
278
279 Calling addbackup() creates a hardlink backup of the specified file
279 Calling addbackup() creates a hardlink backup of the specified file
280 that is used to recover the file in the event of the transaction
280 that is used to recover the file in the event of the transaction
281 aborting.
281 aborting.
282
282
283 * `file`: the file path, relative to .hg/store
283 * `file`: the file path, relative to .hg/store
284 * `hardlink`: use a hardlink to quickly create the backup
284 * `hardlink`: use a hardlink to quickly create the backup
285 """
285 """
286 if self._queue:
286 if self._queue:
287 msg = b'cannot use transaction.addbackup inside "group"'
287 msg = b'cannot use transaction.addbackup inside "group"'
288 raise error.ProgrammingError(msg)
288 raise error.ProgrammingError(msg)
289
289
290 if (
290 if (
291 file in self._newfiles
291 file in self._newfiles
292 or file in self._offsetmap
292 or file in self._offsetmap
293 or file in self._backupmap
293 or file in self._backupmap
294 ):
294 ):
295 return
295 return
296 vfs = self._vfsmap[location]
296 vfs = self._vfsmap[location]
297 dirname, filename = vfs.split(file)
297 dirname, filename = vfs.split(file)
298 backupfilename = b"%s.backup.%s" % (self._journal, filename)
298 backupfilename = b"%s.backup.%s" % (self._journal, filename)
299 backupfile = vfs.reljoin(dirname, backupfilename)
299 backupfile = vfs.reljoin(dirname, backupfilename)
300 if vfs.exists(file):
300 if vfs.exists(file):
301 filepath = vfs.join(file)
301 filepath = vfs.join(file)
302 backuppath = vfs.join(backupfile)
302 backuppath = vfs.join(backupfile)
303 util.copyfile(filepath, backuppath, hardlink=hardlink)
303 util.copyfile(filepath, backuppath, hardlink=hardlink)
304 else:
304 else:
305 backupfile = b''
305 backupfile = b''
306
306
307 self._addbackupentry((location, file, backupfile, False))
307 self._addbackupentry((location, file, backupfile, False))
308
308
309 def _addbackupentry(self, entry):
309 def _addbackupentry(self, entry):
310 """register a new backup entry and write it to disk"""
310 """register a new backup entry and write it to disk"""
311 self._backupentries.append(entry)
311 self._backupentries.append(entry)
312 self._backupmap[entry[1]] = len(self._backupentries) - 1
312 self._backupmap[entry[1]] = len(self._backupentries) - 1
313 self._backupsfile.write(b"%s\0%s\0%s\0%d\n" % entry)
313 self._backupsfile.write(b"%s\0%s\0%s\0%d\n" % entry)
314 self._backupsfile.flush()
314 self._backupsfile.flush()
315
315
316 @active
316 @active
317 def registertmp(self, tmpfile, location=b''):
317 def registertmp(self, tmpfile, location=b''):
318 """register a temporary transaction file
318 """register a temporary transaction file
319
319
320 Such files will be deleted when the transaction exits (on both
320 Such files will be deleted when the transaction exits (on both
321 failure and success).
321 failure and success).
322 """
322 """
323 self._addbackupentry((location, b'', tmpfile, False))
323 self._addbackupentry((location, b'', tmpfile, False))
324
324
325 @active
325 @active
326 def addfilegenerator(
326 def addfilegenerator(
327 self,
327 self,
328 genid,
328 genid,
329 filenames,
329 filenames,
330 genfunc,
330 genfunc,
331 order=0,
331 order=0,
332 location=b'',
332 location=b'',
333 post_finalize=False,
333 post_finalize=False,
334 ):
334 ):
335 """add a function to generates some files at transaction commit
335 """add a function to generates some files at transaction commit
336
336
337 The `genfunc` argument is a function capable of generating proper
337 The `genfunc` argument is a function capable of generating proper
338 content of each entry in the `filename` tuple.
338 content of each entry in the `filename` tuple.
339
339
340 At transaction close time, `genfunc` will be called with one file
340 At transaction close time, `genfunc` will be called with one file
341 object argument per entries in `filenames`.
341 object argument per entries in `filenames`.
342
342
343 The transaction itself is responsible for the backup, creation and
343 The transaction itself is responsible for the backup, creation and
344 final write of such file.
344 final write of such file.
345
345
346 The `genid` argument is used to ensure the same set of file is only
346 The `genid` argument is used to ensure the same set of file is only
347 generated once. Call to `addfilegenerator` for a `genid` already
347 generated once. Call to `addfilegenerator` for a `genid` already
348 present will overwrite the old entry.
348 present will overwrite the old entry.
349
349
350 The `order` argument may be used to control the order in which multiple
350 The `order` argument may be used to control the order in which multiple
351 generator will be executed.
351 generator will be executed.
352
352
353 The `location` arguments may be used to indicate the files are located
353 The `location` arguments may be used to indicate the files are located
354 outside of the the standard directory for transaction. It should match
354 outside of the the standard directory for transaction. It should match
355 one of the key of the `transaction.vfsmap` dictionary.
355 one of the key of the `transaction.vfsmap` dictionary.
356
356
357 The `post_finalize` argument can be set to `True` for file generation
357 The `post_finalize` argument can be set to `True` for file generation
358 that must be run after the transaction has been finalized.
358 that must be run after the transaction has been finalized.
359 """
359 """
360 # For now, we are unable to do proper backup and restore of custom vfs
360 # For now, we are unable to do proper backup and restore of custom vfs
361 # but for bookmarks that are handled outside this mechanism.
361 # but for bookmarks that are handled outside this mechanism.
362 entry = (order, filenames, genfunc, location, post_finalize)
362 entry = (order, filenames, genfunc, location, post_finalize)
363 self._filegenerators[genid] = entry
363 self._filegenerators[genid] = entry
364
364
365 @active
365 @active
366 def removefilegenerator(self, genid):
366 def removefilegenerator(self, genid):
367 """reverse of addfilegenerator, remove a file generator function"""
367 """reverse of addfilegenerator, remove a file generator function"""
368 if genid in self._filegenerators:
368 if genid in self._filegenerators:
369 del self._filegenerators[genid]
369 del self._filegenerators[genid]
370
370
371 def _generatefiles(self, suffix=b'', group=GEN_GROUP_ALL):
371 def _generatefiles(self, suffix=b'', group=GEN_GROUP_ALL):
372 # write files registered for generation
372 # write files registered for generation
373 any = False
373 any = False
374
374
375 if group == GEN_GROUP_ALL:
375 if group == GEN_GROUP_ALL:
376 skip_post = skip_pre = False
376 skip_post = skip_pre = False
377 else:
377 else:
378 skip_pre = group == GEN_GROUP_POST_FINALIZE
378 skip_pre = group == GEN_GROUP_POST_FINALIZE
379 skip_post = group == GEN_GROUP_PRE_FINALIZE
379 skip_post = group == GEN_GROUP_PRE_FINALIZE
380
380
381 for id, entry in sorted(self._filegenerators.items()):
381 for id, entry in sorted(self._filegenerators.items()):
382 any = True
382 any = True
383 order, filenames, genfunc, location, post_finalize = entry
383 order, filenames, genfunc, location, post_finalize = entry
384
384
385 # for generation at closing, check if it's before or after finalize
385 # for generation at closing, check if it's before or after finalize
386 if skip_post and post_finalize:
386 if skip_post and post_finalize:
387 continue
387 continue
388 elif skip_pre and not post_finalize:
388 elif skip_pre and not post_finalize:
389 continue
389 continue
390
390
391 vfs = self._vfsmap[location]
391 vfs = self._vfsmap[location]
392 files = []
392 files = []
393 try:
393 try:
394 for name in filenames:
394 for name in filenames:
395 name += suffix
395 name += suffix
396 if suffix:
396 if suffix:
397 self.registertmp(name, location=location)
397 self.registertmp(name, location=location)
398 checkambig = False
398 checkambig = False
399 else:
399 else:
400 self.addbackup(name, location=location)
400 self.addbackup(name, location=location)
401 checkambig = (name, location) in self._checkambigfiles
401 checkambig = (name, location) in self._checkambigfiles
402 files.append(
402 files.append(
403 vfs(name, b'w', atomictemp=True, checkambig=checkambig)
403 vfs(name, b'w', atomictemp=True, checkambig=checkambig)
404 )
404 )
405 genfunc(*files)
405 genfunc(*files)
406 for f in files:
406 for f in files:
407 f.close()
407 f.close()
408 # skip discard() loop since we're sure no open file remains
408 # skip discard() loop since we're sure no open file remains
409 del files[:]
409 del files[:]
410 finally:
410 finally:
411 for f in files:
411 for f in files:
412 f.discard()
412 f.discard()
413 return any
413 return any
414
414
415 @active
415 @active
416 def findoffset(self, file):
416 def findoffset(self, file):
417 if file in self._newfiles:
417 if file in self._newfiles:
418 return 0
418 return 0
419 return self._offsetmap.get(file)
419 return self._offsetmap.get(file)
420
420
421 @active
421 @active
422 def readjournal(self):
422 def readjournal(self):
423 self._file.seek(0)
423 self._file.seek(0)
424 entries = []
424 entries = []
425 for l in self._file.readlines():
425 for l in self._file.readlines():
426 file, troffset = l.split(b'\0')
426 file, troffset = l.split(b'\0')
427 entries.append((file, int(troffset)))
427 entries.append((file, int(troffset)))
428 return entries
428 return entries
429
429
430 @active
430 @active
431 def replace(self, file, offset):
431 def replace(self, file, offset):
432 """
432 """
433 replace can only replace already committed entries
433 replace can only replace already committed entries
434 that are not pending in the queue
434 that are not pending in the queue
435 """
435 """
436 if file in self._newfiles:
436 if file in self._newfiles:
437 if not offset:
437 if not offset:
438 return
438 return
439 self._newfiles.remove(file)
439 self._newfiles.remove(file)
440 self._offsetmap[file] = offset
440 self._offsetmap[file] = offset
441 elif file in self._offsetmap:
441 elif file in self._offsetmap:
442 if not offset:
442 if not offset:
443 del self._offsetmap[file]
443 del self._offsetmap[file]
444 self._newfiles.add(file)
444 self._newfiles.add(file)
445 else:
445 else:
446 self._offsetmap[file] = offset
446 self._offsetmap[file] = offset
447 else:
447 else:
448 raise KeyError(file)
448 raise KeyError(file)
449 self._file.write(b"%s\0%d\n" % (file, offset))
449 self._file.write(b"%s\0%d\n" % (file, offset))
450 self._file.flush()
450 self._file.flush()
451
451
452 @active
452 @active
453 def nest(self, name='<unnamed>'):
453 def nest(self, name='<unnamed>'):
454 self._count += 1
454 self._count += 1
455 self._usages += 1
455 self._usages += 1
456 self._names.append(name)
456 self._names.append(name)
457 return self
457 return self
458
458
459 def release(self):
459 def release(self):
460 if self._count > 0:
460 if self._count > 0:
461 self._usages -= 1
461 self._usages -= 1
462 if self._names:
462 if self._names:
463 self._names.pop()
463 self._names.pop()
464 # if the transaction scopes are left without being closed, fail
464 # if the transaction scopes are left without being closed, fail
465 if self._count > 0 and self._usages == 0:
465 if self._count > 0 and self._usages == 0:
466 self._abort()
466 self._abort()
467
467
468 def running(self):
468 def running(self):
469 return self._count > 0
469 return self._count > 0
470
470
471 def addpending(self, category, callback):
471 def addpending(self, category, callback):
472 """add a callback to be called when the transaction is pending
472 """add a callback to be called when the transaction is pending
473
473
474 The transaction will be given as callback's first argument.
474 The transaction will be given as callback's first argument.
475
475
476 Category is a unique identifier to allow overwriting an old callback
476 Category is a unique identifier to allow overwriting an old callback
477 with a newer callback.
477 with a newer callback.
478 """
478 """
479 self._pendingcallback[category] = callback
479 self._pendingcallback[category] = callback
480
480
481 @active
481 @active
482 def writepending(self):
482 def writepending(self):
483 """write pending file to temporary version
483 """write pending file to temporary version
484
484
485 This is used to allow hooks to view a transaction before commit"""
485 This is used to allow hooks to view a transaction before commit"""
486 categories = sorted(self._pendingcallback)
486 categories = sorted(self._pendingcallback)
487 for cat in categories:
487 for cat in categories:
488 # remove callback since the data will have been flushed
488 # remove callback since the data will have been flushed
489 any = self._pendingcallback.pop(cat)(self)
489 any = self._pendingcallback.pop(cat)(self)
490 self._anypending = self._anypending or any
490 self._anypending = self._anypending or any
491 self._anypending |= self._generatefiles(suffix=b'.pending')
491 self._anypending |= self._generatefiles(suffix=b'.pending')
492 return self._anypending
492 return self._anypending
493
493
494 @active
494 @active
495 def hasfinalize(self, category):
495 def hasfinalize(self, category):
496 """check is a callback already exist for a category"""
496 """check is a callback already exist for a category"""
497 return category in self._finalizecallback
497 return category in self._finalizecallback
498
498
499 @active
499 @active
500 def addfinalize(self, category, callback):
500 def addfinalize(self, category, callback):
501 """add a callback to be called when the transaction is closed
501 """add a callback to be called when the transaction is closed
502
502
503 The transaction will be given as callback's first argument.
503 The transaction will be given as callback's first argument.
504
504
505 Category is a unique identifier to allow overwriting old callbacks with
505 Category is a unique identifier to allow overwriting old callbacks with
506 newer callbacks.
506 newer callbacks.
507 """
507 """
508 self._finalizecallback[category] = callback
508 self._finalizecallback[category] = callback
509
509
510 @active
510 @active
511 def addpostclose(self, category, callback):
511 def addpostclose(self, category, callback):
512 """add or replace a callback to be called after the transaction closed
512 """add or replace a callback to be called after the transaction closed
513
513
514 The transaction will be given as callback's first argument.
514 The transaction will be given as callback's first argument.
515
515
516 Category is a unique identifier to allow overwriting an old callback
516 Category is a unique identifier to allow overwriting an old callback
517 with a newer callback.
517 with a newer callback.
518 """
518 """
519 self._postclosecallback[category] = callback
519 self._postclosecallback[category] = callback
520
520
521 @active
521 @active
522 def getpostclose(self, category):
522 def getpostclose(self, category):
523 """return a postclose callback added before, or None"""
523 """return a postclose callback added before, or None"""
524 return self._postclosecallback.get(category, None)
524 return self._postclosecallback.get(category, None)
525
525
526 @active
526 @active
527 def addabort(self, category, callback):
527 def addabort(self, category, callback):
528 """add a callback to be called when the transaction is aborted.
528 """add a callback to be called when the transaction is aborted.
529
529
530 The transaction will be given as the first argument to the callback.
530 The transaction will be given as the first argument to the callback.
531
531
532 Category is a unique identifier to allow overwriting an old callback
532 Category is a unique identifier to allow overwriting an old callback
533 with a newer callback.
533 with a newer callback.
534 """
534 """
535 self._abortcallback[category] = callback
535 self._abortcallback[category] = callback
536
536
537 @active
537 @active
538 def addvalidator(self, category, callback):
538 def addvalidator(self, category, callback):
539 """adds a callback to be called when validating the transaction.
539 """adds a callback to be called when validating the transaction.
540
540
541 The transaction will be given as the first argument to the callback.
541 The transaction will be given as the first argument to the callback.
542
542
543 callback should raise exception if to abort transaction"""
543 callback should raise exception if to abort transaction"""
544 self._validatecallback[category] = callback
544 self._validatecallback[category] = callback
545
545
546 @active
546 @active
547 def close(self):
547 def close(self):
548 '''commit the transaction'''
548 '''commit the transaction'''
549 if self._count == 1:
549 if self._count == 1:
550 for category in sorted(self._validatecallback):
550 for category in sorted(self._validatecallback):
551 self._validatecallback[category](self)
551 self._validatecallback[category](self)
552 self._validatecallback = None # Help prevent cycles.
552 self._validatecallback = None # Help prevent cycles.
553 self._generatefiles(group=GEN_GROUP_PRE_FINALIZE)
553 self._generatefiles(group=GEN_GROUP_PRE_FINALIZE)
554 while self._finalizecallback:
554 while self._finalizecallback:
555 callbacks = self._finalizecallback
555 callbacks = self._finalizecallback
556 self._finalizecallback = {}
556 self._finalizecallback = {}
557 categories = sorted(callbacks)
557 categories = sorted(callbacks)
558 for cat in categories:
558 for cat in categories:
559 callbacks[cat](self)
559 callbacks[cat](self)
560 # Prevent double usage and help clear cycles.
560 # Prevent double usage and help clear cycles.
561 self._finalizecallback = None
561 self._finalizecallback = None
562 self._generatefiles(group=GEN_GROUP_POST_FINALIZE)
562 self._generatefiles(group=GEN_GROUP_POST_FINALIZE)
563
563
564 self._count -= 1
564 self._count -= 1
565 if self._count != 0:
565 if self._count != 0:
566 return
566 return
567 self._file.close()
567 self._file.close()
568 self._backupsfile.close()
568 self._backupsfile.close()
569 # cleanup temporary files
569 # cleanup temporary files
570 for l, f, b, c in self._backupentries:
570 for l, f, b, c in self._backupentries:
571 if l not in self._vfsmap and c:
571 if l not in self._vfsmap and c:
572 self._report(
572 self._report(
573 b"couldn't remove %s: unknown cache location %s\n" % (b, l)
573 b"couldn't remove %s: unknown cache location %s\n" % (b, l)
574 )
574 )
575 continue
575 continue
576 vfs = self._vfsmap[l]
576 vfs = self._vfsmap[l]
577 if not f and b and vfs.exists(b):
577 if not f and b and vfs.exists(b):
578 try:
578 try:
579 vfs.unlink(b)
579 vfs.unlink(b)
580 except (IOError, OSError, error.Abort) as inst:
580 except (IOError, OSError, error.Abort) as inst:
581 if not c:
581 if not c:
582 raise
582 raise
583 # Abort may be raise by read only opener
583 # Abort may be raise by read only opener
584 self._report(
584 self._report(
585 b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
585 b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
586 )
586 )
587 self._offsetmap = {}
587 self._offsetmap = {}
588 self._newfiles = set()
588 self._newfiles = set()
589 self._writeundo()
589 self._writeundo()
590 if self._after:
590 if self._after:
591 self._after()
591 self._after()
592 self._after = None # Help prevent cycles.
592 self._after = None # Help prevent cycles.
593 if self._opener.isfile(self._backupjournal):
593 if self._opener.isfile(self._backupjournal):
594 self._opener.unlink(self._backupjournal)
594 self._opener.unlink(self._backupjournal)
595 if self._opener.isfile(self._journal):
595 if self._opener.isfile(self._journal):
596 self._opener.unlink(self._journal)
596 self._opener.unlink(self._journal)
597 for l, _f, b, c in self._backupentries:
597 for l, _f, b, c in self._backupentries:
598 if l not in self._vfsmap and c:
598 if l not in self._vfsmap and c:
599 self._report(
599 self._report(
600 b"couldn't remove %s: unknown cache location"
600 b"couldn't remove %s: unknown cache location"
601 b"%s\n" % (b, l)
601 b"%s\n" % (b, l)
602 )
602 )
603 continue
603 continue
604 vfs = self._vfsmap[l]
604 vfs = self._vfsmap[l]
605 if b and vfs.exists(b):
605 if b and vfs.exists(b):
606 try:
606 try:
607 vfs.unlink(b)
607 vfs.unlink(b)
608 except (IOError, OSError, error.Abort) as inst:
608 except (IOError, OSError, error.Abort) as inst:
609 if not c:
609 if not c:
610 raise
610 raise
611 # Abort may be raise by read only opener
611 # Abort may be raise by read only opener
612 self._report(
612 self._report(
613 b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
613 b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
614 )
614 )
615 self._backupentries = []
615 self._backupentries = []
616 self._journal = None
616 self._journal = None
617
617
618 self._releasefn(self, True) # notify success of closing transaction
618 self._releasefn(self, True) # notify success of closing transaction
619 self._releasefn = None # Help prevent cycles.
619 self._releasefn = None # Help prevent cycles.
620
620
621 # run post close action
621 # run post close action
622 categories = sorted(self._postclosecallback)
622 categories = sorted(self._postclosecallback)
623 for cat in categories:
623 for cat in categories:
624 self._postclosecallback[cat](self)
624 self._postclosecallback[cat](self)
625 # Prevent double usage and help clear cycles.
625 # Prevent double usage and help clear cycles.
626 self._postclosecallback = None
626 self._postclosecallback = None
627
627
628 @active
628 @active
629 def abort(self):
629 def abort(self):
630 """abort the transaction (generally called on error, or when the
630 """abort the transaction (generally called on error, or when the
631 transaction is not explicitly committed before going out of
631 transaction is not explicitly committed before going out of
632 scope)"""
632 scope)"""
633 self._abort()
633 self._abort()
634
634
635 def _writeundo(self):
635 def _writeundo(self):
636 """write transaction data for possible future undo call"""
636 """write transaction data for possible future undo call"""
637 if self._undoname is None:
637 if self._undoname is None:
638 return
638 return
639
639
640 undo_backup_path = b"%s.backupfiles" % self._undoname
640 undo_backup_path = b"%s.backupfiles" % self._undoname
641 undobackupfile = self._opener.open(undo_backup_path, b'w')
641 undobackupfile = self._opener.open(undo_backup_path, b'w')
642 undobackupfile.write(b'%d\n' % version)
642 undobackupfile.write(b'%d\n' % version)
643 for l, f, b, c in self._backupentries:
643 for l, f, b, c in self._backupentries:
644 if not f: # temporary file
644 if not f: # temporary file
645 continue
645 continue
646 if not b:
646 if not b:
647 u = b''
647 u = b''
648 else:
648 else:
649 if l not in self._vfsmap and c:
649 if l not in self._vfsmap and c:
650 self._report(
650 self._report(
651 b"couldn't remove %s: unknown cache location"
651 b"couldn't remove %s: unknown cache location"
652 b"%s\n" % (b, l)
652 b"%s\n" % (b, l)
653 )
653 )
654 continue
654 continue
655 vfs = self._vfsmap[l]
655 vfs = self._vfsmap[l]
656 base, name = vfs.split(b)
656 base, name = vfs.split(b)
657 assert name.startswith(self._journal), name
657 assert name.startswith(self._journal), name
658 uname = name.replace(self._journal, self._undoname, 1)
658 uname = name.replace(self._journal, self._undoname, 1)
659 u = vfs.reljoin(base, uname)
659 u = vfs.reljoin(base, uname)
660 util.copyfile(vfs.join(b), vfs.join(u), hardlink=True)
660 util.copyfile(vfs.join(b), vfs.join(u), hardlink=True)
661 undobackupfile.write(b"%s\0%s\0%s\0%d\n" % (l, f, u, c))
661 undobackupfile.write(b"%s\0%s\0%s\0%d\n" % (l, f, u, c))
662 undobackupfile.close()
662 undobackupfile.close()
663
663
664 def _abort(self):
664 def _abort(self):
665 entries = self.readjournal()
665 entries = self.readjournal()
666 self._count = 0
666 self._count = 0
667 self._usages = 0
667 self._usages = 0
668 self._file.close()
668 self._file.close()
669 self._backupsfile.close()
669 self._backupsfile.close()
670
670
671 quick = self._can_quick_abort(entries)
671 quick = self._can_quick_abort(entries)
672 try:
672 try:
673 if not quick:
673 if not quick:
674 self._report(_(b"transaction abort!\n"))
674 self._report(_(b"transaction abort!\n"))
675 for cat in sorted(self._abortcallback):
675 for cat in sorted(self._abortcallback):
676 self._abortcallback[cat](self)
676 self._abortcallback[cat](self)
677 # Prevent double usage and help clear cycles.
677 # Prevent double usage and help clear cycles.
678 self._abortcallback = None
678 self._abortcallback = None
679 if quick:
679 if quick:
680 self._do_quick_abort(entries)
680 self._do_quick_abort(entries)
681 else:
681 else:
682 self._do_full_abort(entries)
682 self._do_full_abort(entries)
683 finally:
683 finally:
684 self._journal = None
684 self._journal = None
685 self._releasefn(self, False) # notify failure of transaction
685 self._releasefn(self, False) # notify failure of transaction
686 self._releasefn = None # Help prevent cycles.
686 self._releasefn = None # Help prevent cycles.
687
687
688 def _can_quick_abort(self, entries):
688 def _can_quick_abort(self, entries):
689 """False if any semantic content have been written on disk
689 """False if any semantic content have been written on disk
690
690
691 True if nothing, except temporary files has been writen on disk."""
691 True if nothing, except temporary files has been writen on disk."""
692 if entries:
692 if entries:
693 return False
693 return False
694 if self._backupentries:
694 for e in self._backupentries:
695 return False
695 if e[1]:
696 return False
696 return True
697 return True
697
698
698 def _do_quick_abort(self, entries):
699 def _do_quick_abort(self, entries):
699 """(Silently) do a quick cleanup (see _can_quick_abort)"""
700 """(Silently) do a quick cleanup (see _can_quick_abort)"""
700 assert self._can_quick_abort(entries)
701 assert self._can_quick_abort(entries)
702 tmp_files = [e for e in self._backupentries if not e[1]]
703 for vfs_id, old_path, tmp_path, xxx in tmp_files:
704 assert not old_path
705 vfs = self._vfsmap[vfs_id]
706 try:
707 vfs.unlink(tmp_path)
708 except FileNotFoundError:
709 pass
701 if self._backupjournal:
710 if self._backupjournal:
702 self._opener.unlink(self._backupjournal)
711 self._opener.unlink(self._backupjournal)
703 if self._journal:
712 if self._journal:
704 self._opener.unlink(self._journal)
713 self._opener.unlink(self._journal)
705
714
706 def _do_full_abort(self, entries):
715 def _do_full_abort(self, entries):
707 """(Noisily) rollback all the change introduced by the transaction"""
716 """(Noisily) rollback all the change introduced by the transaction"""
708 try:
717 try:
709 _playback(
718 _playback(
710 self._journal,
719 self._journal,
711 self._report,
720 self._report,
712 self._opener,
721 self._opener,
713 self._vfsmap,
722 self._vfsmap,
714 entries,
723 entries,
715 self._backupentries,
724 self._backupentries,
716 False,
725 False,
717 checkambigfiles=self._checkambigfiles,
726 checkambigfiles=self._checkambigfiles,
718 )
727 )
719 self._report(_(b"rollback completed\n"))
728 self._report(_(b"rollback completed\n"))
720 except BaseException as exc:
729 except BaseException as exc:
721 self._report(_(b"rollback failed - please run hg recover\n"))
730 self._report(_(b"rollback failed - please run hg recover\n"))
722 self._report(
731 self._report(
723 _(b"(failure reason: %s)\n") % stringutil.forcebytestr(exc)
732 _(b"(failure reason: %s)\n") % stringutil.forcebytestr(exc)
724 )
733 )
725
734
726
735
727 BAD_VERSION_MSG = _(
736 BAD_VERSION_MSG = _(
728 b"journal was created by a different version of Mercurial\n"
737 b"journal was created by a different version of Mercurial\n"
729 )
738 )
730
739
731
740
732 def rollback(opener, vfsmap, file, report, checkambigfiles=None):
741 def rollback(opener, vfsmap, file, report, checkambigfiles=None):
733 """Rolls back the transaction contained in the given file
742 """Rolls back the transaction contained in the given file
734
743
735 Reads the entries in the specified file, and the corresponding
744 Reads the entries in the specified file, and the corresponding
736 '*.backupfiles' file, to recover from an incomplete transaction.
745 '*.backupfiles' file, to recover from an incomplete transaction.
737
746
738 * `file`: a file containing a list of entries, specifying where
747 * `file`: a file containing a list of entries, specifying where
739 to truncate each file. The file should contain a list of
748 to truncate each file. The file should contain a list of
740 file\0offset pairs, delimited by newlines. The corresponding
749 file\0offset pairs, delimited by newlines. The corresponding
741 '*.backupfiles' file should contain a list of file\0backupfile
750 '*.backupfiles' file should contain a list of file\0backupfile
742 pairs, delimited by \0.
751 pairs, delimited by \0.
743
752
744 `checkambigfiles` is a set of (path, vfs-location) tuples,
753 `checkambigfiles` is a set of (path, vfs-location) tuples,
745 which determine whether file stat ambiguity should be avoided at
754 which determine whether file stat ambiguity should be avoided at
746 restoring corresponded files.
755 restoring corresponded files.
747 """
756 """
748 entries = []
757 entries = []
749 backupentries = []
758 backupentries = []
750
759
751 with opener.open(file) as fp:
760 with opener.open(file) as fp:
752 lines = fp.readlines()
761 lines = fp.readlines()
753 for l in lines:
762 for l in lines:
754 try:
763 try:
755 f, o = l.split(b'\0')
764 f, o = l.split(b'\0')
756 entries.append((f, int(o)))
765 entries.append((f, int(o)))
757 except ValueError:
766 except ValueError:
758 report(
767 report(
759 _(b"couldn't read journal entry %r!\n") % pycompat.bytestr(l)
768 _(b"couldn't read journal entry %r!\n") % pycompat.bytestr(l)
760 )
769 )
761
770
762 backupjournal = b"%s.backupfiles" % file
771 backupjournal = b"%s.backupfiles" % file
763 if opener.exists(backupjournal):
772 if opener.exists(backupjournal):
764 fp = opener.open(backupjournal)
773 fp = opener.open(backupjournal)
765 lines = fp.readlines()
774 lines = fp.readlines()
766 if lines:
775 if lines:
767 ver = lines[0][:-1]
776 ver = lines[0][:-1]
768 if ver != (b'%d' % version):
777 if ver != (b'%d' % version):
769 report(BAD_VERSION_MSG)
778 report(BAD_VERSION_MSG)
770 else:
779 else:
771 for line in lines[1:]:
780 for line in lines[1:]:
772 if line:
781 if line:
773 # Shave off the trailing newline
782 # Shave off the trailing newline
774 line = line[:-1]
783 line = line[:-1]
775 l, f, b, c = line.split(b'\0')
784 l, f, b, c = line.split(b'\0')
776 backupentries.append((l, f, b, bool(c)))
785 backupentries.append((l, f, b, bool(c)))
777
786
778 _playback(
787 _playback(
779 file,
788 file,
780 report,
789 report,
781 opener,
790 opener,
782 vfsmap,
791 vfsmap,
783 entries,
792 entries,
784 backupentries,
793 backupentries,
785 checkambigfiles=checkambigfiles,
794 checkambigfiles=checkambigfiles,
786 )
795 )
@@ -1,1261 +1,1253 b''
1
1
2 $ hg init repo
2 $ hg init repo
3 $ cd repo
3 $ cd repo
4
4
5 $ cat > $TESTTMP/hook.sh <<'EOF'
5 $ cat > $TESTTMP/hook.sh <<'EOF'
6 > echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"
6 > echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"
7 > EOF
7 > EOF
8 $ TESTHOOK="hooks.txnclose-bookmark.test=sh $TESTTMP/hook.sh"
8 $ TESTHOOK="hooks.txnclose-bookmark.test=sh $TESTTMP/hook.sh"
9
9
10 no bookmarks
10 no bookmarks
11
11
12 $ hg bookmarks
12 $ hg bookmarks
13 no bookmarks set
13 no bookmarks set
14
14
15 $ hg bookmarks -Tjson
15 $ hg bookmarks -Tjson
16 [
16 [
17 ]
17 ]
18
18
19 bookmark rev -1
19 bookmark rev -1
20
20
21 $ hg bookmark X --config "$TESTHOOK"
21 $ hg bookmark X --config "$TESTHOOK"
22 test-hook-bookmark: X: -> 0000000000000000000000000000000000000000
22 test-hook-bookmark: X: -> 0000000000000000000000000000000000000000
23
23
24 list bookmarks
24 list bookmarks
25
25
26 $ hg bookmarks
26 $ hg bookmarks
27 * X -1:000000000000
27 * X -1:000000000000
28
28
29 list bookmarks with color
29 list bookmarks with color
30
30
31 $ hg --config extensions.color= --config color.mode=ansi \
31 $ hg --config extensions.color= --config color.mode=ansi \
32 > bookmarks --color=always
32 > bookmarks --color=always
33 \x1b[0;32m * \x1b[0m\x1b[0;32mX\x1b[0m\x1b[0;32m -1:000000000000\x1b[0m (esc)
33 \x1b[0;32m * \x1b[0m\x1b[0;32mX\x1b[0m\x1b[0;32m -1:000000000000\x1b[0m (esc)
34
34
35 $ echo a > a
35 $ echo a > a
36 $ hg add a
36 $ hg add a
37 $ hg commit -m 0 --config "$TESTHOOK"
37 $ hg commit -m 0 --config "$TESTHOOK"
38 test-hook-bookmark: X: 0000000000000000000000000000000000000000 -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
38 test-hook-bookmark: X: 0000000000000000000000000000000000000000 -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
39
39
40 bookmark X moved to rev 0
40 bookmark X moved to rev 0
41
41
42 $ hg bookmarks
42 $ hg bookmarks
43 * X 0:f7b1eb17ad24
43 * X 0:f7b1eb17ad24
44
44
45 look up bookmark
45 look up bookmark
46
46
47 $ hg log -r X
47 $ hg log -r X
48 changeset: 0:f7b1eb17ad24
48 changeset: 0:f7b1eb17ad24
49 bookmark: X
49 bookmark: X
50 tag: tip
50 tag: tip
51 user: test
51 user: test
52 date: Thu Jan 01 00:00:00 1970 +0000
52 date: Thu Jan 01 00:00:00 1970 +0000
53 summary: 0
53 summary: 0
54
54
55
55
56 second bookmark for rev 0, command should work even with ui.strict on
56 second bookmark for rev 0, command should work even with ui.strict on
57
57
58 $ hg --config ui.strict=1 bookmark X2 --config "$TESTHOOK"
58 $ hg --config ui.strict=1 bookmark X2 --config "$TESTHOOK"
59 test-hook-bookmark: X2: -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
59 test-hook-bookmark: X2: -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
60
60
61 bookmark rev -1 again
61 bookmark rev -1 again
62
62
63 $ hg bookmark -r null Y
63 $ hg bookmark -r null Y
64
64
65 list bookmarks
65 list bookmarks
66
66
67 $ hg bookmarks
67 $ hg bookmarks
68 X 0:f7b1eb17ad24
68 X 0:f7b1eb17ad24
69 * X2 0:f7b1eb17ad24
69 * X2 0:f7b1eb17ad24
70 Y -1:000000000000
70 Y -1:000000000000
71 $ hg bookmarks -l
71 $ hg bookmarks -l
72 X 0:f7b1eb17ad24
72 X 0:f7b1eb17ad24
73 * X2 0:f7b1eb17ad24
73 * X2 0:f7b1eb17ad24
74 Y -1:000000000000
74 Y -1:000000000000
75 $ hg bookmarks -l X Y
75 $ hg bookmarks -l X Y
76 X 0:f7b1eb17ad24
76 X 0:f7b1eb17ad24
77 Y -1:000000000000
77 Y -1:000000000000
78 $ hg bookmarks -l .
78 $ hg bookmarks -l .
79 * X2 0:f7b1eb17ad24
79 * X2 0:f7b1eb17ad24
80 $ hg bookmarks -l X A Y
80 $ hg bookmarks -l X A Y
81 abort: bookmark 'A' does not exist
81 abort: bookmark 'A' does not exist
82 [10]
82 [10]
83 $ hg bookmarks -l -r0
83 $ hg bookmarks -l -r0
84 abort: cannot specify both --list and --rev
84 abort: cannot specify both --list and --rev
85 [10]
85 [10]
86 $ hg bookmarks -l --inactive
86 $ hg bookmarks -l --inactive
87 abort: cannot specify both --inactive and --list
87 abort: cannot specify both --inactive and --list
88 [10]
88 [10]
89
89
90 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
90 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
91 0 X
91 0 X
92 0 X2
92 0 X2
93
93
94 $ echo b > b
94 $ echo b > b
95 $ hg add b
95 $ hg add b
96 $ hg commit -m 1 --config "$TESTHOOK"
96 $ hg commit -m 1 --config "$TESTHOOK"
97 test-hook-bookmark: X2: f7b1eb17ad24730a1651fccd46c43826d1bbc2ac -> 925d80f479bb026b0fb3deb27503780b13f74123
97 test-hook-bookmark: X2: f7b1eb17ad24730a1651fccd46c43826d1bbc2ac -> 925d80f479bb026b0fb3deb27503780b13f74123
98
98
99 $ hg bookmarks -T '{rev}:{node|shortest} {bookmark} {desc|firstline}\n'
99 $ hg bookmarks -T '{rev}:{node|shortest} {bookmark} {desc|firstline}\n'
100 0:f7b1 X 0
100 0:f7b1 X 0
101 1:925d X2 1
101 1:925d X2 1
102 -1:0000 Y
102 -1:0000 Y
103
103
104 $ hg bookmarks -Tjson
104 $ hg bookmarks -Tjson
105 [
105 [
106 {
106 {
107 "active": false,
107 "active": false,
108 "bookmark": "X",
108 "bookmark": "X",
109 "node": "f7b1eb17ad24730a1651fccd46c43826d1bbc2ac",
109 "node": "f7b1eb17ad24730a1651fccd46c43826d1bbc2ac",
110 "rev": 0
110 "rev": 0
111 },
111 },
112 {
112 {
113 "active": true,
113 "active": true,
114 "bookmark": "X2",
114 "bookmark": "X2",
115 "node": "925d80f479bb026b0fb3deb27503780b13f74123",
115 "node": "925d80f479bb026b0fb3deb27503780b13f74123",
116 "rev": 1
116 "rev": 1
117 },
117 },
118 {
118 {
119 "active": false,
119 "active": false,
120 "bookmark": "Y",
120 "bookmark": "Y",
121 "node": "0000000000000000000000000000000000000000",
121 "node": "0000000000000000000000000000000000000000",
122 "rev": -1
122 "rev": -1
123 }
123 }
124 ]
124 ]
125
125
126 bookmarks revset
126 bookmarks revset
127
127
128 $ hg log -r 'bookmark()'
128 $ hg log -r 'bookmark()'
129 changeset: 0:f7b1eb17ad24
129 changeset: 0:f7b1eb17ad24
130 bookmark: X
130 bookmark: X
131 user: test
131 user: test
132 date: Thu Jan 01 00:00:00 1970 +0000
132 date: Thu Jan 01 00:00:00 1970 +0000
133 summary: 0
133 summary: 0
134
134
135 changeset: 1:925d80f479bb
135 changeset: 1:925d80f479bb
136 bookmark: X2
136 bookmark: X2
137 tag: tip
137 tag: tip
138 user: test
138 user: test
139 date: Thu Jan 01 00:00:00 1970 +0000
139 date: Thu Jan 01 00:00:00 1970 +0000
140 summary: 1
140 summary: 1
141
141
142 $ hg log -r 'bookmark(Y)'
142 $ hg log -r 'bookmark(Y)'
143 $ hg log -r 'bookmark(X2)'
143 $ hg log -r 'bookmark(X2)'
144 changeset: 1:925d80f479bb
144 changeset: 1:925d80f479bb
145 bookmark: X2
145 bookmark: X2
146 tag: tip
146 tag: tip
147 user: test
147 user: test
148 date: Thu Jan 01 00:00:00 1970 +0000
148 date: Thu Jan 01 00:00:00 1970 +0000
149 summary: 1
149 summary: 1
150
150
151 $ hg log -r 'bookmark("re:X")'
151 $ hg log -r 'bookmark("re:X")'
152 changeset: 0:f7b1eb17ad24
152 changeset: 0:f7b1eb17ad24
153 bookmark: X
153 bookmark: X
154 user: test
154 user: test
155 date: Thu Jan 01 00:00:00 1970 +0000
155 date: Thu Jan 01 00:00:00 1970 +0000
156 summary: 0
156 summary: 0
157
157
158 changeset: 1:925d80f479bb
158 changeset: 1:925d80f479bb
159 bookmark: X2
159 bookmark: X2
160 tag: tip
160 tag: tip
161 user: test
161 user: test
162 date: Thu Jan 01 00:00:00 1970 +0000
162 date: Thu Jan 01 00:00:00 1970 +0000
163 summary: 1
163 summary: 1
164
164
165 $ hg log -r 'bookmark("literal:X")'
165 $ hg log -r 'bookmark("literal:X")'
166 changeset: 0:f7b1eb17ad24
166 changeset: 0:f7b1eb17ad24
167 bookmark: X
167 bookmark: X
168 user: test
168 user: test
169 date: Thu Jan 01 00:00:00 1970 +0000
169 date: Thu Jan 01 00:00:00 1970 +0000
170 summary: 0
170 summary: 0
171
171
172
172
173 "." is expanded to the active bookmark:
173 "." is expanded to the active bookmark:
174
174
175 $ hg log -r 'bookmark(.)'
175 $ hg log -r 'bookmark(.)'
176 changeset: 1:925d80f479bb
176 changeset: 1:925d80f479bb
177 bookmark: X2
177 bookmark: X2
178 tag: tip
178 tag: tip
179 user: test
179 user: test
180 date: Thu Jan 01 00:00:00 1970 +0000
180 date: Thu Jan 01 00:00:00 1970 +0000
181 summary: 1
181 summary: 1
182
182
183
183
184 but "literal:." is not since "." seems not a literal bookmark:
184 but "literal:." is not since "." seems not a literal bookmark:
185
185
186 $ hg log -r 'bookmark("literal:.")'
186 $ hg log -r 'bookmark("literal:.")'
187 abort: bookmark '.' does not exist
187 abort: bookmark '.' does not exist
188 [10]
188 [10]
189
189
190 "." should fail if there's no active bookmark:
190 "." should fail if there's no active bookmark:
191
191
192 $ hg bookmark --inactive
192 $ hg bookmark --inactive
193 $ hg log -r 'bookmark(.)'
193 $ hg log -r 'bookmark(.)'
194 abort: no active bookmark
194 abort: no active bookmark
195 [10]
195 [10]
196 $ hg log -r 'present(bookmark(.))'
196 $ hg log -r 'present(bookmark(.))'
197
197
198 $ hg log -r 'bookmark(unknown)'
198 $ hg log -r 'bookmark(unknown)'
199 abort: bookmark 'unknown' does not exist
199 abort: bookmark 'unknown' does not exist
200 [10]
200 [10]
201 $ hg log -r 'bookmark("literal:unknown")'
201 $ hg log -r 'bookmark("literal:unknown")'
202 abort: bookmark 'unknown' does not exist
202 abort: bookmark 'unknown' does not exist
203 [10]
203 [10]
204 $ hg log -r 'bookmark("re:unknown")'
204 $ hg log -r 'bookmark("re:unknown")'
205 $ hg log -r 'present(bookmark("literal:unknown"))'
205 $ hg log -r 'present(bookmark("literal:unknown"))'
206 $ hg log -r 'present(bookmark("re:unknown"))'
206 $ hg log -r 'present(bookmark("re:unknown"))'
207
207
208 $ hg help revsets | grep 'bookmark('
208 $ hg help revsets | grep 'bookmark('
209 "bookmark([name])"
209 "bookmark([name])"
210
210
211 reactivate "X2"
211 reactivate "X2"
212
212
213 $ hg update X2
213 $ hg update X2
214 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
214 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
215 (activating bookmark X2)
215 (activating bookmark X2)
216
216
217 bookmarks X and X2 moved to rev 1, Y at rev -1
217 bookmarks X and X2 moved to rev 1, Y at rev -1
218
218
219 $ hg bookmarks
219 $ hg bookmarks
220 X 0:f7b1eb17ad24
220 X 0:f7b1eb17ad24
221 * X2 1:925d80f479bb
221 * X2 1:925d80f479bb
222 Y -1:000000000000
222 Y -1:000000000000
223
223
224 bookmark rev 0 again
224 bookmark rev 0 again
225
225
226 $ hg bookmark -r 0 Z
226 $ hg bookmark -r 0 Z
227
227
228 $ hg update X
228 $ hg update X
229 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
229 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
230 (activating bookmark X)
230 (activating bookmark X)
231 $ echo c > c
231 $ echo c > c
232 $ hg add c
232 $ hg add c
233 $ hg commit -m 2
233 $ hg commit -m 2
234 created new head
234 created new head
235
235
236 bookmarks X moved to rev 2, Y at rev -1, Z at rev 0
236 bookmarks X moved to rev 2, Y at rev -1, Z at rev 0
237
237
238 $ hg bookmarks
238 $ hg bookmarks
239 * X 2:db815d6d32e6
239 * X 2:db815d6d32e6
240 X2 1:925d80f479bb
240 X2 1:925d80f479bb
241 Y -1:000000000000
241 Y -1:000000000000
242 Z 0:f7b1eb17ad24
242 Z 0:f7b1eb17ad24
243
243
244 rename nonexistent bookmark
244 rename nonexistent bookmark
245
245
246 $ hg bookmark -m A B
246 $ hg bookmark -m A B
247 abort: bookmark 'A' does not exist
247 abort: bookmark 'A' does not exist
248 [10]
248 [10]
249
249
250 rename to existent bookmark
250 rename to existent bookmark
251
251
252 $ hg bookmark -m X Y
252 $ hg bookmark -m X Y
253 abort: bookmark 'Y' already exists (use -f to force)
253 abort: bookmark 'Y' already exists (use -f to force)
254 [255]
254 [255]
255
255
256 force rename to existent bookmark
256 force rename to existent bookmark
257
257
258 $ hg bookmark -f -m X Y
258 $ hg bookmark -f -m X Y
259
259
260 rename bookmark using .
260 rename bookmark using .
261
261
262 $ hg book rename-me
262 $ hg book rename-me
263 $ hg book -m . renamed --config "$TESTHOOK"
263 $ hg book -m . renamed --config "$TESTHOOK"
264 test-hook-bookmark: rename-me: db815d6d32e69058eadefc8cffbad37675707975 ->
264 test-hook-bookmark: rename-me: db815d6d32e69058eadefc8cffbad37675707975 ->
265 test-hook-bookmark: renamed: -> db815d6d32e69058eadefc8cffbad37675707975
265 test-hook-bookmark: renamed: -> db815d6d32e69058eadefc8cffbad37675707975
266 $ hg bookmark
266 $ hg bookmark
267 X2 1:925d80f479bb
267 X2 1:925d80f479bb
268 Y 2:db815d6d32e6
268 Y 2:db815d6d32e6
269 Z 0:f7b1eb17ad24
269 Z 0:f7b1eb17ad24
270 * renamed 2:db815d6d32e6
270 * renamed 2:db815d6d32e6
271 $ hg up -q Y
271 $ hg up -q Y
272 $ hg book -d renamed --config "$TESTHOOK"
272 $ hg book -d renamed --config "$TESTHOOK"
273 test-hook-bookmark: renamed: db815d6d32e69058eadefc8cffbad37675707975 ->
273 test-hook-bookmark: renamed: db815d6d32e69058eadefc8cffbad37675707975 ->
274
274
275 rename bookmark using . with no active bookmark
275 rename bookmark using . with no active bookmark
276
276
277 $ hg book rename-me
277 $ hg book rename-me
278 $ hg book -i rename-me
278 $ hg book -i rename-me
279 $ hg book -m . renamed
279 $ hg book -m . renamed
280 abort: no active bookmark
280 abort: no active bookmark
281 [10]
281 [10]
282 $ hg up -q Y
282 $ hg up -q Y
283 $ hg book -d rename-me
283 $ hg book -d rename-me
284
284
285 delete bookmark using .
285 delete bookmark using .
286
286
287 $ hg book delete-me
287 $ hg book delete-me
288 $ hg book -d .
288 $ hg book -d .
289 $ hg bookmark
289 $ hg bookmark
290 X2 1:925d80f479bb
290 X2 1:925d80f479bb
291 Y 2:db815d6d32e6
291 Y 2:db815d6d32e6
292 Z 0:f7b1eb17ad24
292 Z 0:f7b1eb17ad24
293 $ hg up -q Y
293 $ hg up -q Y
294
294
295 delete bookmark using . with no active bookmark
295 delete bookmark using . with no active bookmark
296
296
297 $ hg book delete-me
297 $ hg book delete-me
298 $ hg book -i delete-me
298 $ hg book -i delete-me
299 $ hg book -d .
299 $ hg book -d .
300 abort: no active bookmark
300 abort: no active bookmark
301 [10]
301 [10]
302 $ hg up -q Y
302 $ hg up -q Y
303 $ hg book -d delete-me
303 $ hg book -d delete-me
304
304
305 list bookmarks
305 list bookmarks
306
306
307 $ hg bookmark
307 $ hg bookmark
308 X2 1:925d80f479bb
308 X2 1:925d80f479bb
309 * Y 2:db815d6d32e6
309 * Y 2:db815d6d32e6
310 Z 0:f7b1eb17ad24
310 Z 0:f7b1eb17ad24
311
311
312 bookmarks from a revset
312 bookmarks from a revset
313 $ hg bookmark -r '.^1' REVSET
313 $ hg bookmark -r '.^1' REVSET
314 $ hg bookmark -r ':tip' TIP
314 $ hg bookmark -r ':tip' TIP
315 $ hg up -q TIP
315 $ hg up -q TIP
316 $ hg bookmarks
316 $ hg bookmarks
317 REVSET 0:f7b1eb17ad24
317 REVSET 0:f7b1eb17ad24
318 * TIP 2:db815d6d32e6
318 * TIP 2:db815d6d32e6
319 X2 1:925d80f479bb
319 X2 1:925d80f479bb
320 Y 2:db815d6d32e6
320 Y 2:db815d6d32e6
321 Z 0:f7b1eb17ad24
321 Z 0:f7b1eb17ad24
322
322
323 $ hg bookmark -d REVSET
323 $ hg bookmark -d REVSET
324 $ hg bookmark -d TIP
324 $ hg bookmark -d TIP
325
325
326 rename without new name or multiple names
326 rename without new name or multiple names
327
327
328 $ hg bookmark -m Y
328 $ hg bookmark -m Y
329 abort: new bookmark name required
329 abort: new bookmark name required
330 [10]
330 [10]
331 $ hg bookmark -m Y Y2 Y3
331 $ hg bookmark -m Y Y2 Y3
332 abort: only one new bookmark name allowed
332 abort: only one new bookmark name allowed
333 [10]
333 [10]
334
334
335 delete without name
335 delete without name
336
336
337 $ hg bookmark -d
337 $ hg bookmark -d
338 abort: bookmark name required
338 abort: bookmark name required
339 [10]
339 [10]
340
340
341 delete nonexistent bookmark
341 delete nonexistent bookmark
342
342
343 $ hg bookmark -d A
343 $ hg bookmark -d A
344 abort: bookmark 'A' does not exist
344 abort: bookmark 'A' does not exist
345 [10]
345 [10]
346
346
347 delete with --inactive
347 delete with --inactive
348
348
349 $ hg bookmark -d --inactive Y
349 $ hg bookmark -d --inactive Y
350 abort: cannot specify both --inactive and --delete
350 abort: cannot specify both --inactive and --delete
351 [10]
351 [10]
352
352
353 bookmark name with spaces should be stripped
353 bookmark name with spaces should be stripped
354
354
355 $ hg bookmark ' x y '
355 $ hg bookmark ' x y '
356
356
357 list bookmarks
357 list bookmarks
358
358
359 $ hg bookmarks
359 $ hg bookmarks
360 X2 1:925d80f479bb
360 X2 1:925d80f479bb
361 Y 2:db815d6d32e6
361 Y 2:db815d6d32e6
362 Z 0:f7b1eb17ad24
362 Z 0:f7b1eb17ad24
363 * x y 2:db815d6d32e6
363 * x y 2:db815d6d32e6
364 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
364 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
365 2 Y
365 2 Y
366 2 x y
366 2 x y
367 1 X2
367 1 X2
368 0 Z
368 0 Z
369
369
370 look up stripped bookmark name
370 look up stripped bookmark name
371
371
372 $ hg log -r '"x y"'
372 $ hg log -r '"x y"'
373 changeset: 2:db815d6d32e6
373 changeset: 2:db815d6d32e6
374 bookmark: Y
374 bookmark: Y
375 bookmark: x y
375 bookmark: x y
376 tag: tip
376 tag: tip
377 parent: 0:f7b1eb17ad24
377 parent: 0:f7b1eb17ad24
378 user: test
378 user: test
379 date: Thu Jan 01 00:00:00 1970 +0000
379 date: Thu Jan 01 00:00:00 1970 +0000
380 summary: 2
380 summary: 2
381
381
382
382
383 reject bookmark name with newline
383 reject bookmark name with newline
384
384
385 $ hg bookmark '
385 $ hg bookmark '
386 > '
386 > '
387 abort: bookmark names cannot consist entirely of whitespace
387 abort: bookmark names cannot consist entirely of whitespace
388 [10]
388 [10]
389
389
390 $ hg bookmark -m Z '
390 $ hg bookmark -m Z '
391 > '
391 > '
392 abort: bookmark names cannot consist entirely of whitespace
392 abort: bookmark names cannot consist entirely of whitespace
393 [10]
393 [10]
394
394
395 bookmark with reserved name
395 bookmark with reserved name
396
396
397 $ hg bookmark tip
397 $ hg bookmark tip
398 abort: the name 'tip' is reserved
398 abort: the name 'tip' is reserved
399 [10]
399 [10]
400
400
401 $ hg bookmark .
401 $ hg bookmark .
402 abort: the name '.' is reserved
402 abort: the name '.' is reserved
403 [10]
403 [10]
404
404
405 $ hg bookmark null
405 $ hg bookmark null
406 abort: the name 'null' is reserved
406 abort: the name 'null' is reserved
407 [10]
407 [10]
408
408
409
409
410 bookmark with existing name
410 bookmark with existing name
411
411
412 $ hg bookmark X2
412 $ hg bookmark X2
413 abort: bookmark 'X2' already exists (use -f to force)
413 abort: bookmark 'X2' already exists (use -f to force)
414 [255]
414 [255]
415
415
416 $ hg bookmark -m Y Z
416 $ hg bookmark -m Y Z
417 abort: bookmark 'Z' already exists (use -f to force)
417 abort: bookmark 'Z' already exists (use -f to force)
418 [255]
418 [255]
419
419
420 bookmark with name of branch
420 bookmark with name of branch
421
421
422 $ hg bookmark default
422 $ hg bookmark default
423 abort: a bookmark cannot have the name of an existing branch
423 abort: a bookmark cannot have the name of an existing branch
424 [255]
424 [255]
425
425
426 $ hg bookmark -m Y default
426 $ hg bookmark -m Y default
427 abort: a bookmark cannot have the name of an existing branch
427 abort: a bookmark cannot have the name of an existing branch
428 [255]
428 [255]
429
429
430 bookmark with integer name
430 bookmark with integer name
431
431
432 $ hg bookmark 10
432 $ hg bookmark 10
433 abort: cannot use an integer as a name
433 abort: cannot use an integer as a name
434 [10]
434 [10]
435
435
436 bookmark with a name that matches a node id
436 bookmark with a name that matches a node id
437 $ hg bookmark 925d80f479bb db815d6d32e6 --config "$TESTHOOK"
437 $ hg bookmark 925d80f479bb db815d6d32e6 --config "$TESTHOOK"
438 bookmark 925d80f479bb matches a changeset hash
438 bookmark 925d80f479bb matches a changeset hash
439 (did you leave a -r out of an 'hg bookmark' command?)
439 (did you leave a -r out of an 'hg bookmark' command?)
440 bookmark db815d6d32e6 matches a changeset hash
440 bookmark db815d6d32e6 matches a changeset hash
441 (did you leave a -r out of an 'hg bookmark' command?)
441 (did you leave a -r out of an 'hg bookmark' command?)
442 test-hook-bookmark: 925d80f479bb: -> db815d6d32e69058eadefc8cffbad37675707975
442 test-hook-bookmark: 925d80f479bb: -> db815d6d32e69058eadefc8cffbad37675707975
443 test-hook-bookmark: db815d6d32e6: -> db815d6d32e69058eadefc8cffbad37675707975
443 test-hook-bookmark: db815d6d32e6: -> db815d6d32e69058eadefc8cffbad37675707975
444 $ hg bookmark -d 925d80f479bb
444 $ hg bookmark -d 925d80f479bb
445 $ hg bookmark -d db815d6d32e6
445 $ hg bookmark -d db815d6d32e6
446
446
447 $ cd ..
447 $ cd ..
448
448
449 bookmark with a name that matches an ambiguous node id
449 bookmark with a name that matches an ambiguous node id
450
450
451 $ hg init ambiguous
451 $ hg init ambiguous
452 $ cd ambiguous
452 $ cd ambiguous
453 $ echo 0 > a
453 $ echo 0 > a
454 $ hg ci -qAm 0
454 $ hg ci -qAm 0
455 $ for i in 1057 2857 4025; do
455 $ for i in 1057 2857 4025; do
456 > hg up -q 0
456 > hg up -q 0
457 > echo $i > a
457 > echo $i > a
458 > hg ci -qm $i
458 > hg ci -qm $i
459 > done
459 > done
460 $ hg up -q null
460 $ hg up -q null
461 $ hg log -r0: -T '{rev}:{node}\n'
461 $ hg log -r0: -T '{rev}:{node}\n'
462 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
462 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
463 1:c56256a09cd28e5764f32e8e2810d0f01e2e357a
463 1:c56256a09cd28e5764f32e8e2810d0f01e2e357a
464 2:c5623987d205cd6d9d8389bfc40fff9dbb670b48
464 2:c5623987d205cd6d9d8389bfc40fff9dbb670b48
465 3:c562ddd9c94164376c20b86b0b4991636a3bf84f
465 3:c562ddd9c94164376c20b86b0b4991636a3bf84f
466
466
467 $ hg bookmark -r0 c562
467 $ hg bookmark -r0 c562
468 $ hg bookmarks
468 $ hg bookmarks
469 c562 0:b4e73ffab476
469 c562 0:b4e73ffab476
470
470
471 $ cd ..
471 $ cd ..
472
472
473 incompatible options
473 incompatible options
474
474
475 $ cd repo
475 $ cd repo
476
476
477 $ hg bookmark -m Y -d Z
477 $ hg bookmark -m Y -d Z
478 abort: cannot specify both --delete and --rename
478 abort: cannot specify both --delete and --rename
479 [10]
479 [10]
480
480
481 $ hg bookmark -r 1 -d Z
481 $ hg bookmark -r 1 -d Z
482 abort: cannot specify both --delete and --rev
482 abort: cannot specify both --delete and --rev
483 [10]
483 [10]
484
484
485 $ hg bookmark -r 1 -m Z Y
485 $ hg bookmark -r 1 -m Z Y
486 abort: cannot specify both --rename and --rev
486 abort: cannot specify both --rename and --rev
487 [10]
487 [10]
488
488
489 force bookmark with existing name
489 force bookmark with existing name
490
490
491 $ hg bookmark -f X2 --config "$TESTHOOK"
491 $ hg bookmark -f X2 --config "$TESTHOOK"
492 test-hook-bookmark: X2: 925d80f479bb026b0fb3deb27503780b13f74123 -> db815d6d32e69058eadefc8cffbad37675707975
492 test-hook-bookmark: X2: 925d80f479bb026b0fb3deb27503780b13f74123 -> db815d6d32e69058eadefc8cffbad37675707975
493
493
494 force bookmark back to where it was, should deactivate it
494 force bookmark back to where it was, should deactivate it
495
495
496 $ hg bookmark -fr1 X2
496 $ hg bookmark -fr1 X2
497 $ hg bookmarks
497 $ hg bookmarks
498 X2 1:925d80f479bb
498 X2 1:925d80f479bb
499 Y 2:db815d6d32e6
499 Y 2:db815d6d32e6
500 Z 0:f7b1eb17ad24
500 Z 0:f7b1eb17ad24
501 x y 2:db815d6d32e6
501 x y 2:db815d6d32e6
502
502
503 forward bookmark to descendant without --force
503 forward bookmark to descendant without --force
504
504
505 $ hg bookmark Z
505 $ hg bookmark Z
506 moving bookmark 'Z' forward from f7b1eb17ad24
506 moving bookmark 'Z' forward from f7b1eb17ad24
507
507
508 list bookmarks
508 list bookmarks
509
509
510 $ hg bookmark
510 $ hg bookmark
511 X2 1:925d80f479bb
511 X2 1:925d80f479bb
512 Y 2:db815d6d32e6
512 Y 2:db815d6d32e6
513 * Z 2:db815d6d32e6
513 * Z 2:db815d6d32e6
514 x y 2:db815d6d32e6
514 x y 2:db815d6d32e6
515 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
515 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
516 2 Y
516 2 Y
517 2 Z
517 2 Z
518 2 x y
518 2 x y
519 1 X2
519 1 X2
520
520
521 revision but no bookmark name
521 revision but no bookmark name
522
522
523 $ hg bookmark -r .
523 $ hg bookmark -r .
524 abort: bookmark name required
524 abort: bookmark name required
525 [10]
525 [10]
526
526
527 bookmark name with whitespace only
527 bookmark name with whitespace only
528
528
529 $ hg bookmark ' '
529 $ hg bookmark ' '
530 abort: bookmark names cannot consist entirely of whitespace
530 abort: bookmark names cannot consist entirely of whitespace
531 [10]
531 [10]
532
532
533 $ hg bookmark -m Y ' '
533 $ hg bookmark -m Y ' '
534 abort: bookmark names cannot consist entirely of whitespace
534 abort: bookmark names cannot consist entirely of whitespace
535 [10]
535 [10]
536
536
537 invalid bookmark
537 invalid bookmark
538
538
539 $ hg bookmark 'foo:bar'
539 $ hg bookmark 'foo:bar'
540 abort: ':' cannot be used in a name
540 abort: ':' cannot be used in a name
541 [10]
541 [10]
542
542
543 $ hg bookmark 'foo
543 $ hg bookmark 'foo
544 > bar'
544 > bar'
545 abort: '\n' cannot be used in a name
545 abort: '\n' cannot be used in a name
546 [10]
546 [10]
547
547
548 the bookmark extension should be ignored now that it is part of core
548 the bookmark extension should be ignored now that it is part of core
549
549
550 $ echo "[extensions]" >> $HGRCPATH
550 $ echo "[extensions]" >> $HGRCPATH
551 $ echo "bookmarks=" >> $HGRCPATH
551 $ echo "bookmarks=" >> $HGRCPATH
552 $ hg bookmarks
552 $ hg bookmarks
553 X2 1:925d80f479bb
553 X2 1:925d80f479bb
554 Y 2:db815d6d32e6
554 Y 2:db815d6d32e6
555 * Z 2:db815d6d32e6
555 * Z 2:db815d6d32e6
556 x y 2:db815d6d32e6
556 x y 2:db815d6d32e6
557
557
558 test summary
558 test summary
559
559
560 $ hg summary
560 $ hg summary
561 parent: 2:db815d6d32e6 tip
561 parent: 2:db815d6d32e6 tip
562 2
562 2
563 branch: default
563 branch: default
564 bookmarks: *Z Y x y
564 bookmarks: *Z Y x y
565 commit: (clean)
565 commit: (clean)
566 update: 1 new changesets, 2 branch heads (merge)
566 update: 1 new changesets, 2 branch heads (merge)
567 phases: 3 draft
567 phases: 3 draft
568
568
569 test id
569 test id
570
570
571 $ hg id
571 $ hg id
572 db815d6d32e6 tip Y/Z/x y
572 db815d6d32e6 tip Y/Z/x y
573
573
574 test rollback
574 test rollback
575
575
576 $ echo foo > f1
576 $ echo foo > f1
577 $ hg bookmark tmp-rollback
577 $ hg bookmark tmp-rollback
578 $ hg add .
578 $ hg add .
579 adding f1
579 adding f1
580 $ hg ci -mr
580 $ hg ci -mr
581 $ hg bookmarks
581 $ hg bookmarks
582 X2 1:925d80f479bb
582 X2 1:925d80f479bb
583 Y 2:db815d6d32e6
583 Y 2:db815d6d32e6
584 Z 2:db815d6d32e6
584 Z 2:db815d6d32e6
585 * tmp-rollback 3:2bf5cfec5864
585 * tmp-rollback 3:2bf5cfec5864
586 x y 2:db815d6d32e6
586 x y 2:db815d6d32e6
587 $ hg rollback
587 $ hg rollback
588 repository tip rolled back to revision 2 (undo commit)
588 repository tip rolled back to revision 2 (undo commit)
589 working directory now based on revision 2
589 working directory now based on revision 2
590 $ hg bookmarks
590 $ hg bookmarks
591 X2 1:925d80f479bb
591 X2 1:925d80f479bb
592 Y 2:db815d6d32e6
592 Y 2:db815d6d32e6
593 Z 2:db815d6d32e6
593 Z 2:db815d6d32e6
594 * tmp-rollback 2:db815d6d32e6
594 * tmp-rollback 2:db815d6d32e6
595 x y 2:db815d6d32e6
595 x y 2:db815d6d32e6
596 $ hg bookmark -f Z -r 1
596 $ hg bookmark -f Z -r 1
597 $ hg rollback
597 $ hg rollback
598 repository tip rolled back to revision 2 (undo bookmark)
598 repository tip rolled back to revision 2 (undo bookmark)
599 $ hg bookmarks
599 $ hg bookmarks
600 X2 1:925d80f479bb
600 X2 1:925d80f479bb
601 Y 2:db815d6d32e6
601 Y 2:db815d6d32e6
602 Z 2:db815d6d32e6
602 Z 2:db815d6d32e6
603 * tmp-rollback 2:db815d6d32e6
603 * tmp-rollback 2:db815d6d32e6
604 x y 2:db815d6d32e6
604 x y 2:db815d6d32e6
605 $ hg bookmark -d tmp-rollback
605 $ hg bookmark -d tmp-rollback
606
606
607 activate bookmark on working dir parent without --force
607 activate bookmark on working dir parent without --force
608
608
609 $ hg bookmark --inactive Z
609 $ hg bookmark --inactive Z
610 $ hg bookmark Z
610 $ hg bookmark Z
611
611
612 deactivate current 'Z', but also add 'Y'
612 deactivate current 'Z', but also add 'Y'
613
613
614 $ hg bookmark -d Y
614 $ hg bookmark -d Y
615 $ hg bookmark --inactive Z Y
615 $ hg bookmark --inactive Z Y
616 $ hg bookmark -l
616 $ hg bookmark -l
617 X2 1:925d80f479bb
617 X2 1:925d80f479bb
618 Y 2:db815d6d32e6
618 Y 2:db815d6d32e6
619 Z 2:db815d6d32e6
619 Z 2:db815d6d32e6
620 x y 2:db815d6d32e6
620 x y 2:db815d6d32e6
621 $ hg bookmark Z
621 $ hg bookmark Z
622
622
623 bookmark wdir to activate it (issue6218)
623 bookmark wdir to activate it (issue6218)
624
624
625 $ hg bookmark -d Z
625 $ hg bookmark -d Z
626 $ hg bookmark -r 'wdir()' Z
626 $ hg bookmark -r 'wdir()' Z
627 $ hg bookmark -l
627 $ hg bookmark -l
628 X2 1:925d80f479bb
628 X2 1:925d80f479bb
629 Y 2:db815d6d32e6
629 Y 2:db815d6d32e6
630 * Z 2:db815d6d32e6
630 * Z 2:db815d6d32e6
631 x y 2:db815d6d32e6
631 x y 2:db815d6d32e6
632
632
633 test clone
633 test clone
634
634
635 $ hg bookmark -r 2 -i @
635 $ hg bookmark -r 2 -i @
636 $ hg bookmark -r 2 -i a@
636 $ hg bookmark -r 2 -i a@
637 $ hg bookmarks
637 $ hg bookmarks
638 @ 2:db815d6d32e6
638 @ 2:db815d6d32e6
639 X2 1:925d80f479bb
639 X2 1:925d80f479bb
640 Y 2:db815d6d32e6
640 Y 2:db815d6d32e6
641 * Z 2:db815d6d32e6
641 * Z 2:db815d6d32e6
642 a@ 2:db815d6d32e6
642 a@ 2:db815d6d32e6
643 x y 2:db815d6d32e6
643 x y 2:db815d6d32e6
644 $ hg clone . cloned-bookmarks
644 $ hg clone . cloned-bookmarks
645 updating to bookmark @
645 updating to bookmark @
646 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
646 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
647 $ hg -R cloned-bookmarks bookmarks
647 $ hg -R cloned-bookmarks bookmarks
648 * @ 2:db815d6d32e6
648 * @ 2:db815d6d32e6
649 X2 1:925d80f479bb
649 X2 1:925d80f479bb
650 Y 2:db815d6d32e6
650 Y 2:db815d6d32e6
651 Z 2:db815d6d32e6
651 Z 2:db815d6d32e6
652 a@ 2:db815d6d32e6
652 a@ 2:db815d6d32e6
653 x y 2:db815d6d32e6
653 x y 2:db815d6d32e6
654
654
655 test clone with pull protocol
655 test clone with pull protocol
656
656
657 $ hg clone --pull . cloned-bookmarks-pull
657 $ hg clone --pull . cloned-bookmarks-pull
658 requesting all changes
658 requesting all changes
659 adding changesets
659 adding changesets
660 adding manifests
660 adding manifests
661 adding file changes
661 adding file changes
662 added 3 changesets with 3 changes to 3 files (+1 heads)
662 added 3 changesets with 3 changes to 3 files (+1 heads)
663 new changesets f7b1eb17ad24:db815d6d32e6
663 new changesets f7b1eb17ad24:db815d6d32e6
664 updating to bookmark @
664 updating to bookmark @
665 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
665 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
666 $ hg -R cloned-bookmarks-pull bookmarks
666 $ hg -R cloned-bookmarks-pull bookmarks
667 * @ 2:db815d6d32e6
667 * @ 2:db815d6d32e6
668 X2 1:925d80f479bb
668 X2 1:925d80f479bb
669 Y 2:db815d6d32e6
669 Y 2:db815d6d32e6
670 Z 2:db815d6d32e6
670 Z 2:db815d6d32e6
671 a@ 2:db815d6d32e6
671 a@ 2:db815d6d32e6
672 x y 2:db815d6d32e6
672 x y 2:db815d6d32e6
673
673
674 delete multiple bookmarks at once
674 delete multiple bookmarks at once
675
675
676 $ hg bookmark -d @ a@
676 $ hg bookmark -d @ a@
677
677
678 test clone with a bookmark named "default" (issue3677)
678 test clone with a bookmark named "default" (issue3677)
679
679
680 $ hg bookmark -r 1 -f -i default
680 $ hg bookmark -r 1 -f -i default
681 $ hg clone . cloned-bookmark-default
681 $ hg clone . cloned-bookmark-default
682 updating to branch default
682 updating to branch default
683 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
683 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
684 $ hg -R cloned-bookmark-default bookmarks
684 $ hg -R cloned-bookmark-default bookmarks
685 X2 1:925d80f479bb
685 X2 1:925d80f479bb
686 Y 2:db815d6d32e6
686 Y 2:db815d6d32e6
687 Z 2:db815d6d32e6
687 Z 2:db815d6d32e6
688 default 1:925d80f479bb
688 default 1:925d80f479bb
689 x y 2:db815d6d32e6
689 x y 2:db815d6d32e6
690 $ hg -R cloned-bookmark-default parents -q
690 $ hg -R cloned-bookmark-default parents -q
691 2:db815d6d32e6
691 2:db815d6d32e6
692 $ hg bookmark -d default
692 $ hg bookmark -d default
693
693
694 test clone with a specific revision
694 test clone with a specific revision
695
695
696 $ hg clone -r 925d80 . cloned-bookmarks-rev
696 $ hg clone -r 925d80 . cloned-bookmarks-rev
697 adding changesets
697 adding changesets
698 adding manifests
698 adding manifests
699 adding file changes
699 adding file changes
700 added 2 changesets with 2 changes to 2 files
700 added 2 changesets with 2 changes to 2 files
701 new changesets f7b1eb17ad24:925d80f479bb
701 new changesets f7b1eb17ad24:925d80f479bb
702 updating to branch default
702 updating to branch default
703 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
703 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
704 $ hg -R cloned-bookmarks-rev bookmarks
704 $ hg -R cloned-bookmarks-rev bookmarks
705 X2 1:925d80f479bb
705 X2 1:925d80f479bb
706
706
707 test clone with update to a bookmark
707 test clone with update to a bookmark
708
708
709 $ hg clone -u Z . ../cloned-bookmarks-update
709 $ hg clone -u Z . ../cloned-bookmarks-update
710 updating to branch default
710 updating to branch default
711 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
711 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
712 $ hg -R ../cloned-bookmarks-update bookmarks
712 $ hg -R ../cloned-bookmarks-update bookmarks
713 X2 1:925d80f479bb
713 X2 1:925d80f479bb
714 Y 2:db815d6d32e6
714 Y 2:db815d6d32e6
715 * Z 2:db815d6d32e6
715 * Z 2:db815d6d32e6
716 x y 2:db815d6d32e6
716 x y 2:db815d6d32e6
717
717
718 create bundle with two heads
718 create bundle with two heads
719
719
720 $ hg clone . tobundle
720 $ hg clone . tobundle
721 updating to branch default
721 updating to branch default
722 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
722 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
723 $ echo x > tobundle/x
723 $ echo x > tobundle/x
724 $ hg -R tobundle add tobundle/x
724 $ hg -R tobundle add tobundle/x
725 $ hg -R tobundle commit -m'x'
725 $ hg -R tobundle commit -m'x'
726 $ hg -R tobundle update -r -2
726 $ hg -R tobundle update -r -2
727 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
727 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
728 $ echo y > tobundle/y
728 $ echo y > tobundle/y
729 $ hg -R tobundle branch test
729 $ hg -R tobundle branch test
730 marked working directory as branch test
730 marked working directory as branch test
731 (branches are permanent and global, did you want a bookmark?)
731 (branches are permanent and global, did you want a bookmark?)
732 $ hg -R tobundle add tobundle/y
732 $ hg -R tobundle add tobundle/y
733 $ hg -R tobundle commit -m'y'
733 $ hg -R tobundle commit -m'y'
734 $ hg -R tobundle bundle tobundle.hg
734 $ hg -R tobundle bundle tobundle.hg
735 searching for changes
735 searching for changes
736 2 changesets found
736 2 changesets found
737 $ hg unbundle tobundle.hg
737 $ hg unbundle tobundle.hg
738 adding changesets
738 adding changesets
739 adding manifests
739 adding manifests
740 adding file changes
740 adding file changes
741 added 2 changesets with 2 changes to 2 files (+1 heads)
741 added 2 changesets with 2 changes to 2 files (+1 heads)
742 new changesets 125c9a1d6df6:9ba5f110a0b3 (2 drafts)
742 new changesets 125c9a1d6df6:9ba5f110a0b3 (2 drafts)
743 (run 'hg heads' to see heads, 'hg merge' to merge)
743 (run 'hg heads' to see heads, 'hg merge' to merge)
744
744
745 update to active bookmark if it's not the parent
745 update to active bookmark if it's not the parent
746
746
747 (it is known issue that fsmonitor can't handle nested repositories. In
747 (it is known issue that fsmonitor can't handle nested repositories. In
748 this test scenario, cloned-bookmark-default and tobundle exist in the
748 this test scenario, cloned-bookmark-default and tobundle exist in the
749 working directory of current repository)
749 working directory of current repository)
750
750
751 $ hg summary
751 $ hg summary
752 parent: 2:db815d6d32e6
752 parent: 2:db815d6d32e6
753 2
753 2
754 branch: default
754 branch: default
755 bookmarks: *Z Y x y
755 bookmarks: *Z Y x y
756 commit: 1 added, 1 unknown (new branch head) (no-fsmonitor !)
756 commit: 1 added, 1 unknown (new branch head) (no-fsmonitor !)
757 commit: 1 added, * unknown (new branch head) (glob) (fsmonitor !)
757 commit: 1 added, * unknown (new branch head) (glob) (fsmonitor !)
758 update: 2 new changesets (update)
758 update: 2 new changesets (update)
759 phases: 5 draft
759 phases: 5 draft
760 $ hg update
760 $ hg update
761 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
761 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
762 updating bookmark Z
762 updating bookmark Z
763 $ hg bookmarks
763 $ hg bookmarks
764 X2 1:925d80f479bb
764 X2 1:925d80f479bb
765 Y 2:db815d6d32e6
765 Y 2:db815d6d32e6
766 * Z 3:125c9a1d6df6
766 * Z 3:125c9a1d6df6
767 x y 2:db815d6d32e6
767 x y 2:db815d6d32e6
768
768
769 pull --update works the same as pull && update
769 pull --update works the same as pull && update
770
770
771 $ hg bookmark -r3 Y
771 $ hg bookmark -r3 Y
772 moving bookmark 'Y' forward from db815d6d32e6
772 moving bookmark 'Y' forward from db815d6d32e6
773 $ cp -R ../cloned-bookmarks-update ../cloned-bookmarks-manual-update
773 $ cp -R ../cloned-bookmarks-update ../cloned-bookmarks-manual-update
774 $ cp -R ../cloned-bookmarks-update ../cloned-bookmarks-manual-update-with-divergence
774 $ cp -R ../cloned-bookmarks-update ../cloned-bookmarks-manual-update-with-divergence
775
775
776 (manual version)
776 (manual version)
777
777
778 $ hg -R ../cloned-bookmarks-manual-update update Y
778 $ hg -R ../cloned-bookmarks-manual-update update Y
779 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
779 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
780 (activating bookmark Y)
780 (activating bookmark Y)
781 $ hg -R ../cloned-bookmarks-manual-update pull .
781 $ hg -R ../cloned-bookmarks-manual-update pull .
782 pulling from .
782 pulling from .
783 searching for changes
783 searching for changes
784 adding changesets
784 adding changesets
785 adding manifests
785 adding manifests
786 adding file changes
786 adding file changes
787 updating bookmark Y
787 updating bookmark Y
788 updating bookmark Z
788 updating bookmark Z
789 added 2 changesets with 2 changes to 2 files (+1 heads)
789 added 2 changesets with 2 changes to 2 files (+1 heads)
790 new changesets 125c9a1d6df6:9ba5f110a0b3
790 new changesets 125c9a1d6df6:9ba5f110a0b3
791 (run 'hg heads' to see heads, 'hg merge' to merge)
791 (run 'hg heads' to see heads, 'hg merge' to merge)
792
792
793 (# tests strange but with --date crashing when bookmark have to move)
793 (# tests strange but with --date crashing when bookmark have to move)
794
794
795 $ hg -R ../cloned-bookmarks-manual-update update -d 1986
795 $ hg -R ../cloned-bookmarks-manual-update update -d 1986
796 abort: revision matching date not found
796 abort: revision matching date not found
797 [10]
797 [10]
798 $ hg -R ../cloned-bookmarks-manual-update update
798 $ hg -R ../cloned-bookmarks-manual-update update
799 updating to active bookmark Y
799 updating to active bookmark Y
800 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
800 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
801
801
802 (all in one version)
802 (all in one version)
803
803
804 $ hg -R ../cloned-bookmarks-update update Y
804 $ hg -R ../cloned-bookmarks-update update Y
805 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
805 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
806 (activating bookmark Y)
806 (activating bookmark Y)
807 $ hg -R ../cloned-bookmarks-update pull --update .
807 $ hg -R ../cloned-bookmarks-update pull --update .
808 pulling from .
808 pulling from .
809 searching for changes
809 searching for changes
810 adding changesets
810 adding changesets
811 adding manifests
811 adding manifests
812 adding file changes
812 adding file changes
813 updating bookmark Y
813 updating bookmark Y
814 updating bookmark Z
814 updating bookmark Z
815 added 2 changesets with 2 changes to 2 files (+1 heads)
815 added 2 changesets with 2 changes to 2 files (+1 heads)
816 new changesets 125c9a1d6df6:9ba5f110a0b3
816 new changesets 125c9a1d6df6:9ba5f110a0b3
817 updating to active bookmark Y
817 updating to active bookmark Y
818 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
818 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
819
819
820 We warn about divergent during bare update to the active bookmark
820 We warn about divergent during bare update to the active bookmark
821
821
822 $ hg -R ../cloned-bookmarks-manual-update-with-divergence update Y
822 $ hg -R ../cloned-bookmarks-manual-update-with-divergence update Y
823 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
823 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
824 (activating bookmark Y)
824 (activating bookmark Y)
825 $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks -r X2 Y@1
825 $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks -r X2 Y@1
826 $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks
826 $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks
827 X2 1:925d80f479bb
827 X2 1:925d80f479bb
828 * Y 2:db815d6d32e6
828 * Y 2:db815d6d32e6
829 Y@1 1:925d80f479bb
829 Y@1 1:925d80f479bb
830 Z 2:db815d6d32e6
830 Z 2:db815d6d32e6
831 x y 2:db815d6d32e6
831 x y 2:db815d6d32e6
832 $ hg -R ../cloned-bookmarks-manual-update-with-divergence pull
832 $ hg -R ../cloned-bookmarks-manual-update-with-divergence pull
833 pulling from $TESTTMP/repo
833 pulling from $TESTTMP/repo
834 searching for changes
834 searching for changes
835 adding changesets
835 adding changesets
836 adding manifests
836 adding manifests
837 adding file changes
837 adding file changes
838 updating bookmark Y
838 updating bookmark Y
839 updating bookmark Z
839 updating bookmark Z
840 added 2 changesets with 2 changes to 2 files (+1 heads)
840 added 2 changesets with 2 changes to 2 files (+1 heads)
841 new changesets 125c9a1d6df6:9ba5f110a0b3
841 new changesets 125c9a1d6df6:9ba5f110a0b3
842 (run 'hg heads' to see heads, 'hg merge' to merge)
842 (run 'hg heads' to see heads, 'hg merge' to merge)
843 $ hg -R ../cloned-bookmarks-manual-update-with-divergence update
843 $ hg -R ../cloned-bookmarks-manual-update-with-divergence update
844 updating to active bookmark Y
844 updating to active bookmark Y
845 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
845 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
846 1 other divergent bookmarks for "Y"
846 1 other divergent bookmarks for "Y"
847
847
848 test wrongly formated bookmark
848 test wrongly formated bookmark
849
849
850 $ echo '' >> .hg/bookmarks
850 $ echo '' >> .hg/bookmarks
851 $ hg bookmarks
851 $ hg bookmarks
852 X2 1:925d80f479bb
852 X2 1:925d80f479bb
853 Y 3:125c9a1d6df6
853 Y 3:125c9a1d6df6
854 * Z 3:125c9a1d6df6
854 * Z 3:125c9a1d6df6
855 x y 2:db815d6d32e6
855 x y 2:db815d6d32e6
856 $ echo "Ican'thasformatedlines" >> .hg/bookmarks
856 $ echo "Ican'thasformatedlines" >> .hg/bookmarks
857 $ hg bookmarks
857 $ hg bookmarks
858 malformed line in .hg/bookmarks: "Ican'thasformatedlines"
858 malformed line in .hg/bookmarks: "Ican'thasformatedlines"
859 X2 1:925d80f479bb
859 X2 1:925d80f479bb
860 Y 3:125c9a1d6df6
860 Y 3:125c9a1d6df6
861 * Z 3:125c9a1d6df6
861 * Z 3:125c9a1d6df6
862 x y 2:db815d6d32e6
862 x y 2:db815d6d32e6
863
863
864 test missing revisions
864 test missing revisions
865
865
866 $ echo "925d80f479b925d80f479bc925d80f479bccabab z" > .hg/bookmarks
866 $ echo "925d80f479b925d80f479bc925d80f479bccabab z" > .hg/bookmarks
867 $ hg book
867 $ hg book
868 no bookmarks set
868 no bookmarks set
869
869
870 test stripping a non-checked-out but bookmarked revision
870 test stripping a non-checked-out but bookmarked revision
871
871
872 $ hg log --graph
872 $ hg log --graph
873 o changeset: 4:9ba5f110a0b3
873 o changeset: 4:9ba5f110a0b3
874 | branch: test
874 | branch: test
875 | tag: tip
875 | tag: tip
876 | parent: 2:db815d6d32e6
876 | parent: 2:db815d6d32e6
877 | user: test
877 | user: test
878 | date: Thu Jan 01 00:00:00 1970 +0000
878 | date: Thu Jan 01 00:00:00 1970 +0000
879 | summary: y
879 | summary: y
880 |
880 |
881 | @ changeset: 3:125c9a1d6df6
881 | @ changeset: 3:125c9a1d6df6
882 |/ user: test
882 |/ user: test
883 | date: Thu Jan 01 00:00:00 1970 +0000
883 | date: Thu Jan 01 00:00:00 1970 +0000
884 | summary: x
884 | summary: x
885 |
885 |
886 o changeset: 2:db815d6d32e6
886 o changeset: 2:db815d6d32e6
887 | parent: 0:f7b1eb17ad24
887 | parent: 0:f7b1eb17ad24
888 | user: test
888 | user: test
889 | date: Thu Jan 01 00:00:00 1970 +0000
889 | date: Thu Jan 01 00:00:00 1970 +0000
890 | summary: 2
890 | summary: 2
891 |
891 |
892 | o changeset: 1:925d80f479bb
892 | o changeset: 1:925d80f479bb
893 |/ user: test
893 |/ user: test
894 | date: Thu Jan 01 00:00:00 1970 +0000
894 | date: Thu Jan 01 00:00:00 1970 +0000
895 | summary: 1
895 | summary: 1
896 |
896 |
897 o changeset: 0:f7b1eb17ad24
897 o changeset: 0:f7b1eb17ad24
898 user: test
898 user: test
899 date: Thu Jan 01 00:00:00 1970 +0000
899 date: Thu Jan 01 00:00:00 1970 +0000
900 summary: 0
900 summary: 0
901
901
902 $ hg book should-end-on-two
902 $ hg book should-end-on-two
903 $ hg co --clean 4
903 $ hg co --clean 4
904 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
904 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
905 (leaving bookmark should-end-on-two)
905 (leaving bookmark should-end-on-two)
906 $ hg book four
906 $ hg book four
907 $ hg --config extensions.mq= strip 3
907 $ hg --config extensions.mq= strip 3
908 saved backup bundle to * (glob)
908 saved backup bundle to * (glob)
909 should-end-on-two should end up pointing to revision 2, as that's the
909 should-end-on-two should end up pointing to revision 2, as that's the
910 tipmost surviving ancestor of the stripped revision.
910 tipmost surviving ancestor of the stripped revision.
911 $ hg log --graph
911 $ hg log --graph
912 @ changeset: 3:9ba5f110a0b3
912 @ changeset: 3:9ba5f110a0b3
913 | branch: test
913 | branch: test
914 | bookmark: four
914 | bookmark: four
915 | tag: tip
915 | tag: tip
916 | user: test
916 | user: test
917 | date: Thu Jan 01 00:00:00 1970 +0000
917 | date: Thu Jan 01 00:00:00 1970 +0000
918 | summary: y
918 | summary: y
919 |
919 |
920 o changeset: 2:db815d6d32e6
920 o changeset: 2:db815d6d32e6
921 | bookmark: should-end-on-two
921 | bookmark: should-end-on-two
922 | parent: 0:f7b1eb17ad24
922 | parent: 0:f7b1eb17ad24
923 | user: test
923 | user: test
924 | date: Thu Jan 01 00:00:00 1970 +0000
924 | date: Thu Jan 01 00:00:00 1970 +0000
925 | summary: 2
925 | summary: 2
926 |
926 |
927 | o changeset: 1:925d80f479bb
927 | o changeset: 1:925d80f479bb
928 |/ user: test
928 |/ user: test
929 | date: Thu Jan 01 00:00:00 1970 +0000
929 | date: Thu Jan 01 00:00:00 1970 +0000
930 | summary: 1
930 | summary: 1
931 |
931 |
932 o changeset: 0:f7b1eb17ad24
932 o changeset: 0:f7b1eb17ad24
933 user: test
933 user: test
934 date: Thu Jan 01 00:00:00 1970 +0000
934 date: Thu Jan 01 00:00:00 1970 +0000
935 summary: 0
935 summary: 0
936
936
937
937
938 no-op update doesn't deactivate bookmarks
938 no-op update doesn't deactivate bookmarks
939
939
940 (it is known issue that fsmonitor can't handle nested repositories. In
940 (it is known issue that fsmonitor can't handle nested repositories. In
941 this test scenario, cloned-bookmark-default and tobundle exist in the
941 this test scenario, cloned-bookmark-default and tobundle exist in the
942 working directory of current repository)
942 working directory of current repository)
943
943
944 $ hg bookmarks
944 $ hg bookmarks
945 * four 3:9ba5f110a0b3
945 * four 3:9ba5f110a0b3
946 should-end-on-two 2:db815d6d32e6
946 should-end-on-two 2:db815d6d32e6
947 $ hg up four
947 $ hg up four
948 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
948 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
949 $ hg up
949 $ hg up
950 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
950 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
951 $ hg sum
951 $ hg sum
952 parent: 3:9ba5f110a0b3 tip
952 parent: 3:9ba5f110a0b3 tip
953 y
953 y
954 branch: test
954 branch: test
955 bookmarks: *four
955 bookmarks: *four
956 commit: 2 unknown (clean) (no-fsmonitor !)
956 commit: 2 unknown (clean) (no-fsmonitor !)
957 commit: * unknown (clean) (glob) (fsmonitor !)
957 commit: * unknown (clean) (glob) (fsmonitor !)
958 update: (current)
958 update: (current)
959 phases: 4 draft
959 phases: 4 draft
960
960
961 test clearing divergent bookmarks of linear ancestors
961 test clearing divergent bookmarks of linear ancestors
962
962
963 $ hg bookmark Z -r 0
963 $ hg bookmark Z -r 0
964 $ hg bookmark Z@1 -r 1
964 $ hg bookmark Z@1 -r 1
965 $ hg bookmark Z@2 -r 2
965 $ hg bookmark Z@2 -r 2
966 $ hg bookmark Z@3 -r 3
966 $ hg bookmark Z@3 -r 3
967 $ hg book
967 $ hg book
968 Z 0:f7b1eb17ad24
968 Z 0:f7b1eb17ad24
969 Z@1 1:925d80f479bb
969 Z@1 1:925d80f479bb
970 Z@2 2:db815d6d32e6
970 Z@2 2:db815d6d32e6
971 Z@3 3:9ba5f110a0b3
971 Z@3 3:9ba5f110a0b3
972 * four 3:9ba5f110a0b3
972 * four 3:9ba5f110a0b3
973 should-end-on-two 2:db815d6d32e6
973 should-end-on-two 2:db815d6d32e6
974 $ hg bookmark Z
974 $ hg bookmark Z
975 moving bookmark 'Z' forward from f7b1eb17ad24
975 moving bookmark 'Z' forward from f7b1eb17ad24
976 $ hg book
976 $ hg book
977 * Z 3:9ba5f110a0b3
977 * Z 3:9ba5f110a0b3
978 Z@1 1:925d80f479bb
978 Z@1 1:925d80f479bb
979 four 3:9ba5f110a0b3
979 four 3:9ba5f110a0b3
980 should-end-on-two 2:db815d6d32e6
980 should-end-on-two 2:db815d6d32e6
981
981
982 test clearing only a single divergent bookmark across branches
982 test clearing only a single divergent bookmark across branches
983
983
984 $ hg book foo -r 1
984 $ hg book foo -r 1
985 $ hg book foo@1 -r 0
985 $ hg book foo@1 -r 0
986 $ hg book foo@2 -r 2
986 $ hg book foo@2 -r 2
987 $ hg book foo@3 -r 3
987 $ hg book foo@3 -r 3
988 $ hg book foo -r foo@3
988 $ hg book foo -r foo@3
989 $ hg book
989 $ hg book
990 * Z 3:9ba5f110a0b3
990 * Z 3:9ba5f110a0b3
991 Z@1 1:925d80f479bb
991 Z@1 1:925d80f479bb
992 foo 3:9ba5f110a0b3
992 foo 3:9ba5f110a0b3
993 foo@1 0:f7b1eb17ad24
993 foo@1 0:f7b1eb17ad24
994 foo@2 2:db815d6d32e6
994 foo@2 2:db815d6d32e6
995 four 3:9ba5f110a0b3
995 four 3:9ba5f110a0b3
996 should-end-on-two 2:db815d6d32e6
996 should-end-on-two 2:db815d6d32e6
997
997
998 pull --update works the same as pull && update (case #2)
998 pull --update works the same as pull && update (case #2)
999
999
1000 It is assumed that "hg pull" itself doesn't update current active
1000 It is assumed that "hg pull" itself doesn't update current active
1001 bookmark ('Y' in tests below).
1001 bookmark ('Y' in tests below).
1002
1002
1003 $ hg pull -q ../cloned-bookmarks-update
1003 $ hg pull -q ../cloned-bookmarks-update
1004 divergent bookmark Z stored as Z@2
1004 divergent bookmark Z stored as Z@2
1005
1005
1006 (pulling revision on another named branch with --update updates
1006 (pulling revision on another named branch with --update updates
1007 neither the working directory nor current active bookmark: "no-op"
1007 neither the working directory nor current active bookmark: "no-op"
1008 case)
1008 case)
1009
1009
1010 $ echo yy >> y
1010 $ echo yy >> y
1011 $ hg commit -m yy
1011 $ hg commit -m yy
1012
1012
1013 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1013 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1014 * Y 3:125c9a1d6df6
1014 * Y 3:125c9a1d6df6
1015 $ hg -R ../cloned-bookmarks-update path
1015 $ hg -R ../cloned-bookmarks-update path
1016 default = $TESTTMP/repo
1016 default = $TESTTMP/repo
1017 $ pwd
1017 $ pwd
1018 $TESTTMP/repo
1018 $TESTTMP/repo
1019 $ hg -R ../cloned-bookmarks-update pull . --update
1019 $ hg -R ../cloned-bookmarks-update pull . --update
1020 pulling from .
1020 pulling from .
1021 searching for changes
1021 searching for changes
1022 adding changesets
1022 adding changesets
1023 adding manifests
1023 adding manifests
1024 adding file changes
1024 adding file changes
1025 divergent bookmark Z stored as Z@default
1025 divergent bookmark Z stored as Z@default
1026 adding remote bookmark foo
1026 adding remote bookmark foo
1027 adding remote bookmark four
1027 adding remote bookmark four
1028 adding remote bookmark should-end-on-two
1028 adding remote bookmark should-end-on-two
1029 added 1 changesets with 1 changes to 1 files
1029 added 1 changesets with 1 changes to 1 files
1030 new changesets 5fb12f0f2d51
1030 new changesets 5fb12f0f2d51
1031 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1031 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1032 $ hg -R ../cloned-bookmarks-update parents -T "{rev}:{node|short}\n"
1032 $ hg -R ../cloned-bookmarks-update parents -T "{rev}:{node|short}\n"
1033 3:125c9a1d6df6
1033 3:125c9a1d6df6
1034 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1034 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1035 * Y 3:125c9a1d6df6
1035 * Y 3:125c9a1d6df6
1036
1036
1037 (pulling revision on current named/topological branch with --update
1037 (pulling revision on current named/topological branch with --update
1038 updates the working directory and current active bookmark)
1038 updates the working directory and current active bookmark)
1039
1039
1040 $ hg update -C -q 125c9a1d6df6
1040 $ hg update -C -q 125c9a1d6df6
1041 $ echo xx >> x
1041 $ echo xx >> x
1042 $ hg commit -m xx
1042 $ hg commit -m xx
1043
1043
1044 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1044 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1045 * Y 3:125c9a1d6df6
1045 * Y 3:125c9a1d6df6
1046 $ hg -R ../cloned-bookmarks-update pull . --update
1046 $ hg -R ../cloned-bookmarks-update pull . --update
1047 pulling from .
1047 pulling from .
1048 searching for changes
1048 searching for changes
1049 adding changesets
1049 adding changesets
1050 adding manifests
1050 adding manifests
1051 adding file changes
1051 adding file changes
1052 divergent bookmark Z stored as Z@default
1052 divergent bookmark Z stored as Z@default
1053 added 1 changesets with 1 changes to 1 files
1053 added 1 changesets with 1 changes to 1 files
1054 new changesets 81dcce76aa0b
1054 new changesets 81dcce76aa0b
1055 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1055 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1056 updating bookmark Y
1056 updating bookmark Y
1057 $ hg -R ../cloned-bookmarks-update parents -T "{rev}:{node|short}\n"
1057 $ hg -R ../cloned-bookmarks-update parents -T "{rev}:{node|short}\n"
1058 6:81dcce76aa0b
1058 6:81dcce76aa0b
1059 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1059 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1060 * Y 6:81dcce76aa0b
1060 * Y 6:81dcce76aa0b
1061
1061
1062 $ cd ..
1062 $ cd ..
1063
1063
1064 ensure changelog is written before bookmarks
1064 ensure changelog is written before bookmarks
1065 $ hg init orderrepo
1065 $ hg init orderrepo
1066 $ cd orderrepo
1066 $ cd orderrepo
1067 $ touch a
1067 $ touch a
1068 $ hg commit -Aqm one
1068 $ hg commit -Aqm one
1069 $ hg book mybook
1069 $ hg book mybook
1070 $ echo a > a
1070 $ echo a > a
1071
1071
1072 $ cat > $TESTTMP/pausefinalize.py <<EOF
1072 $ cat > $TESTTMP/pausefinalize.py <<EOF
1073 > import os
1073 > import os
1074 > import time
1074 > import time
1075 > from mercurial import extensions, localrepo
1075 > from mercurial import extensions, localrepo
1076 > def transaction(orig, self, desc, report=None):
1076 > def transaction(orig, self, desc, report=None):
1077 > tr = orig(self, desc, report)
1077 > tr = orig(self, desc, report)
1078 > def sleep(*args, **kwargs):
1078 > def sleep(*args, **kwargs):
1079 > retry = 20
1079 > retry = 20
1080 > while retry > 0 and not os.path.exists(b"$TESTTMP/unpause"):
1080 > while retry > 0 and not os.path.exists(b"$TESTTMP/unpause"):
1081 > retry -= 1
1081 > retry -= 1
1082 > time.sleep(0.5)
1082 > time.sleep(0.5)
1083 > if os.path.exists(b"$TESTTMP/unpause"):
1083 > if os.path.exists(b"$TESTTMP/unpause"):
1084 > os.remove(b"$TESTTMP/unpause")
1084 > os.remove(b"$TESTTMP/unpause")
1085 > # It is important that this finalizer start with 'a', so it runs before
1085 > # It is important that this finalizer start with 'a', so it runs before
1086 > # the changelog finalizer appends to the changelog.
1086 > # the changelog finalizer appends to the changelog.
1087 > tr.addfinalize(b'a-sleep', sleep)
1087 > tr.addfinalize(b'a-sleep', sleep)
1088 > return tr
1088 > return tr
1089 >
1089 >
1090 > def extsetup(ui):
1090 > def extsetup(ui):
1091 > # This extension inserts an artifical pause during the transaction
1091 > # This extension inserts an artifical pause during the transaction
1092 > # finalizer, so we can run commands mid-transaction-close.
1092 > # finalizer, so we can run commands mid-transaction-close.
1093 > extensions.wrapfunction(localrepo.localrepository, 'transaction',
1093 > extensions.wrapfunction(localrepo.localrepository, 'transaction',
1094 > transaction)
1094 > transaction)
1095 > EOF
1095 > EOF
1096 $ hg commit -qm two --config extensions.pausefinalize=$TESTTMP/pausefinalize.py &
1096 $ hg commit -qm two --config extensions.pausefinalize=$TESTTMP/pausefinalize.py &
1097 $ sleep 2
1097 $ sleep 2
1098 $ hg log -r .
1098 $ hg log -r .
1099 changeset: 0:867bc5792c8c
1099 changeset: 0:867bc5792c8c
1100 bookmark: mybook
1100 bookmark: mybook
1101 tag: tip
1101 tag: tip
1102 user: test
1102 user: test
1103 date: Thu Jan 01 00:00:00 1970 +0000
1103 date: Thu Jan 01 00:00:00 1970 +0000
1104 summary: one
1104 summary: one
1105
1105
1106 $ hg bookmarks
1106 $ hg bookmarks
1107 * mybook 0:867bc5792c8c
1107 * mybook 0:867bc5792c8c
1108 $ touch $TESTTMP/unpause
1108 $ touch $TESTTMP/unpause
1109
1109
1110 $ cd ..
1110 $ cd ..
1111
1111
1112 check whether HG_PENDING makes pending changes only in related
1112 check whether HG_PENDING makes pending changes only in related
1113 repositories visible to an external hook.
1113 repositories visible to an external hook.
1114
1114
1115 (emulate a transaction running concurrently by copied
1115 (emulate a transaction running concurrently by copied
1116 .hg/bookmarks.pending in subsequent test)
1116 .hg/bookmarks.pending in subsequent test)
1117
1117
1118 $ cat > $TESTTMP/savepending.sh <<EOF
1118 $ cat > $TESTTMP/savepending.sh <<EOF
1119 > cp .hg/bookmarks.pending .hg/bookmarks.pending.saved
1119 > cp .hg/bookmarks.pending .hg/bookmarks.pending.saved
1120 > exit 1 # to avoid adding new bookmark for subsequent tests
1120 > exit 1 # to avoid adding new bookmark for subsequent tests
1121 > EOF
1121 > EOF
1122
1122
1123 $ hg init unrelated
1123 $ hg init unrelated
1124 $ cd unrelated
1124 $ cd unrelated
1125 $ echo a > a
1125 $ echo a > a
1126 $ hg add a
1126 $ hg add a
1127 $ hg commit -m '#0'
1127 $ hg commit -m '#0'
1128 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" bookmarks INVISIBLE
1128 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" bookmarks INVISIBLE
1129 transaction abort!
1130 rollback completed
1131 abort: pretxnclose hook exited with status 1
1129 abort: pretxnclose hook exited with status 1
1132 [40]
1130 [40]
1133 $ cp .hg/bookmarks.pending.saved .hg/bookmarks.pending
1131 $ cp .hg/bookmarks.pending.saved .hg/bookmarks.pending
1134
1132
1135 (check visible bookmarks while transaction running in repo)
1133 (check visible bookmarks while transaction running in repo)
1136
1134
1137 $ cat > $TESTTMP/checkpending.sh <<EOF
1135 $ cat > $TESTTMP/checkpending.sh <<EOF
1138 > echo "@repo"
1136 > echo "@repo"
1139 > hg -R "$TESTTMP/repo" bookmarks
1137 > hg -R "$TESTTMP/repo" bookmarks
1140 > echo "@unrelated"
1138 > echo "@unrelated"
1141 > hg -R "$TESTTMP/unrelated" bookmarks
1139 > hg -R "$TESTTMP/unrelated" bookmarks
1142 > exit 1 # to avoid adding new bookmark for subsequent tests
1140 > exit 1 # to avoid adding new bookmark for subsequent tests
1143 > EOF
1141 > EOF
1144
1142
1145 $ cd ../repo
1143 $ cd ../repo
1146 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" bookmarks NEW
1144 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" bookmarks NEW
1147 @repo
1145 @repo
1148 * NEW 6:81dcce76aa0b
1146 * NEW 6:81dcce76aa0b
1149 X2 1:925d80f479bb
1147 X2 1:925d80f479bb
1150 Y 4:125c9a1d6df6
1148 Y 4:125c9a1d6df6
1151 Z 5:5fb12f0f2d51
1149 Z 5:5fb12f0f2d51
1152 Z@1 1:925d80f479bb
1150 Z@1 1:925d80f479bb
1153 Z@2 4:125c9a1d6df6
1151 Z@2 4:125c9a1d6df6
1154 foo 3:9ba5f110a0b3
1152 foo 3:9ba5f110a0b3
1155 foo@1 0:f7b1eb17ad24
1153 foo@1 0:f7b1eb17ad24
1156 foo@2 2:db815d6d32e6
1154 foo@2 2:db815d6d32e6
1157 four 3:9ba5f110a0b3
1155 four 3:9ba5f110a0b3
1158 should-end-on-two 2:db815d6d32e6
1156 should-end-on-two 2:db815d6d32e6
1159 x y 2:db815d6d32e6
1157 x y 2:db815d6d32e6
1160 @unrelated
1158 @unrelated
1161 no bookmarks set
1159 no bookmarks set
1162 transaction abort!
1163 rollback completed
1164 abort: pretxnclose hook exited with status 1
1160 abort: pretxnclose hook exited with status 1
1165 [40]
1161 [40]
1166
1162
1167 Check pretxnclose-bookmark can abort a transaction
1163 Check pretxnclose-bookmark can abort a transaction
1168 --------------------------------------------------
1164 --------------------------------------------------
1169
1165
1170 add hooks:
1166 add hooks:
1171
1167
1172 * to prevent NEW bookmark on a non-public changeset
1168 * to prevent NEW bookmark on a non-public changeset
1173 * to prevent non-forward move of NEW bookmark
1169 * to prevent non-forward move of NEW bookmark
1174
1170
1175 $ cat << EOF >> .hg/hgrc
1171 $ cat << EOF >> .hg/hgrc
1176 > [hooks]
1172 > [hooks]
1177 > pretxnclose-bookmark.force-public = sh -c "(echo \$HG_BOOKMARK| grep -v NEW > /dev/null) || [ -z \"\$HG_NODE\" ] || (hg log -r \"\$HG_NODE\" -T '{phase}' | grep public > /dev/null)"
1173 > pretxnclose-bookmark.force-public = sh -c "(echo \$HG_BOOKMARK| grep -v NEW > /dev/null) || [ -z \"\$HG_NODE\" ] || (hg log -r \"\$HG_NODE\" -T '{phase}' | grep public > /dev/null)"
1178 > pretxnclose-bookmark.force-forward = sh -c "(echo \$HG_BOOKMARK| grep -v NEW > /dev/null) || [ -z \"\$HG_NODE\" ] || (hg log -r \"max(\$HG_OLDNODE::\$HG_NODE)\" -T 'MATCH' | grep MATCH > /dev/null)"
1174 > pretxnclose-bookmark.force-forward = sh -c "(echo \$HG_BOOKMARK| grep -v NEW > /dev/null) || [ -z \"\$HG_NODE\" ] || (hg log -r \"max(\$HG_OLDNODE::\$HG_NODE)\" -T 'MATCH' | grep MATCH > /dev/null)"
1179 > EOF
1175 > EOF
1180
1176
1181 $ hg log -G -T phases
1177 $ hg log -G -T phases
1182 @ changeset: 6:81dcce76aa0b
1178 @ changeset: 6:81dcce76aa0b
1183 | tag: tip
1179 | tag: tip
1184 | phase: draft
1180 | phase: draft
1185 | parent: 4:125c9a1d6df6
1181 | parent: 4:125c9a1d6df6
1186 | user: test
1182 | user: test
1187 | date: Thu Jan 01 00:00:00 1970 +0000
1183 | date: Thu Jan 01 00:00:00 1970 +0000
1188 | summary: xx
1184 | summary: xx
1189 |
1185 |
1190 | o changeset: 5:5fb12f0f2d51
1186 | o changeset: 5:5fb12f0f2d51
1191 | | branch: test
1187 | | branch: test
1192 | | bookmark: Z
1188 | | bookmark: Z
1193 | | phase: draft
1189 | | phase: draft
1194 | | parent: 3:9ba5f110a0b3
1190 | | parent: 3:9ba5f110a0b3
1195 | | user: test
1191 | | user: test
1196 | | date: Thu Jan 01 00:00:00 1970 +0000
1192 | | date: Thu Jan 01 00:00:00 1970 +0000
1197 | | summary: yy
1193 | | summary: yy
1198 | |
1194 | |
1199 o | changeset: 4:125c9a1d6df6
1195 o | changeset: 4:125c9a1d6df6
1200 | | bookmark: Y
1196 | | bookmark: Y
1201 | | bookmark: Z@2
1197 | | bookmark: Z@2
1202 | | phase: public
1198 | | phase: public
1203 | | parent: 2:db815d6d32e6
1199 | | parent: 2:db815d6d32e6
1204 | | user: test
1200 | | user: test
1205 | | date: Thu Jan 01 00:00:00 1970 +0000
1201 | | date: Thu Jan 01 00:00:00 1970 +0000
1206 | | summary: x
1202 | | summary: x
1207 | |
1203 | |
1208 | o changeset: 3:9ba5f110a0b3
1204 | o changeset: 3:9ba5f110a0b3
1209 |/ branch: test
1205 |/ branch: test
1210 | bookmark: foo
1206 | bookmark: foo
1211 | bookmark: four
1207 | bookmark: four
1212 | phase: public
1208 | phase: public
1213 | user: test
1209 | user: test
1214 | date: Thu Jan 01 00:00:00 1970 +0000
1210 | date: Thu Jan 01 00:00:00 1970 +0000
1215 | summary: y
1211 | summary: y
1216 |
1212 |
1217 o changeset: 2:db815d6d32e6
1213 o changeset: 2:db815d6d32e6
1218 | bookmark: foo@2
1214 | bookmark: foo@2
1219 | bookmark: should-end-on-two
1215 | bookmark: should-end-on-two
1220 | bookmark: x y
1216 | bookmark: x y
1221 | phase: public
1217 | phase: public
1222 | parent: 0:f7b1eb17ad24
1218 | parent: 0:f7b1eb17ad24
1223 | user: test
1219 | user: test
1224 | date: Thu Jan 01 00:00:00 1970 +0000
1220 | date: Thu Jan 01 00:00:00 1970 +0000
1225 | summary: 2
1221 | summary: 2
1226 |
1222 |
1227 | o changeset: 1:925d80f479bb
1223 | o changeset: 1:925d80f479bb
1228 |/ bookmark: X2
1224 |/ bookmark: X2
1229 | bookmark: Z@1
1225 | bookmark: Z@1
1230 | phase: public
1226 | phase: public
1231 | user: test
1227 | user: test
1232 | date: Thu Jan 01 00:00:00 1970 +0000
1228 | date: Thu Jan 01 00:00:00 1970 +0000
1233 | summary: 1
1229 | summary: 1
1234 |
1230 |
1235 o changeset: 0:f7b1eb17ad24
1231 o changeset: 0:f7b1eb17ad24
1236 bookmark: foo@1
1232 bookmark: foo@1
1237 phase: public
1233 phase: public
1238 user: test
1234 user: test
1239 date: Thu Jan 01 00:00:00 1970 +0000
1235 date: Thu Jan 01 00:00:00 1970 +0000
1240 summary: 0
1236 summary: 0
1241
1237
1242
1238
1243 attempt to create on a default changeset
1239 attempt to create on a default changeset
1244
1240
1245 $ hg bookmark -r 81dcce76aa0b NEW
1241 $ hg bookmark -r 81dcce76aa0b NEW
1246 transaction abort!
1247 rollback completed
1248 abort: pretxnclose-bookmark.force-public hook exited with status 1
1242 abort: pretxnclose-bookmark.force-public hook exited with status 1
1249 [40]
1243 [40]
1250
1244
1251 create on a public changeset
1245 create on a public changeset
1252
1246
1253 $ hg bookmark -r 9ba5f110a0b3 NEW
1247 $ hg bookmark -r 9ba5f110a0b3 NEW
1254
1248
1255 move to the other branch
1249 move to the other branch
1256
1250
1257 $ hg bookmark -f -r 125c9a1d6df6 NEW
1251 $ hg bookmark -f -r 125c9a1d6df6 NEW
1258 transaction abort!
1259 rollback completed
1260 abort: pretxnclose-bookmark.force-forward hook exited with status 1
1252 abort: pretxnclose-bookmark.force-forward hook exited with status 1
1261 [40]
1253 [40]
@@ -1,1141 +1,1131 b''
1 $ cat > $TESTTMP/hook.sh << 'EOF'
1 $ cat > $TESTTMP/hook.sh << 'EOF'
2 > echo "test-hook-close-phase: $HG_NODE: $HG_OLDPHASE -> $HG_PHASE"
2 > echo "test-hook-close-phase: $HG_NODE: $HG_OLDPHASE -> $HG_PHASE"
3 > EOF
3 > EOF
4
4
5 $ cat >> $HGRCPATH << EOF
5 $ cat >> $HGRCPATH << EOF
6 > [extensions]
6 > [extensions]
7 > phasereport=$TESTDIR/testlib/ext-phase-report.py
7 > phasereport=$TESTDIR/testlib/ext-phase-report.py
8 > [hooks]
8 > [hooks]
9 > txnclose-phase.test = sh $TESTTMP/hook.sh
9 > txnclose-phase.test = sh $TESTTMP/hook.sh
10 > EOF
10 > EOF
11
11
12 $ hglog() { hg log -G --template "{rev} {phaseidx} {desc}\n" $*; }
12 $ hglog() { hg log -G --template "{rev} {phaseidx} {desc}\n" $*; }
13 $ mkcommit() {
13 $ mkcommit() {
14 > echo "$1" > "$1"
14 > echo "$1" > "$1"
15 > hg add "$1"
15 > hg add "$1"
16 > message="$1"
16 > message="$1"
17 > shift
17 > shift
18 > hg ci -m "$message" $*
18 > hg ci -m "$message" $*
19 > }
19 > }
20
20
21 $ hg init initialrepo
21 $ hg init initialrepo
22 $ cd initialrepo
22 $ cd initialrepo
23
23
24 Cannot change null revision phase
24 Cannot change null revision phase
25
25
26 $ hg phase --force --secret null
26 $ hg phase --force --secret null
27 abort: cannot change null revision phase
27 abort: cannot change null revision phase
28 [255]
28 [255]
29 $ hg phase null
29 $ hg phase null
30 -1: public
30 -1: public
31
31
32 $ mkcommit A
32 $ mkcommit A
33 test-debug-phase: new rev 0: x -> 1
33 test-debug-phase: new rev 0: x -> 1
34 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> draft
34 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> draft
35
35
36 New commit are draft by default
36 New commit are draft by default
37
37
38 $ hglog
38 $ hglog
39 @ 0 1 A
39 @ 0 1 A
40
40
41
41
42 Following commit are draft too
42 Following commit are draft too
43
43
44 $ mkcommit B
44 $ mkcommit B
45 test-debug-phase: new rev 1: x -> 1
45 test-debug-phase: new rev 1: x -> 1
46 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> draft
46 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> draft
47
47
48 $ hglog
48 $ hglog
49 @ 1 1 B
49 @ 1 1 B
50 |
50 |
51 o 0 1 A
51 o 0 1 A
52
52
53
53
54 Working directory phase is secret when its parent is secret.
54 Working directory phase is secret when its parent is secret.
55
55
56 $ hg phase --force --secret .
56 $ hg phase --force --secret .
57 test-debug-phase: move rev 0: 1 -> 2
57 test-debug-phase: move rev 0: 1 -> 2
58 test-debug-phase: move rev 1: 1 -> 2
58 test-debug-phase: move rev 1: 1 -> 2
59 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: draft -> secret
59 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: draft -> secret
60 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: draft -> secret
60 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: draft -> secret
61 $ hg log -r 'wdir()' -T '{phase}\n'
61 $ hg log -r 'wdir()' -T '{phase}\n'
62 secret
62 secret
63 $ hg log -r 'wdir() and public()' -T '{phase}\n'
63 $ hg log -r 'wdir() and public()' -T '{phase}\n'
64 $ hg log -r 'wdir() and draft()' -T '{phase}\n'
64 $ hg log -r 'wdir() and draft()' -T '{phase}\n'
65 $ hg log -r 'wdir() and secret()' -T '{phase}\n'
65 $ hg log -r 'wdir() and secret()' -T '{phase}\n'
66 secret
66 secret
67
67
68 Working directory phase is draft when its parent is draft.
68 Working directory phase is draft when its parent is draft.
69
69
70 $ hg phase --draft .
70 $ hg phase --draft .
71 test-debug-phase: move rev 1: 2 -> 1
71 test-debug-phase: move rev 1: 2 -> 1
72 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: secret -> draft
72 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: secret -> draft
73 $ hg log -r 'wdir()' -T '{phase}\n'
73 $ hg log -r 'wdir()' -T '{phase}\n'
74 draft
74 draft
75 $ hg log -r 'wdir() and public()' -T '{phase}\n'
75 $ hg log -r 'wdir() and public()' -T '{phase}\n'
76 $ hg log -r 'wdir() and draft()' -T '{phase}\n'
76 $ hg log -r 'wdir() and draft()' -T '{phase}\n'
77 draft
77 draft
78 $ hg log -r 'wdir() and secret()' -T '{phase}\n'
78 $ hg log -r 'wdir() and secret()' -T '{phase}\n'
79
79
80 Working directory phase is secret when a new commit will be created as secret,
80 Working directory phase is secret when a new commit will be created as secret,
81 even if the parent is draft.
81 even if the parent is draft.
82
82
83 $ hg log -r 'wdir() and secret()' -T '{phase}\n' \
83 $ hg log -r 'wdir() and secret()' -T '{phase}\n' \
84 > --config phases.new-commit='secret'
84 > --config phases.new-commit='secret'
85 secret
85 secret
86
86
87 Working directory phase is draft when its parent is public.
87 Working directory phase is draft when its parent is public.
88
88
89 $ hg phase --public .
89 $ hg phase --public .
90 test-debug-phase: move rev 0: 1 -> 0
90 test-debug-phase: move rev 0: 1 -> 0
91 test-debug-phase: move rev 1: 1 -> 0
91 test-debug-phase: move rev 1: 1 -> 0
92 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: draft -> public
92 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: draft -> public
93 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: draft -> public
93 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: draft -> public
94 $ hg log -r 'wdir()' -T '{phase}\n'
94 $ hg log -r 'wdir()' -T '{phase}\n'
95 draft
95 draft
96 $ hg log -r 'wdir() and public()' -T '{phase}\n'
96 $ hg log -r 'wdir() and public()' -T '{phase}\n'
97 $ hg log -r 'wdir() and draft()' -T '{phase}\n'
97 $ hg log -r 'wdir() and draft()' -T '{phase}\n'
98 draft
98 draft
99 $ hg log -r 'wdir() and secret()' -T '{phase}\n'
99 $ hg log -r 'wdir() and secret()' -T '{phase}\n'
100 $ hg log -r 'wdir() and secret()' -T '{phase}\n' \
100 $ hg log -r 'wdir() and secret()' -T '{phase}\n' \
101 > --config phases.new-commit='secret'
101 > --config phases.new-commit='secret'
102 secret
102 secret
103
103
104 Draft commit are properly created over public one:
104 Draft commit are properly created over public one:
105
105
106 $ hg phase
106 $ hg phase
107 1: public
107 1: public
108 $ hglog
108 $ hglog
109 @ 1 0 B
109 @ 1 0 B
110 |
110 |
111 o 0 0 A
111 o 0 0 A
112
112
113
113
114 $ mkcommit C
114 $ mkcommit C
115 test-debug-phase: new rev 2: x -> 1
115 test-debug-phase: new rev 2: x -> 1
116 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> draft
116 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> draft
117 $ mkcommit D
117 $ mkcommit D
118 test-debug-phase: new rev 3: x -> 1
118 test-debug-phase: new rev 3: x -> 1
119 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> draft
119 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> draft
120
120
121 $ hglog
121 $ hglog
122 @ 3 1 D
122 @ 3 1 D
123 |
123 |
124 o 2 1 C
124 o 2 1 C
125 |
125 |
126 o 1 0 B
126 o 1 0 B
127 |
127 |
128 o 0 0 A
128 o 0 0 A
129
129
130
130
131 Test creating changeset as secret
131 Test creating changeset as secret
132
132
133 $ mkcommit E --config phases.new-commit='secret'
133 $ mkcommit E --config phases.new-commit='secret'
134 test-debug-phase: new rev 4: x -> 2
134 test-debug-phase: new rev 4: x -> 2
135 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: -> secret
135 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: -> secret
136 $ hglog
136 $ hglog
137 @ 4 2 E
137 @ 4 2 E
138 |
138 |
139 o 3 1 D
139 o 3 1 D
140 |
140 |
141 o 2 1 C
141 o 2 1 C
142 |
142 |
143 o 1 0 B
143 o 1 0 B
144 |
144 |
145 o 0 0 A
145 o 0 0 A
146
146
147
147
148 Test the secret property is inherited
148 Test the secret property is inherited
149
149
150 $ mkcommit H
150 $ mkcommit H
151 test-debug-phase: new rev 5: x -> 2
151 test-debug-phase: new rev 5: x -> 2
152 test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8: -> secret
152 test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8: -> secret
153 $ hglog
153 $ hglog
154 @ 5 2 H
154 @ 5 2 H
155 |
155 |
156 o 4 2 E
156 o 4 2 E
157 |
157 |
158 o 3 1 D
158 o 3 1 D
159 |
159 |
160 o 2 1 C
160 o 2 1 C
161 |
161 |
162 o 1 0 B
162 o 1 0 B
163 |
163 |
164 o 0 0 A
164 o 0 0 A
165
165
166
166
167 Even on merge
167 Even on merge
168
168
169 $ hg up -q 1
169 $ hg up -q 1
170 $ mkcommit "B'"
170 $ mkcommit "B'"
171 test-debug-phase: new rev 6: x -> 1
171 test-debug-phase: new rev 6: x -> 1
172 created new head
172 created new head
173 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> draft
173 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> draft
174 $ hglog
174 $ hglog
175 @ 6 1 B'
175 @ 6 1 B'
176 |
176 |
177 | o 5 2 H
177 | o 5 2 H
178 | |
178 | |
179 | o 4 2 E
179 | o 4 2 E
180 | |
180 | |
181 | o 3 1 D
181 | o 3 1 D
182 | |
182 | |
183 | o 2 1 C
183 | o 2 1 C
184 |/
184 |/
185 o 1 0 B
185 o 1 0 B
186 |
186 |
187 o 0 0 A
187 o 0 0 A
188
188
189 $ hg merge 4 # E
189 $ hg merge 4 # E
190 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
190 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 (branch merge, don't forget to commit)
191 (branch merge, don't forget to commit)
192 $ hg phase
192 $ hg phase
193 6: draft
193 6: draft
194 4: secret
194 4: secret
195 $ hg ci -m "merge B' and E"
195 $ hg ci -m "merge B' and E"
196 test-debug-phase: new rev 7: x -> 2
196 test-debug-phase: new rev 7: x -> 2
197 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: -> secret
197 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: -> secret
198
198
199 $ hglog
199 $ hglog
200 @ 7 2 merge B' and E
200 @ 7 2 merge B' and E
201 |\
201 |\
202 | o 6 1 B'
202 | o 6 1 B'
203 | |
203 | |
204 +---o 5 2 H
204 +---o 5 2 H
205 | |
205 | |
206 o | 4 2 E
206 o | 4 2 E
207 | |
207 | |
208 o | 3 1 D
208 o | 3 1 D
209 | |
209 | |
210 o | 2 1 C
210 o | 2 1 C
211 |/
211 |/
212 o 1 0 B
212 o 1 0 B
213 |
213 |
214 o 0 0 A
214 o 0 0 A
215
215
216
216
217 Test secret changeset are not pushed
217 Test secret changeset are not pushed
218
218
219 $ hg init ../push-dest
219 $ hg init ../push-dest
220 $ cat > ../push-dest/.hg/hgrc << EOF
220 $ cat > ../push-dest/.hg/hgrc << EOF
221 > [phases]
221 > [phases]
222 > publish=False
222 > publish=False
223 > EOF
223 > EOF
224 $ hg outgoing ../push-dest --template='{rev} {phase} {desc|firstline}\n'
224 $ hg outgoing ../push-dest --template='{rev} {phase} {desc|firstline}\n'
225 comparing with ../push-dest
225 comparing with ../push-dest
226 searching for changes
226 searching for changes
227 0 public A
227 0 public A
228 1 public B
228 1 public B
229 2 draft C
229 2 draft C
230 3 draft D
230 3 draft D
231 6 draft B'
231 6 draft B'
232 $ hg outgoing -r 'branch(default)' ../push-dest --template='{rev} {phase} {desc|firstline}\n'
232 $ hg outgoing -r 'branch(default)' ../push-dest --template='{rev} {phase} {desc|firstline}\n'
233 comparing with ../push-dest
233 comparing with ../push-dest
234 searching for changes
234 searching for changes
235 0 public A
235 0 public A
236 1 public B
236 1 public B
237 2 draft C
237 2 draft C
238 3 draft D
238 3 draft D
239 6 draft B'
239 6 draft B'
240
240
241 $ hg push ../push-dest -f # force because we push multiple heads
241 $ hg push ../push-dest -f # force because we push multiple heads
242 pushing to ../push-dest
242 pushing to ../push-dest
243 searching for changes
243 searching for changes
244 adding changesets
244 adding changesets
245 adding manifests
245 adding manifests
246 adding file changes
246 adding file changes
247 added 5 changesets with 5 changes to 5 files (+1 heads)
247 added 5 changesets with 5 changes to 5 files (+1 heads)
248 test-debug-phase: new rev 0: x -> 0
248 test-debug-phase: new rev 0: x -> 0
249 test-debug-phase: new rev 1: x -> 0
249 test-debug-phase: new rev 1: x -> 0
250 test-debug-phase: new rev 2: x -> 1
250 test-debug-phase: new rev 2: x -> 1
251 test-debug-phase: new rev 3: x -> 1
251 test-debug-phase: new rev 3: x -> 1
252 test-debug-phase: new rev 4: x -> 1
252 test-debug-phase: new rev 4: x -> 1
253 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> public
253 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> public
254 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> public
254 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> public
255 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> draft
255 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> draft
256 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> draft
256 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> draft
257 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> draft
257 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> draft
258 $ hglog
258 $ hglog
259 @ 7 2 merge B' and E
259 @ 7 2 merge B' and E
260 |\
260 |\
261 | o 6 1 B'
261 | o 6 1 B'
262 | |
262 | |
263 +---o 5 2 H
263 +---o 5 2 H
264 | |
264 | |
265 o | 4 2 E
265 o | 4 2 E
266 | |
266 | |
267 o | 3 1 D
267 o | 3 1 D
268 | |
268 | |
269 o | 2 1 C
269 o | 2 1 C
270 |/
270 |/
271 o 1 0 B
271 o 1 0 B
272 |
272 |
273 o 0 0 A
273 o 0 0 A
274
274
275 $ cd ../push-dest
275 $ cd ../push-dest
276 $ hglog
276 $ hglog
277 o 4 1 B'
277 o 4 1 B'
278 |
278 |
279 | o 3 1 D
279 | o 3 1 D
280 | |
280 | |
281 | o 2 1 C
281 | o 2 1 C
282 |/
282 |/
283 o 1 0 B
283 o 1 0 B
284 |
284 |
285 o 0 0 A
285 o 0 0 A
286
286
287
287
288 (Issue3303)
288 (Issue3303)
289 Check that remote secret changeset are ignore when checking creation of remote heads
289 Check that remote secret changeset are ignore when checking creation of remote heads
290
290
291 We add a secret head into the push destination. This secret head shadows a
291 We add a secret head into the push destination. This secret head shadows a
292 visible shared between the initial repo and the push destination.
292 visible shared between the initial repo and the push destination.
293
293
294 $ hg up -q 4 # B'
294 $ hg up -q 4 # B'
295 $ mkcommit Z --config phases.new-commit=secret
295 $ mkcommit Z --config phases.new-commit=secret
296 test-debug-phase: new rev 5: x -> 2
296 test-debug-phase: new rev 5: x -> 2
297 test-hook-close-phase: 2713879da13d6eea1ff22b442a5a87cb31a7ce6a: -> secret
297 test-hook-close-phase: 2713879da13d6eea1ff22b442a5a87cb31a7ce6a: -> secret
298 $ hg phase .
298 $ hg phase .
299 5: secret
299 5: secret
300
300
301 We now try to push a new public changeset that descend from the common public
301 We now try to push a new public changeset that descend from the common public
302 head shadowed by the remote secret head.
302 head shadowed by the remote secret head.
303
303
304 $ cd ../initialrepo
304 $ cd ../initialrepo
305 $ hg up -q 6 #B'
305 $ hg up -q 6 #B'
306 $ mkcommit I
306 $ mkcommit I
307 test-debug-phase: new rev 8: x -> 1
307 test-debug-phase: new rev 8: x -> 1
308 created new head
308 created new head
309 test-hook-close-phase: 6d6770faffce199f1fddd1cf87f6f026138cf061: -> draft
309 test-hook-close-phase: 6d6770faffce199f1fddd1cf87f6f026138cf061: -> draft
310 $ hg push ../push-dest
310 $ hg push ../push-dest
311 pushing to ../push-dest
311 pushing to ../push-dest
312 searching for changes
312 searching for changes
313 adding changesets
313 adding changesets
314 adding manifests
314 adding manifests
315 adding file changes
315 adding file changes
316 added 1 changesets with 1 changes to 1 files (+1 heads)
316 added 1 changesets with 1 changes to 1 files (+1 heads)
317 test-debug-phase: new rev 6: x -> 1
317 test-debug-phase: new rev 6: x -> 1
318 test-hook-close-phase: 6d6770faffce199f1fddd1cf87f6f026138cf061: -> draft
318 test-hook-close-phase: 6d6770faffce199f1fddd1cf87f6f026138cf061: -> draft
319
319
320 :note: The "(+1 heads)" is wrong as we do not had any visible head
320 :note: The "(+1 heads)" is wrong as we do not had any visible head
321
321
322 check that branch cache with "served" filter are properly computed and stored
322 check that branch cache with "served" filter are properly computed and stored
323
323
324 $ ls ../push-dest/.hg/cache/branch2*
324 $ ls ../push-dest/.hg/cache/branch2*
325 ../push-dest/.hg/cache/branch2-base
325 ../push-dest/.hg/cache/branch2-base
326 ../push-dest/.hg/cache/branch2-served
326 ../push-dest/.hg/cache/branch2-served
327 $ cat ../push-dest/.hg/cache/branch2-served
327 $ cat ../push-dest/.hg/cache/branch2-served
328 6d6770faffce199f1fddd1cf87f6f026138cf061 6 465891ffab3c47a3c23792f7dc84156e19a90722
328 6d6770faffce199f1fddd1cf87f6f026138cf061 6 465891ffab3c47a3c23792f7dc84156e19a90722
329 b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e o default
329 b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e o default
330 6d6770faffce199f1fddd1cf87f6f026138cf061 o default
330 6d6770faffce199f1fddd1cf87f6f026138cf061 o default
331 $ hg heads -R ../push-dest --template '{rev}:{node} {phase}\n' #update visible cache too
331 $ hg heads -R ../push-dest --template '{rev}:{node} {phase}\n' #update visible cache too
332 6:6d6770faffce199f1fddd1cf87f6f026138cf061 draft
332 6:6d6770faffce199f1fddd1cf87f6f026138cf061 draft
333 5:2713879da13d6eea1ff22b442a5a87cb31a7ce6a secret
333 5:2713879da13d6eea1ff22b442a5a87cb31a7ce6a secret
334 3:b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e draft
334 3:b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e draft
335 $ ls ../push-dest/.hg/cache/branch2*
335 $ ls ../push-dest/.hg/cache/branch2*
336 ../push-dest/.hg/cache/branch2-base
336 ../push-dest/.hg/cache/branch2-base
337 ../push-dest/.hg/cache/branch2-served
337 ../push-dest/.hg/cache/branch2-served
338 ../push-dest/.hg/cache/branch2-visible
338 ../push-dest/.hg/cache/branch2-visible
339 $ cat ../push-dest/.hg/cache/branch2-served
339 $ cat ../push-dest/.hg/cache/branch2-served
340 6d6770faffce199f1fddd1cf87f6f026138cf061 6 465891ffab3c47a3c23792f7dc84156e19a90722
340 6d6770faffce199f1fddd1cf87f6f026138cf061 6 465891ffab3c47a3c23792f7dc84156e19a90722
341 b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e o default
341 b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e o default
342 6d6770faffce199f1fddd1cf87f6f026138cf061 o default
342 6d6770faffce199f1fddd1cf87f6f026138cf061 o default
343 $ cat ../push-dest/.hg/cache/branch2-visible
343 $ cat ../push-dest/.hg/cache/branch2-visible
344 6d6770faffce199f1fddd1cf87f6f026138cf061 6
344 6d6770faffce199f1fddd1cf87f6f026138cf061 6
345 b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e o default
345 b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e o default
346 2713879da13d6eea1ff22b442a5a87cb31a7ce6a o default
346 2713879da13d6eea1ff22b442a5a87cb31a7ce6a o default
347 6d6770faffce199f1fddd1cf87f6f026138cf061 o default
347 6d6770faffce199f1fddd1cf87f6f026138cf061 o default
348
348
349
349
350 Restore condition prior extra insertion.
350 Restore condition prior extra insertion.
351 $ hg -q --config extensions.mq= strip .
351 $ hg -q --config extensions.mq= strip .
352 $ hg up -q 7
352 $ hg up -q 7
353 $ cd ..
353 $ cd ..
354
354
355 Test secret changeset are not pull
355 Test secret changeset are not pull
356
356
357 $ hg init pull-dest
357 $ hg init pull-dest
358 $ cd pull-dest
358 $ cd pull-dest
359 $ hg pull ../initialrepo
359 $ hg pull ../initialrepo
360 pulling from ../initialrepo
360 pulling from ../initialrepo
361 requesting all changes
361 requesting all changes
362 adding changesets
362 adding changesets
363 adding manifests
363 adding manifests
364 adding file changes
364 adding file changes
365 added 5 changesets with 5 changes to 5 files (+1 heads)
365 added 5 changesets with 5 changes to 5 files (+1 heads)
366 new changesets 4a2df7238c3b:cf9fe039dfd6
366 new changesets 4a2df7238c3b:cf9fe039dfd6
367 test-debug-phase: new rev 0: x -> 0
367 test-debug-phase: new rev 0: x -> 0
368 test-debug-phase: new rev 1: x -> 0
368 test-debug-phase: new rev 1: x -> 0
369 test-debug-phase: new rev 2: x -> 0
369 test-debug-phase: new rev 2: x -> 0
370 test-debug-phase: new rev 3: x -> 0
370 test-debug-phase: new rev 3: x -> 0
371 test-debug-phase: new rev 4: x -> 0
371 test-debug-phase: new rev 4: x -> 0
372 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> public
372 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> public
373 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> public
373 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> public
374 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> public
374 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> public
375 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> public
375 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> public
376 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> public
376 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> public
377 (run 'hg heads' to see heads, 'hg merge' to merge)
377 (run 'hg heads' to see heads, 'hg merge' to merge)
378 $ hglog
378 $ hglog
379 o 4 0 B'
379 o 4 0 B'
380 |
380 |
381 | o 3 0 D
381 | o 3 0 D
382 | |
382 | |
383 | o 2 0 C
383 | o 2 0 C
384 |/
384 |/
385 o 1 0 B
385 o 1 0 B
386 |
386 |
387 o 0 0 A
387 o 0 0 A
388
388
389 $ cd ..
389 $ cd ..
390
390
391 But secret can still be bundled explicitly
391 But secret can still be bundled explicitly
392
392
393 $ cd initialrepo
393 $ cd initialrepo
394 $ hg bundle --base '4^' -r 'children(4)' ../secret-bundle.hg
394 $ hg bundle --base '4^' -r 'children(4)' ../secret-bundle.hg
395 4 changesets found
395 4 changesets found
396 $ cd ..
396 $ cd ..
397
397
398 Test secret changeset are not cloned
398 Test secret changeset are not cloned
399 (during local clone)
399 (during local clone)
400
400
401 $ hg clone -qU initialrepo clone-dest
401 $ hg clone -qU initialrepo clone-dest
402 test-debug-phase: new rev 0: x -> 0
402 test-debug-phase: new rev 0: x -> 0
403 test-debug-phase: new rev 1: x -> 0
403 test-debug-phase: new rev 1: x -> 0
404 test-debug-phase: new rev 2: x -> 0
404 test-debug-phase: new rev 2: x -> 0
405 test-debug-phase: new rev 3: x -> 0
405 test-debug-phase: new rev 3: x -> 0
406 test-debug-phase: new rev 4: x -> 0
406 test-debug-phase: new rev 4: x -> 0
407 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> public
407 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> public
408 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> public
408 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> public
409 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> public
409 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> public
410 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> public
410 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> public
411 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> public
411 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> public
412 $ hglog -R clone-dest
412 $ hglog -R clone-dest
413 o 4 0 B'
413 o 4 0 B'
414 |
414 |
415 | o 3 0 D
415 | o 3 0 D
416 | |
416 | |
417 | o 2 0 C
417 | o 2 0 C
418 |/
418 |/
419 o 1 0 B
419 o 1 0 B
420 |
420 |
421 o 0 0 A
421 o 0 0 A
422
422
423
423
424 Test summary
424 Test summary
425
425
426 $ hg summary -R clone-dest --verbose
426 $ hg summary -R clone-dest --verbose
427 parent: -1:000000000000 (no revision checked out)
427 parent: -1:000000000000 (no revision checked out)
428 branch: default
428 branch: default
429 commit: (clean)
429 commit: (clean)
430 update: 5 new changesets (update)
430 update: 5 new changesets (update)
431 $ hg summary -R initialrepo
431 $ hg summary -R initialrepo
432 parent: 7:17a481b3bccb tip
432 parent: 7:17a481b3bccb tip
433 merge B' and E
433 merge B' and E
434 branch: default
434 branch: default
435 commit: (clean) (secret)
435 commit: (clean) (secret)
436 update: 1 new changesets, 2 branch heads (merge)
436 update: 1 new changesets, 2 branch heads (merge)
437 phases: 3 draft, 3 secret
437 phases: 3 draft, 3 secret
438 $ hg summary -R initialrepo --quiet
438 $ hg summary -R initialrepo --quiet
439 parent: 7:17a481b3bccb tip
439 parent: 7:17a481b3bccb tip
440 update: 1 new changesets, 2 branch heads (merge)
440 update: 1 new changesets, 2 branch heads (merge)
441
441
442 Test revset
442 Test revset
443
443
444 $ cd initialrepo
444 $ cd initialrepo
445 $ hglog -r 'public()'
445 $ hglog -r 'public()'
446 o 1 0 B
446 o 1 0 B
447 |
447 |
448 o 0 0 A
448 o 0 0 A
449
449
450 $ hglog -r 'draft()'
450 $ hglog -r 'draft()'
451 o 6 1 B'
451 o 6 1 B'
452 |
452 |
453 ~
453 ~
454 o 3 1 D
454 o 3 1 D
455 |
455 |
456 o 2 1 C
456 o 2 1 C
457 |
457 |
458 ~
458 ~
459 $ hglog -r 'secret()'
459 $ hglog -r 'secret()'
460 @ 7 2 merge B' and E
460 @ 7 2 merge B' and E
461 |\
461 |\
462 | ~
462 | ~
463 | o 5 2 H
463 | o 5 2 H
464 |/
464 |/
465 o 4 2 E
465 o 4 2 E
466 |
466 |
467 ~
467 ~
468
468
469 test that phase are displayed in log at debug level
469 test that phase are displayed in log at debug level
470
470
471 $ hg log --debug
471 $ hg log --debug
472 changeset: 7:17a481b3bccb796c0521ae97903d81c52bfee4af
472 changeset: 7:17a481b3bccb796c0521ae97903d81c52bfee4af
473 tag: tip
473 tag: tip
474 phase: secret
474 phase: secret
475 parent: 6:cf9fe039dfd67e829edf6522a45de057b5c86519
475 parent: 6:cf9fe039dfd67e829edf6522a45de057b5c86519
476 parent: 4:a603bfb5a83e312131cebcd05353c217d4d21dde
476 parent: 4:a603bfb5a83e312131cebcd05353c217d4d21dde
477 manifest: 7:5e724ffacba267b2ab726c91fc8b650710deaaa8
477 manifest: 7:5e724ffacba267b2ab726c91fc8b650710deaaa8
478 user: test
478 user: test
479 date: Thu Jan 01 00:00:00 1970 +0000
479 date: Thu Jan 01 00:00:00 1970 +0000
480 extra: branch=default
480 extra: branch=default
481 description:
481 description:
482 merge B' and E
482 merge B' and E
483
483
484
484
485 changeset: 6:cf9fe039dfd67e829edf6522a45de057b5c86519
485 changeset: 6:cf9fe039dfd67e829edf6522a45de057b5c86519
486 phase: draft
486 phase: draft
487 parent: 1:27547f69f25460a52fff66ad004e58da7ad3fb56
487 parent: 1:27547f69f25460a52fff66ad004e58da7ad3fb56
488 parent: -1:0000000000000000000000000000000000000000
488 parent: -1:0000000000000000000000000000000000000000
489 manifest: 6:ab8bfef2392903058bf4ebb9e7746e8d7026b27a
489 manifest: 6:ab8bfef2392903058bf4ebb9e7746e8d7026b27a
490 user: test
490 user: test
491 date: Thu Jan 01 00:00:00 1970 +0000
491 date: Thu Jan 01 00:00:00 1970 +0000
492 files+: B'
492 files+: B'
493 extra: branch=default
493 extra: branch=default
494 description:
494 description:
495 B'
495 B'
496
496
497
497
498 changeset: 5:a030c6be5127abc010fcbff1851536552e6951a8
498 changeset: 5:a030c6be5127abc010fcbff1851536552e6951a8
499 phase: secret
499 phase: secret
500 parent: 4:a603bfb5a83e312131cebcd05353c217d4d21dde
500 parent: 4:a603bfb5a83e312131cebcd05353c217d4d21dde
501 parent: -1:0000000000000000000000000000000000000000
501 parent: -1:0000000000000000000000000000000000000000
502 manifest: 5:5c710aa854874fe3d5fa7192e77bdb314cc08b5a
502 manifest: 5:5c710aa854874fe3d5fa7192e77bdb314cc08b5a
503 user: test
503 user: test
504 date: Thu Jan 01 00:00:00 1970 +0000
504 date: Thu Jan 01 00:00:00 1970 +0000
505 files+: H
505 files+: H
506 extra: branch=default
506 extra: branch=default
507 description:
507 description:
508 H
508 H
509
509
510
510
511 changeset: 4:a603bfb5a83e312131cebcd05353c217d4d21dde
511 changeset: 4:a603bfb5a83e312131cebcd05353c217d4d21dde
512 phase: secret
512 phase: secret
513 parent: 3:b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
513 parent: 3:b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
514 parent: -1:0000000000000000000000000000000000000000
514 parent: -1:0000000000000000000000000000000000000000
515 manifest: 4:7173fd1c27119750b959e3a0f47ed78abe75d6dc
515 manifest: 4:7173fd1c27119750b959e3a0f47ed78abe75d6dc
516 user: test
516 user: test
517 date: Thu Jan 01 00:00:00 1970 +0000
517 date: Thu Jan 01 00:00:00 1970 +0000
518 files+: E
518 files+: E
519 extra: branch=default
519 extra: branch=default
520 description:
520 description:
521 E
521 E
522
522
523
523
524 changeset: 3:b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
524 changeset: 3:b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
525 phase: draft
525 phase: draft
526 parent: 2:f838bfaca5c7226600ebcfd84f3c3c13a28d3757
526 parent: 2:f838bfaca5c7226600ebcfd84f3c3c13a28d3757
527 parent: -1:0000000000000000000000000000000000000000
527 parent: -1:0000000000000000000000000000000000000000
528 manifest: 3:6e1f4c47ecb533ffd0c8e52cdc88afb6cd39e20c
528 manifest: 3:6e1f4c47ecb533ffd0c8e52cdc88afb6cd39e20c
529 user: test
529 user: test
530 date: Thu Jan 01 00:00:00 1970 +0000
530 date: Thu Jan 01 00:00:00 1970 +0000
531 files+: D
531 files+: D
532 extra: branch=default
532 extra: branch=default
533 description:
533 description:
534 D
534 D
535
535
536
536
537 changeset: 2:f838bfaca5c7226600ebcfd84f3c3c13a28d3757
537 changeset: 2:f838bfaca5c7226600ebcfd84f3c3c13a28d3757
538 phase: draft
538 phase: draft
539 parent: 1:27547f69f25460a52fff66ad004e58da7ad3fb56
539 parent: 1:27547f69f25460a52fff66ad004e58da7ad3fb56
540 parent: -1:0000000000000000000000000000000000000000
540 parent: -1:0000000000000000000000000000000000000000
541 manifest: 2:66a5a01817fdf5239c273802b5b7618d051c89e4
541 manifest: 2:66a5a01817fdf5239c273802b5b7618d051c89e4
542 user: test
542 user: test
543 date: Thu Jan 01 00:00:00 1970 +0000
543 date: Thu Jan 01 00:00:00 1970 +0000
544 files+: C
544 files+: C
545 extra: branch=default
545 extra: branch=default
546 description:
546 description:
547 C
547 C
548
548
549
549
550 changeset: 1:27547f69f25460a52fff66ad004e58da7ad3fb56
550 changeset: 1:27547f69f25460a52fff66ad004e58da7ad3fb56
551 phase: public
551 phase: public
552 parent: 0:4a2df7238c3b48766b5e22fafbb8a2f506ec8256
552 parent: 0:4a2df7238c3b48766b5e22fafbb8a2f506ec8256
553 parent: -1:0000000000000000000000000000000000000000
553 parent: -1:0000000000000000000000000000000000000000
554 manifest: 1:cb5cbbc1bfbf24cc34b9e8c16914e9caa2d2a7fd
554 manifest: 1:cb5cbbc1bfbf24cc34b9e8c16914e9caa2d2a7fd
555 user: test
555 user: test
556 date: Thu Jan 01 00:00:00 1970 +0000
556 date: Thu Jan 01 00:00:00 1970 +0000
557 files+: B
557 files+: B
558 extra: branch=default
558 extra: branch=default
559 description:
559 description:
560 B
560 B
561
561
562
562
563 changeset: 0:4a2df7238c3b48766b5e22fafbb8a2f506ec8256
563 changeset: 0:4a2df7238c3b48766b5e22fafbb8a2f506ec8256
564 phase: public
564 phase: public
565 parent: -1:0000000000000000000000000000000000000000
565 parent: -1:0000000000000000000000000000000000000000
566 parent: -1:0000000000000000000000000000000000000000
566 parent: -1:0000000000000000000000000000000000000000
567 manifest: 0:007d8c9d88841325f5c6b06371b35b4e8a2b1a83
567 manifest: 0:007d8c9d88841325f5c6b06371b35b4e8a2b1a83
568 user: test
568 user: test
569 date: Thu Jan 01 00:00:00 1970 +0000
569 date: Thu Jan 01 00:00:00 1970 +0000
570 files+: A
570 files+: A
571 extra: branch=default
571 extra: branch=default
572 description:
572 description:
573 A
573 A
574
574
575
575
576
576
577
577
578 (Issue3707)
578 (Issue3707)
579 test invalid phase name
579 test invalid phase name
580
580
581 $ mkcommit I --config phases.new-commit='babar'
581 $ mkcommit I --config phases.new-commit='babar'
582 transaction abort!
582 transaction abort!
583 rollback completed
583 rollback completed
584 config error: phases.new-commit: not a valid phase name ('babar')
584 config error: phases.new-commit: not a valid phase name ('babar')
585 [30]
585 [30]
586 Test phase command
586 Test phase command
587 ===================
587 ===================
588
588
589 initial picture
589 initial picture
590
590
591 $ hg log -G --template "{rev} {phase} {desc}\n"
591 $ hg log -G --template "{rev} {phase} {desc}\n"
592 @ 7 secret merge B' and E
592 @ 7 secret merge B' and E
593 |\
593 |\
594 | o 6 draft B'
594 | o 6 draft B'
595 | |
595 | |
596 +---o 5 secret H
596 +---o 5 secret H
597 | |
597 | |
598 o | 4 secret E
598 o | 4 secret E
599 | |
599 | |
600 o | 3 draft D
600 o | 3 draft D
601 | |
601 | |
602 o | 2 draft C
602 o | 2 draft C
603 |/
603 |/
604 o 1 public B
604 o 1 public B
605 |
605 |
606 o 0 public A
606 o 0 public A
607
607
608
608
609 display changesets phase
609 display changesets phase
610
610
611 (mixing -r and plain rev specification)
611 (mixing -r and plain rev specification)
612
612
613 $ hg phase 1::4 -r 7
613 $ hg phase 1::4 -r 7
614 1: public
614 1: public
615 2: draft
615 2: draft
616 3: draft
616 3: draft
617 4: secret
617 4: secret
618 7: secret
618 7: secret
619
619
620
620
621 move changeset forward
621 move changeset forward
622
622
623 (with -r option)
623 (with -r option)
624
624
625 $ hg phase --public -r 2
625 $ hg phase --public -r 2
626 test-debug-phase: move rev 2: 1 -> 0
626 test-debug-phase: move rev 2: 1 -> 0
627 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: draft -> public
627 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: draft -> public
628 $ hg log -G --template "{rev} {phase} {desc}\n"
628 $ hg log -G --template "{rev} {phase} {desc}\n"
629 @ 7 secret merge B' and E
629 @ 7 secret merge B' and E
630 |\
630 |\
631 | o 6 draft B'
631 | o 6 draft B'
632 | |
632 | |
633 +---o 5 secret H
633 +---o 5 secret H
634 | |
634 | |
635 o | 4 secret E
635 o | 4 secret E
636 | |
636 | |
637 o | 3 draft D
637 o | 3 draft D
638 | |
638 | |
639 o | 2 public C
639 o | 2 public C
640 |/
640 |/
641 o 1 public B
641 o 1 public B
642 |
642 |
643 o 0 public A
643 o 0 public A
644
644
645
645
646 move changeset backward
646 move changeset backward
647
647
648 (without -r option)
648 (without -r option)
649
649
650 $ hg phase --draft --force 2
650 $ hg phase --draft --force 2
651 test-debug-phase: move rev 2: 0 -> 1
651 test-debug-phase: move rev 2: 0 -> 1
652 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: public -> draft
652 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: public -> draft
653 $ hg log -G --template "{rev} {phase} {desc}\n"
653 $ hg log -G --template "{rev} {phase} {desc}\n"
654 @ 7 secret merge B' and E
654 @ 7 secret merge B' and E
655 |\
655 |\
656 | o 6 draft B'
656 | o 6 draft B'
657 | |
657 | |
658 +---o 5 secret H
658 +---o 5 secret H
659 | |
659 | |
660 o | 4 secret E
660 o | 4 secret E
661 | |
661 | |
662 o | 3 draft D
662 o | 3 draft D
663 | |
663 | |
664 o | 2 draft C
664 o | 2 draft C
665 |/
665 |/
666 o 1 public B
666 o 1 public B
667 |
667 |
668 o 0 public A
668 o 0 public A
669
669
670
670
671 move changeset forward and backward
671 move changeset forward and backward
672
672
673 $ hg phase --draft --force 1::4
673 $ hg phase --draft --force 1::4
674 test-debug-phase: move rev 1: 0 -> 1
674 test-debug-phase: move rev 1: 0 -> 1
675 test-debug-phase: move rev 4: 2 -> 1
675 test-debug-phase: move rev 4: 2 -> 1
676 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: public -> draft
676 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: public -> draft
677 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: secret -> draft
677 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: secret -> draft
678 $ hg log -G --template "{rev} {phase} {desc}\n"
678 $ hg log -G --template "{rev} {phase} {desc}\n"
679 @ 7 secret merge B' and E
679 @ 7 secret merge B' and E
680 |\
680 |\
681 | o 6 draft B'
681 | o 6 draft B'
682 | |
682 | |
683 +---o 5 secret H
683 +---o 5 secret H
684 | |
684 | |
685 o | 4 draft E
685 o | 4 draft E
686 | |
686 | |
687 o | 3 draft D
687 o | 3 draft D
688 | |
688 | |
689 o | 2 draft C
689 o | 2 draft C
690 |/
690 |/
691 o 1 draft B
691 o 1 draft B
692 |
692 |
693 o 0 public A
693 o 0 public A
694
694
695 test partial failure
695 test partial failure
696
696
697 $ hg phase --public 7
697 $ hg phase --public 7
698 test-debug-phase: move rev 1: 1 -> 0
698 test-debug-phase: move rev 1: 1 -> 0
699 test-debug-phase: move rev 2: 1 -> 0
699 test-debug-phase: move rev 2: 1 -> 0
700 test-debug-phase: move rev 3: 1 -> 0
700 test-debug-phase: move rev 3: 1 -> 0
701 test-debug-phase: move rev 4: 1 -> 0
701 test-debug-phase: move rev 4: 1 -> 0
702 test-debug-phase: move rev 6: 1 -> 0
702 test-debug-phase: move rev 6: 1 -> 0
703 test-debug-phase: move rev 7: 2 -> 0
703 test-debug-phase: move rev 7: 2 -> 0
704 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: draft -> public
704 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: draft -> public
705 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: draft -> public
705 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: draft -> public
706 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: draft -> public
706 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: draft -> public
707 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: draft -> public
707 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: draft -> public
708 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: draft -> public
708 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: draft -> public
709 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: secret -> public
709 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: secret -> public
710 $ hg phase --draft '5 or 7'
710 $ hg phase --draft '5 or 7'
711 test-debug-phase: move rev 5: 2 -> 1
711 test-debug-phase: move rev 5: 2 -> 1
712 test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8: secret -> draft
712 test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8: secret -> draft
713 cannot move 1 changesets to a higher phase, use --force
713 cannot move 1 changesets to a higher phase, use --force
714 phase changed for 1 changesets
714 phase changed for 1 changesets
715 [1]
715 [1]
716 $ hg log -G --template "{rev} {phase} {desc}\n"
716 $ hg log -G --template "{rev} {phase} {desc}\n"
717 @ 7 public merge B' and E
717 @ 7 public merge B' and E
718 |\
718 |\
719 | o 6 public B'
719 | o 6 public B'
720 | |
720 | |
721 +---o 5 draft H
721 +---o 5 draft H
722 | |
722 | |
723 o | 4 public E
723 o | 4 public E
724 | |
724 | |
725 o | 3 public D
725 o | 3 public D
726 | |
726 | |
727 o | 2 public C
727 o | 2 public C
728 |/
728 |/
729 o 1 public B
729 o 1 public B
730 |
730 |
731 o 0 public A
731 o 0 public A
732
732
733
733
734 test complete failure
734 test complete failure
735
735
736 $ hg phase --draft 7
736 $ hg phase --draft 7
737 cannot move 1 changesets to a higher phase, use --force
737 cannot move 1 changesets to a higher phase, use --force
738 no phases changed
738 no phases changed
739 [1]
739 [1]
740
740
741 $ cd ..
741 $ cd ..
742
742
743 test hidden changeset are not cloned as public (issue3935)
743 test hidden changeset are not cloned as public (issue3935)
744
744
745 $ cd initialrepo
745 $ cd initialrepo
746
746
747 (enabling evolution)
747 (enabling evolution)
748 $ cat >> $HGRCPATH << EOF
748 $ cat >> $HGRCPATH << EOF
749 > [experimental]
749 > [experimental]
750 > evolution.createmarkers=True
750 > evolution.createmarkers=True
751 > EOF
751 > EOF
752
752
753 (making a changeset hidden; H in that case)
753 (making a changeset hidden; H in that case)
754 $ hg debugobsolete `hg id --debug -r 5`
754 $ hg debugobsolete `hg id --debug -r 5`
755 1 new obsolescence markers
755 1 new obsolescence markers
756 obsoleted 1 changesets
756 obsoleted 1 changesets
757
757
758 $ cd ..
758 $ cd ..
759 $ hg clone initialrepo clonewithobs
759 $ hg clone initialrepo clonewithobs
760 requesting all changes
760 requesting all changes
761 adding changesets
761 adding changesets
762 adding manifests
762 adding manifests
763 adding file changes
763 adding file changes
764 added 7 changesets with 6 changes to 6 files
764 added 7 changesets with 6 changes to 6 files
765 new changesets 4a2df7238c3b:17a481b3bccb
765 new changesets 4a2df7238c3b:17a481b3bccb
766 test-debug-phase: new rev 0: x -> 0
766 test-debug-phase: new rev 0: x -> 0
767 test-debug-phase: new rev 1: x -> 0
767 test-debug-phase: new rev 1: x -> 0
768 test-debug-phase: new rev 2: x -> 0
768 test-debug-phase: new rev 2: x -> 0
769 test-debug-phase: new rev 3: x -> 0
769 test-debug-phase: new rev 3: x -> 0
770 test-debug-phase: new rev 4: x -> 0
770 test-debug-phase: new rev 4: x -> 0
771 test-debug-phase: new rev 5: x -> 0
771 test-debug-phase: new rev 5: x -> 0
772 test-debug-phase: new rev 6: x -> 0
772 test-debug-phase: new rev 6: x -> 0
773 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> public
773 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> public
774 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> public
774 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> public
775 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> public
775 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> public
776 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> public
776 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> public
777 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: -> public
777 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: -> public
778 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> public
778 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> public
779 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: -> public
779 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: -> public
780 updating to branch default
780 updating to branch default
781 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
781 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
782 $ cd clonewithobs
782 $ cd clonewithobs
783 $ hg log -G --template "{rev} {phase} {desc}\n"
783 $ hg log -G --template "{rev} {phase} {desc}\n"
784 @ 6 public merge B' and E
784 @ 6 public merge B' and E
785 |\
785 |\
786 | o 5 public B'
786 | o 5 public B'
787 | |
787 | |
788 o | 4 public E
788 o | 4 public E
789 | |
789 | |
790 o | 3 public D
790 o | 3 public D
791 | |
791 | |
792 o | 2 public C
792 o | 2 public C
793 |/
793 |/
794 o 1 public B
794 o 1 public B
795 |
795 |
796 o 0 public A
796 o 0 public A
797
797
798
798
799 test verify repo containing hidden changesets, which should not abort just
799 test verify repo containing hidden changesets, which should not abort just
800 because repo.cancopy() is False
800 because repo.cancopy() is False
801
801
802 $ cd ../initialrepo
802 $ cd ../initialrepo
803 $ hg verify -q
803 $ hg verify -q
804
804
805 $ cd ..
805 $ cd ..
806
806
807 check whether HG_PENDING makes pending changes only in related
807 check whether HG_PENDING makes pending changes only in related
808 repositories visible to an external hook.
808 repositories visible to an external hook.
809
809
810 (emulate a transaction running concurrently by copied
810 (emulate a transaction running concurrently by copied
811 .hg/phaseroots.pending in subsequent test)
811 .hg/phaseroots.pending in subsequent test)
812
812
813 $ cat > $TESTTMP/savepending.sh <<EOF
813 $ cat > $TESTTMP/savepending.sh <<EOF
814 > cp .hg/store/phaseroots.pending .hg/store/phaseroots.pending.saved
814 > cp .hg/store/phaseroots.pending .hg/store/phaseroots.pending.saved
815 > exit 1 # to avoid changing phase for subsequent tests
815 > exit 1 # to avoid changing phase for subsequent tests
816 > EOF
816 > EOF
817 $ cd push-dest
817 $ cd push-dest
818 $ hg phase 6
818 $ hg phase 6
819 6: draft
819 6: draft
820 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" phase -f -s 6
820 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" phase -f -s 6
821 transaction abort!
822 rollback completed
823 abort: pretxnclose hook exited with status 1
821 abort: pretxnclose hook exited with status 1
824 [40]
822 [40]
825 $ cp .hg/store/phaseroots.pending.saved .hg/store/phaseroots.pending
823 $ cp .hg/store/phaseroots.pending.saved .hg/store/phaseroots.pending
826
824
827 (check (in)visibility of phaseroot while transaction running in repo)
825 (check (in)visibility of phaseroot while transaction running in repo)
828
826
829 $ cat > $TESTTMP/checkpending.sh <<EOF
827 $ cat > $TESTTMP/checkpending.sh <<EOF
830 > echo '@initialrepo'
828 > echo '@initialrepo'
831 > hg -R "$TESTTMP/initialrepo" phase 7
829 > hg -R "$TESTTMP/initialrepo" phase 7
832 > echo '@push-dest'
830 > echo '@push-dest'
833 > hg -R "$TESTTMP/push-dest" phase 6
831 > hg -R "$TESTTMP/push-dest" phase 6
834 > exit 1 # to avoid changing phase for subsequent tests
832 > exit 1 # to avoid changing phase for subsequent tests
835 > EOF
833 > EOF
836 $ cd ../initialrepo
834 $ cd ../initialrepo
837 $ hg phase 7
835 $ hg phase 7
838 7: public
836 7: public
839 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" phase -f -s 7
837 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" phase -f -s 7
840 @initialrepo
838 @initialrepo
841 7: secret
839 7: secret
842 @push-dest
840 @push-dest
843 6: draft
841 6: draft
844 transaction abort!
845 rollback completed
846 abort: pretxnclose hook exited with status 1
842 abort: pretxnclose hook exited with status 1
847 [40]
843 [40]
848
844
849 Check that pretxnclose-phase hook can control phase movement
845 Check that pretxnclose-phase hook can control phase movement
850
846
851 $ hg phase --force b3325c91a4d9 --secret
847 $ hg phase --force b3325c91a4d9 --secret
852 test-debug-phase: move rev 3: 0 -> 2
848 test-debug-phase: move rev 3: 0 -> 2
853 test-debug-phase: move rev 4: 0 -> 2
849 test-debug-phase: move rev 4: 0 -> 2
854 test-debug-phase: move rev 5: 1 -> 2
850 test-debug-phase: move rev 5: 1 -> 2
855 test-debug-phase: move rev 7: 0 -> 2
851 test-debug-phase: move rev 7: 0 -> 2
856 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: public -> secret
852 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: public -> secret
857 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: public -> secret
853 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: public -> secret
858 test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8: draft -> secret
854 test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8: draft -> secret
859 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: public -> secret
855 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: public -> secret
860 $ hg log -G -T phases
856 $ hg log -G -T phases
861 @ changeset: 7:17a481b3bccb
857 @ changeset: 7:17a481b3bccb
862 |\ tag: tip
858 |\ tag: tip
863 | | phase: secret
859 | | phase: secret
864 | | parent: 6:cf9fe039dfd6
860 | | parent: 6:cf9fe039dfd6
865 | | parent: 4:a603bfb5a83e
861 | | parent: 4:a603bfb5a83e
866 | | user: test
862 | | user: test
867 | | date: Thu Jan 01 00:00:00 1970 +0000
863 | | date: Thu Jan 01 00:00:00 1970 +0000
868 | | summary: merge B' and E
864 | | summary: merge B' and E
869 | |
865 | |
870 | o changeset: 6:cf9fe039dfd6
866 | o changeset: 6:cf9fe039dfd6
871 | | phase: public
867 | | phase: public
872 | | parent: 1:27547f69f254
868 | | parent: 1:27547f69f254
873 | | user: test
869 | | user: test
874 | | date: Thu Jan 01 00:00:00 1970 +0000
870 | | date: Thu Jan 01 00:00:00 1970 +0000
875 | | summary: B'
871 | | summary: B'
876 | |
872 | |
877 o | changeset: 4:a603bfb5a83e
873 o | changeset: 4:a603bfb5a83e
878 | | phase: secret
874 | | phase: secret
879 | | user: test
875 | | user: test
880 | | date: Thu Jan 01 00:00:00 1970 +0000
876 | | date: Thu Jan 01 00:00:00 1970 +0000
881 | | summary: E
877 | | summary: E
882 | |
878 | |
883 o | changeset: 3:b3325c91a4d9
879 o | changeset: 3:b3325c91a4d9
884 | | phase: secret
880 | | phase: secret
885 | | user: test
881 | | user: test
886 | | date: Thu Jan 01 00:00:00 1970 +0000
882 | | date: Thu Jan 01 00:00:00 1970 +0000
887 | | summary: D
883 | | summary: D
888 | |
884 | |
889 o | changeset: 2:f838bfaca5c7
885 o | changeset: 2:f838bfaca5c7
890 |/ phase: public
886 |/ phase: public
891 | user: test
887 | user: test
892 | date: Thu Jan 01 00:00:00 1970 +0000
888 | date: Thu Jan 01 00:00:00 1970 +0000
893 | summary: C
889 | summary: C
894 |
890 |
895 o changeset: 1:27547f69f254
891 o changeset: 1:27547f69f254
896 | phase: public
892 | phase: public
897 | user: test
893 | user: test
898 | date: Thu Jan 01 00:00:00 1970 +0000
894 | date: Thu Jan 01 00:00:00 1970 +0000
899 | summary: B
895 | summary: B
900 |
896 |
901 o changeset: 0:4a2df7238c3b
897 o changeset: 0:4a2df7238c3b
902 phase: public
898 phase: public
903 user: test
899 user: test
904 date: Thu Jan 01 00:00:00 1970 +0000
900 date: Thu Jan 01 00:00:00 1970 +0000
905 summary: A
901 summary: A
906
902
907
903
908 Install a hook that prevent b3325c91a4d9 to become public
904 Install a hook that prevent b3325c91a4d9 to become public
909
905
910 $ cat >> .hg/hgrc << EOF
906 $ cat >> .hg/hgrc << EOF
911 > [hooks]
907 > [hooks]
912 > pretxnclose-phase.nopublish_D = sh -c "(echo \$HG_NODE| grep -v b3325c91a4d9>/dev/null) || [ 'public' != \$HG_PHASE ]"
908 > pretxnclose-phase.nopublish_D = sh -c "(echo \$HG_NODE| grep -v b3325c91a4d9>/dev/null) || [ 'public' != \$HG_PHASE ]"
913 > EOF
909 > EOF
914
910
915 Try various actions. only the draft move should succeed
911 Try various actions. only the draft move should succeed
916
912
917 $ hg phase --public b3325c91a4d9
913 $ hg phase --public b3325c91a4d9
918 transaction abort!
919 rollback completed
920 abort: pretxnclose-phase.nopublish_D hook exited with status 1
914 abort: pretxnclose-phase.nopublish_D hook exited with status 1
921 [40]
915 [40]
922 $ hg phase --public a603bfb5a83e
916 $ hg phase --public a603bfb5a83e
923 transaction abort!
924 rollback completed
925 abort: pretxnclose-phase.nopublish_D hook exited with status 1
917 abort: pretxnclose-phase.nopublish_D hook exited with status 1
926 [40]
918 [40]
927 $ hg phase --draft 17a481b3bccb
919 $ hg phase --draft 17a481b3bccb
928 test-debug-phase: move rev 3: 2 -> 1
920 test-debug-phase: move rev 3: 2 -> 1
929 test-debug-phase: move rev 4: 2 -> 1
921 test-debug-phase: move rev 4: 2 -> 1
930 test-debug-phase: move rev 7: 2 -> 1
922 test-debug-phase: move rev 7: 2 -> 1
931 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: secret -> draft
923 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: secret -> draft
932 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: secret -> draft
924 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: secret -> draft
933 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: secret -> draft
925 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: secret -> draft
934 $ hg phase --public 17a481b3bccb
926 $ hg phase --public 17a481b3bccb
935 transaction abort!
936 rollback completed
937 abort: pretxnclose-phase.nopublish_D hook exited with status 1
927 abort: pretxnclose-phase.nopublish_D hook exited with status 1
938 [40]
928 [40]
939
929
940 $ cd ..
930 $ cd ..
941
931
942 Test for the "internal" phase
932 Test for the "internal" phase
943 =============================
933 =============================
944
934
945 Check we deny its usage on older repository
935 Check we deny its usage on older repository
946
936
947 $ hg init no-internal-phase --config format.use-internal-phase=no
937 $ hg init no-internal-phase --config format.use-internal-phase=no
948 $ cd no-internal-phase
938 $ cd no-internal-phase
949 $ hg debugrequires | grep internal-phase
939 $ hg debugrequires | grep internal-phase
950 [1]
940 [1]
951 $ echo X > X
941 $ echo X > X
952 $ hg add X
942 $ hg add X
953 $ hg status
943 $ hg status
954 A X
944 A X
955 $ hg --config "phases.new-commit=internal" commit -m "my test internal commit" 2>&1 | grep ProgrammingError
945 $ hg --config "phases.new-commit=internal" commit -m "my test internal commit" 2>&1 | grep ProgrammingError
956 ** ProgrammingError: this repository does not support the internal phase
946 ** ProgrammingError: this repository does not support the internal phase
957 raise error.ProgrammingError(msg) (no-pyoxidizer !)
947 raise error.ProgrammingError(msg) (no-pyoxidizer !)
958 *ProgrammingError: this repository does not support the internal phase (glob)
948 *ProgrammingError: this repository does not support the internal phase (glob)
959 $ hg --config "phases.new-commit=archived" commit -m "my test archived commit" 2>&1 | grep ProgrammingError
949 $ hg --config "phases.new-commit=archived" commit -m "my test archived commit" 2>&1 | grep ProgrammingError
960 ** ProgrammingError: this repository does not support the archived phase
950 ** ProgrammingError: this repository does not support the archived phase
961 raise error.ProgrammingError(msg) (no-pyoxidizer !)
951 raise error.ProgrammingError(msg) (no-pyoxidizer !)
962 *ProgrammingError: this repository does not support the archived phase (glob)
952 *ProgrammingError: this repository does not support the archived phase (glob)
963
953
964 $ cd ..
954 $ cd ..
965
955
966 Check it works fine with repository that supports it.
956 Check it works fine with repository that supports it.
967
957
968 $ hg init internal-phase --config format.use-internal-phase=yes
958 $ hg init internal-phase --config format.use-internal-phase=yes
969 $ cd internal-phase
959 $ cd internal-phase
970 $ hg debugrequires | grep internal-phase
960 $ hg debugrequires | grep internal-phase
971 internal-phase-2
961 internal-phase-2
972 $ mkcommit A
962 $ mkcommit A
973 test-debug-phase: new rev 0: x -> 1
963 test-debug-phase: new rev 0: x -> 1
974 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> draft
964 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> draft
975
965
976 Commit an internal changesets
966 Commit an internal changesets
977
967
978 $ echo B > B
968 $ echo B > B
979 $ hg add B
969 $ hg add B
980 $ hg status
970 $ hg status
981 A B
971 A B
982 $ hg --config "phases.new-commit=internal" commit -m "my test internal commit"
972 $ hg --config "phases.new-commit=internal" commit -m "my test internal commit"
983 test-debug-phase: new rev 1: x -> 96
973 test-debug-phase: new rev 1: x -> 96
984 test-hook-close-phase: c01c42dffc7f81223397e99652a0703f83e1c5ea: -> internal
974 test-hook-close-phase: c01c42dffc7f81223397e99652a0703f83e1c5ea: -> internal
985
975
986 The changeset is a working parent descendant.
976 The changeset is a working parent descendant.
987 Per the usual visibility rules, it is made visible.
977 Per the usual visibility rules, it is made visible.
988
978
989 $ hg log -G -l 3
979 $ hg log -G -l 3
990 @ changeset: 1:c01c42dffc7f
980 @ changeset: 1:c01c42dffc7f
991 | tag: tip
981 | tag: tip
992 | user: test
982 | user: test
993 | date: Thu Jan 01 00:00:00 1970 +0000
983 | date: Thu Jan 01 00:00:00 1970 +0000
994 | summary: my test internal commit
984 | summary: my test internal commit
995 |
985 |
996 o changeset: 0:4a2df7238c3b
986 o changeset: 0:4a2df7238c3b
997 user: test
987 user: test
998 date: Thu Jan 01 00:00:00 1970 +0000
988 date: Thu Jan 01 00:00:00 1970 +0000
999 summary: A
989 summary: A
1000
990
1001
991
1002 Commit is hidden as expected
992 Commit is hidden as expected
1003
993
1004 $ hg up 0
994 $ hg up 0
1005 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
995 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1006 $ hg log -G
996 $ hg log -G
1007 @ changeset: 0:4a2df7238c3b
997 @ changeset: 0:4a2df7238c3b
1008 tag: tip
998 tag: tip
1009 user: test
999 user: test
1010 date: Thu Jan 01 00:00:00 1970 +0000
1000 date: Thu Jan 01 00:00:00 1970 +0000
1011 summary: A
1001 summary: A
1012
1002
1013
1003
1014 Test for archived phase
1004 Test for archived phase
1015 -----------------------
1005 -----------------------
1016
1006
1017 Commit an archived changesets
1007 Commit an archived changesets
1018
1008
1019 $ cd ..
1009 $ cd ..
1020 $ hg clone --quiet --pull internal-phase archived-phase \
1010 $ hg clone --quiet --pull internal-phase archived-phase \
1021 > --config format.exp-archived-phase=yes \
1011 > --config format.exp-archived-phase=yes \
1022 > --config extensions.phasereport='!' \
1012 > --config extensions.phasereport='!' \
1023 > --config hooks.txnclose-phase.test=
1013 > --config hooks.txnclose-phase.test=
1024
1014
1025 $ cd archived-phase
1015 $ cd archived-phase
1026
1016
1027 $ echo B > B
1017 $ echo B > B
1028 $ hg add B
1018 $ hg add B
1029 $ hg status
1019 $ hg status
1030 A B
1020 A B
1031 $ hg --config "phases.new-commit=archived" commit -m "my test archived commit"
1021 $ hg --config "phases.new-commit=archived" commit -m "my test archived commit"
1032 test-debug-phase: new rev 1: x -> 32
1022 test-debug-phase: new rev 1: x -> 32
1033 test-hook-close-phase: 8df5997c3361518f733d1ae67cd3adb9b0eaf125: -> archived
1023 test-hook-close-phase: 8df5997c3361518f733d1ae67cd3adb9b0eaf125: -> archived
1034
1024
1035 The changeset is a working parent descendant.
1025 The changeset is a working parent descendant.
1036 Per the usual visibility rules, it is made visible.
1026 Per the usual visibility rules, it is made visible.
1037
1027
1038 $ hg log -G -l 3
1028 $ hg log -G -l 3
1039 @ changeset: 1:8df5997c3361
1029 @ changeset: 1:8df5997c3361
1040 | tag: tip
1030 | tag: tip
1041 | user: test
1031 | user: test
1042 | date: Thu Jan 01 00:00:00 1970 +0000
1032 | date: Thu Jan 01 00:00:00 1970 +0000
1043 | summary: my test archived commit
1033 | summary: my test archived commit
1044 |
1034 |
1045 o changeset: 0:4a2df7238c3b
1035 o changeset: 0:4a2df7238c3b
1046 user: test
1036 user: test
1047 date: Thu Jan 01 00:00:00 1970 +0000
1037 date: Thu Jan 01 00:00:00 1970 +0000
1048 summary: A
1038 summary: A
1049
1039
1050
1040
1051 Commit is hidden as expected
1041 Commit is hidden as expected
1052
1042
1053 $ hg up 0
1043 $ hg up 0
1054 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1044 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1055 $ hg log -G
1045 $ hg log -G
1056 @ changeset: 0:4a2df7238c3b
1046 @ changeset: 0:4a2df7238c3b
1057 tag: tip
1047 tag: tip
1058 user: test
1048 user: test
1059 date: Thu Jan 01 00:00:00 1970 +0000
1049 date: Thu Jan 01 00:00:00 1970 +0000
1060 summary: A
1050 summary: A
1061
1051
1062 $ cd ..
1052 $ cd ..
1063
1053
1064 Recommitting an exact match of a public commit shouldn't change it to
1054 Recommitting an exact match of a public commit shouldn't change it to
1065 draft:
1055 draft:
1066
1056
1067 $ cd initialrepo
1057 $ cd initialrepo
1068 $ hg phase -r 2
1058 $ hg phase -r 2
1069 2: public
1059 2: public
1070 $ hg up -C 1
1060 $ hg up -C 1
1071 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
1061 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
1072 $ mkcommit C
1062 $ mkcommit C
1073 warning: commit already existed in the repository!
1063 warning: commit already existed in the repository!
1074 $ hg phase -r 2
1064 $ hg phase -r 2
1075 2: public
1065 2: public
1076
1066
1077 Same, but for secret:
1067 Same, but for secret:
1078
1068
1079 $ hg up 7
1069 $ hg up 7
1080 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1070 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1081 $ mkcommit F -s
1071 $ mkcommit F -s
1082 test-debug-phase: new rev 8: x -> 2
1072 test-debug-phase: new rev 8: x -> 2
1083 test-hook-close-phase: de414268ec5ce2330c590b942fbb5ff0b0ca1a0a: -> secret
1073 test-hook-close-phase: de414268ec5ce2330c590b942fbb5ff0b0ca1a0a: -> secret
1084 $ hg up 7
1074 $ hg up 7
1085 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1075 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1086 $ hg phase
1076 $ hg phase
1087 7: draft
1077 7: draft
1088 $ mkcommit F
1078 $ mkcommit F
1089 test-debug-phase: new rev 8: x -> 2
1079 test-debug-phase: new rev 8: x -> 2
1090 warning: commit already existed in the repository!
1080 warning: commit already existed in the repository!
1091 test-hook-close-phase: de414268ec5ce2330c590b942fbb5ff0b0ca1a0a: -> secret
1081 test-hook-close-phase: de414268ec5ce2330c590b942fbb5ff0b0ca1a0a: -> secret
1092 $ hg phase -r tip
1082 $ hg phase -r tip
1093 8: secret
1083 8: secret
1094
1084
1095 But what about obsoleted changesets?
1085 But what about obsoleted changesets?
1096
1086
1097 $ hg up 4
1087 $ hg up 4
1098 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1088 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1099 $ mkcommit H
1089 $ mkcommit H
1100 test-debug-phase: new rev 5: x -> 2
1090 test-debug-phase: new rev 5: x -> 2
1101 warning: commit already existed in the repository!
1091 warning: commit already existed in the repository!
1102 test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8: -> secret
1092 test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8: -> secret
1103 $ hg phase -r 5
1093 $ hg phase -r 5
1104 5: secret
1094 5: secret
1105 $ hg par
1095 $ hg par
1106 changeset: 5:a030c6be5127
1096 changeset: 5:a030c6be5127
1107 user: test
1097 user: test
1108 date: Thu Jan 01 00:00:00 1970 +0000
1098 date: Thu Jan 01 00:00:00 1970 +0000
1109 obsolete: pruned
1099 obsolete: pruned
1110 summary: H
1100 summary: H
1111
1101
1112 $ hg up tip
1102 $ hg up tip
1113 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1103 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1114 $ cd ..
1104 $ cd ..
1115
1105
1116 Testing that command line flags override configuration
1106 Testing that command line flags override configuration
1117
1107
1118 $ hg init commit-overrides
1108 $ hg init commit-overrides
1119 $ cd commit-overrides
1109 $ cd commit-overrides
1120
1110
1121 `hg commit --draft` overrides new-commit=secret
1111 `hg commit --draft` overrides new-commit=secret
1122
1112
1123 $ mkcommit A --config phases.new-commit='secret' --draft
1113 $ mkcommit A --config phases.new-commit='secret' --draft
1124 test-debug-phase: new rev 0: x -> 1
1114 test-debug-phase: new rev 0: x -> 1
1125 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> draft
1115 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> draft
1126 $ hglog
1116 $ hglog
1127 @ 0 1 A
1117 @ 0 1 A
1128
1118
1129
1119
1130 `hg commit --secret` overrides new-commit=draft
1120 `hg commit --secret` overrides new-commit=draft
1131
1121
1132 $ mkcommit B --config phases.new-commit='draft' --secret
1122 $ mkcommit B --config phases.new-commit='draft' --secret
1133 test-debug-phase: new rev 1: x -> 2
1123 test-debug-phase: new rev 1: x -> 2
1134 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> secret
1124 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> secret
1135 $ hglog
1125 $ hglog
1136 @ 1 2 B
1126 @ 1 2 B
1137 |
1127 |
1138 o 0 1 A
1128 o 0 1 A
1139
1129
1140
1130
1141 $ cd ..
1131 $ cd ..
@@ -1,204 +1,202 b''
1 #testcases continuecommand continueflag
1 #testcases continuecommand continueflag
2 Rebasing using a single transaction
2 Rebasing using a single transaction
3
3
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [extensions]
5 > [extensions]
6 > rebase=
6 > rebase=
7 > drawdag=$TESTDIR/drawdag.py
7 > drawdag=$TESTDIR/drawdag.py
8 >
8 >
9 > [rebase]
9 > [rebase]
10 > singletransaction=True
10 > singletransaction=True
11 >
11 >
12 > [phases]
12 > [phases]
13 > publish=False
13 > publish=False
14 >
14 >
15 > [alias]
15 > [alias]
16 > tglog = log -G --template "{rev}: {desc}"
16 > tglog = log -G --template "{rev}: {desc}"
17 > EOF
17 > EOF
18
18
19 #if continueflag
19 #if continueflag
20 $ cat >> $HGRCPATH <<EOF
20 $ cat >> $HGRCPATH <<EOF
21 > [alias]
21 > [alias]
22 > continue = rebase --continue
22 > continue = rebase --continue
23 > EOF
23 > EOF
24 #endif
24 #endif
25
25
26 Check that a simple rebase works
26 Check that a simple rebase works
27
27
28 $ hg init simple && cd simple
28 $ hg init simple && cd simple
29 $ hg debugdrawdag <<'EOF'
29 $ hg debugdrawdag <<'EOF'
30 > Z
30 > Z
31 > |
31 > |
32 > | D
32 > | D
33 > | |
33 > | |
34 > | C
34 > | C
35 > | |
35 > | |
36 > Y B
36 > Y B
37 > |/
37 > |/
38 > A
38 > A
39 > EOF
39 > EOF
40 - We should only see one status stored message. It comes from the start.
40 - We should only see one status stored message. It comes from the start.
41 $ hg rebase --debug -b D -d Z | grep 'status stored'
41 $ hg rebase --debug -b D -d Z | grep 'status stored'
42 rebase status stored
42 rebase status stored
43 $ hg tglog
43 $ hg tglog
44 o 5: D
44 o 5: D
45 |
45 |
46 o 4: C
46 o 4: C
47 |
47 |
48 o 3: B
48 o 3: B
49 |
49 |
50 o 2: Z
50 o 2: Z
51 |
51 |
52 o 1: Y
52 o 1: Y
53 |
53 |
54 o 0: A
54 o 0: A
55
55
56 $ cd ..
56 $ cd ..
57
57
58 Check that --collapse works
58 Check that --collapse works
59
59
60 $ hg init collapse && cd collapse
60 $ hg init collapse && cd collapse
61 $ hg debugdrawdag <<'EOF'
61 $ hg debugdrawdag <<'EOF'
62 > Z
62 > Z
63 > |
63 > |
64 > | D
64 > | D
65 > | |
65 > | |
66 > | C
66 > | C
67 > | |
67 > | |
68 > Y B
68 > Y B
69 > |/
69 > |/
70 > A
70 > A
71 > EOF
71 > EOF
72 - We should only see two status stored messages. One from the start, one from
72 - We should only see two status stored messages. One from the start, one from
73 - cmdutil.commitforceeditor() which forces tr.writepending()
73 - cmdutil.commitforceeditor() which forces tr.writepending()
74 $ hg rebase --collapse --debug -b D -d Z | grep 'status stored'
74 $ hg rebase --collapse --debug -b D -d Z | grep 'status stored'
75 rebase status stored
75 rebase status stored
76 rebase status stored
76 rebase status stored
77 $ hg tglog
77 $ hg tglog
78 o 3: Collapsed revision
78 o 3: Collapsed revision
79 | * B
79 | * B
80 | * C
80 | * C
81 | * D
81 | * D
82 o 2: Z
82 o 2: Z
83 |
83 |
84 o 1: Y
84 o 1: Y
85 |
85 |
86 o 0: A
86 o 0: A
87
87
88 $ cd ..
88 $ cd ..
89
89
90 With --collapse, check that conflicts can be resolved and rebase can then be
90 With --collapse, check that conflicts can be resolved and rebase can then be
91 continued
91 continued
92
92
93 $ hg init collapse-conflict && cd collapse-conflict
93 $ hg init collapse-conflict && cd collapse-conflict
94 $ hg debugdrawdag <<'EOF'
94 $ hg debugdrawdag <<'EOF'
95 > Z # Z/conflict=Z
95 > Z # Z/conflict=Z
96 > |
96 > |
97 > | D
97 > | D
98 > | |
98 > | |
99 > | C # C/conflict=C
99 > | C # C/conflict=C
100 > | |
100 > | |
101 > Y B
101 > Y B
102 > |/
102 > |/
103 > A
103 > A
104 > EOF
104 > EOF
105 $ hg rebase --collapse -b D -d Z
105 $ hg rebase --collapse -b D -d Z
106 rebasing 1:112478962961 B "B"
106 rebasing 1:112478962961 B "B"
107 rebasing 3:c26739dbe603 C "C"
107 rebasing 3:c26739dbe603 C "C"
108 merging conflict
108 merging conflict
109 warning: conflicts while merging conflict! (edit, then use 'hg resolve --mark')
109 warning: conflicts while merging conflict! (edit, then use 'hg resolve --mark')
110 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
110 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
111 [240]
111 [240]
112 $ hg tglog
112 $ hg tglog
113 o 5: D
113 o 5: D
114 |
114 |
115 | @ 4: Z
115 | @ 4: Z
116 | |
116 | |
117 % | 3: C
117 % | 3: C
118 | |
118 | |
119 | o 2: Y
119 | o 2: Y
120 | |
120 | |
121 o | 1: B
121 o | 1: B
122 |/
122 |/
123 o 0: A
123 o 0: A
124
124
125 $ hg st
125 $ hg st
126 M conflict
126 M conflict
127 A B
127 A B
128 A C
128 A C
129 ? conflict.orig
129 ? conflict.orig
130 $ echo resolved > conflict
130 $ echo resolved > conflict
131 $ hg resolve -m
131 $ hg resolve -m
132 (no more unresolved files)
132 (no more unresolved files)
133 continue: hg rebase --continue
133 continue: hg rebase --continue
134 $ hg continue
134 $ hg continue
135 already rebased 1:112478962961 B "B" as 79bc8f4973ce
135 already rebased 1:112478962961 B "B" as 79bc8f4973ce
136 rebasing 3:c26739dbe603 C "C"
136 rebasing 3:c26739dbe603 C "C"
137 rebasing 5:d24bb333861c D tip "D"
137 rebasing 5:d24bb333861c D tip "D"
138 saved backup bundle to $TESTTMP/collapse-conflict/.hg/strip-backup/112478962961-b5b34645-rebase.hg
138 saved backup bundle to $TESTTMP/collapse-conflict/.hg/strip-backup/112478962961-b5b34645-rebase.hg
139 $ hg tglog
139 $ hg tglog
140 o 3: Collapsed revision
140 o 3: Collapsed revision
141 | * B
141 | * B
142 | * C
142 | * C
143 | * D
143 | * D
144 o 2: Z
144 o 2: Z
145 |
145 |
146 o 1: Y
146 o 1: Y
147 |
147 |
148 o 0: A
148 o 0: A
149
149
150 $ cd ..
150 $ cd ..
151
151
152 With --collapse, check that the commit message editing can be canceled and
152 With --collapse, check that the commit message editing can be canceled and
153 rebase can then be continued
153 rebase can then be continued
154
154
155 $ hg init collapse-cancel-editor && cd collapse-cancel-editor
155 $ hg init collapse-cancel-editor && cd collapse-cancel-editor
156 $ hg debugdrawdag <<'EOF'
156 $ hg debugdrawdag <<'EOF'
157 > Z
157 > Z
158 > |
158 > |
159 > | D
159 > | D
160 > | |
160 > | |
161 > | C
161 > | C
162 > | |
162 > | |
163 > Y B
163 > Y B
164 > |/
164 > |/
165 > A
165 > A
166 > EOF
166 > EOF
167 $ HGEDITOR=false hg --config ui.interactive=1 rebase --collapse -b D -d Z
167 $ HGEDITOR=false hg --config ui.interactive=1 rebase --collapse -b D -d Z
168 rebasing 1:112478962961 B "B"
168 rebasing 1:112478962961 B "B"
169 rebasing 3:26805aba1e60 C "C"
169 rebasing 3:26805aba1e60 C "C"
170 rebasing 5:f585351a92f8 D tip "D"
170 rebasing 5:f585351a92f8 D tip "D"
171 transaction abort!
172 rollback completed
173 abort: edit failed: false exited with status 1
171 abort: edit failed: false exited with status 1
174 [250]
172 [250]
175 $ hg tglog
173 $ hg tglog
176 o 5: D
174 o 5: D
177 |
175 |
178 | o 4: Z
176 | o 4: Z
179 | |
177 | |
180 o | 3: C
178 o | 3: C
181 | |
179 | |
182 | o 2: Y
180 | o 2: Y
183 | |
181 | |
184 o | 1: B
182 o | 1: B
185 |/
183 |/
186 o 0: A
184 o 0: A
187
185
188 $ hg continue
186 $ hg continue
189 rebasing 1:112478962961 B "B"
187 rebasing 1:112478962961 B "B"
190 rebasing 3:26805aba1e60 C "C"
188 rebasing 3:26805aba1e60 C "C"
191 rebasing 5:f585351a92f8 D tip "D"
189 rebasing 5:f585351a92f8 D tip "D"
192 saved backup bundle to $TESTTMP/collapse-cancel-editor/.hg/strip-backup/112478962961-cb2a9b47-rebase.hg
190 saved backup bundle to $TESTTMP/collapse-cancel-editor/.hg/strip-backup/112478962961-cb2a9b47-rebase.hg
193 $ hg tglog
191 $ hg tglog
194 o 3: Collapsed revision
192 o 3: Collapsed revision
195 | * B
193 | * B
196 | * C
194 | * C
197 | * D
195 | * D
198 o 2: Z
196 o 2: Z
199 |
197 |
200 o 1: Y
198 o 1: Y
201 |
199 |
202 o 0: A
200 o 0: A
203
201
204 $ cd ..
202 $ cd ..
@@ -1,292 +1,288 b''
1 #testcases vfs svfs
1 #testcases vfs svfs
2 #testcases safe normal
2 #testcases safe normal
3
3
4 #if safe
4 #if safe
5 $ echo "[format]" >> $HGRCPATH
5 $ echo "[format]" >> $HGRCPATH
6 $ echo "use-share-safe = True" >> $HGRCPATH
6 $ echo "use-share-safe = True" >> $HGRCPATH
7 #endif
7 #endif
8
8
9 $ echo "[extensions]" >> $HGRCPATH
9 $ echo "[extensions]" >> $HGRCPATH
10 $ echo "share = " >> $HGRCPATH
10 $ echo "share = " >> $HGRCPATH
11
11
12 #if svfs
12 #if svfs
13 $ echo "[format]" >> $HGRCPATH
13 $ echo "[format]" >> $HGRCPATH
14 $ echo "bookmarks-in-store = yes " >> $HGRCPATH
14 $ echo "bookmarks-in-store = yes " >> $HGRCPATH
15 #endif
15 #endif
16
16
17 prepare repo1
17 prepare repo1
18
18
19 $ hg init repo1
19 $ hg init repo1
20 $ cd repo1
20 $ cd repo1
21 $ echo a > a
21 $ echo a > a
22 $ hg commit -A -m'init'
22 $ hg commit -A -m'init'
23 adding a
23 adding a
24 $ echo a >> a
24 $ echo a >> a
25 $ hg commit -m'change in shared clone'
25 $ hg commit -m'change in shared clone'
26 $ echo b > b
26 $ echo b > b
27 $ hg commit -A -m'another file'
27 $ hg commit -A -m'another file'
28 adding b
28 adding b
29
29
30 share it
30 share it
31
31
32 $ cd ..
32 $ cd ..
33 $ hg share repo1 repo2
33 $ hg share repo1 repo2
34 updating working directory
34 updating working directory
35 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
35 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
36
36
37 test sharing bookmarks
37 test sharing bookmarks
38
38
39 $ hg share -B repo1 repo3
39 $ hg share -B repo1 repo3
40 updating working directory
40 updating working directory
41 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
41 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 $ cd repo1
42 $ cd repo1
43 $ hg bookmark bm1
43 $ hg bookmark bm1
44 $ hg bookmarks
44 $ hg bookmarks
45 * bm1 2:c2e0ac586386
45 * bm1 2:c2e0ac586386
46 $ cd ../repo2
46 $ cd ../repo2
47 $ hg book bm2
47 $ hg book bm2
48 $ hg bookmarks
48 $ hg bookmarks
49 bm1 2:c2e0ac586386 (svfs !)
49 bm1 2:c2e0ac586386 (svfs !)
50 * bm2 2:c2e0ac586386
50 * bm2 2:c2e0ac586386
51 $ cd ../repo3
51 $ cd ../repo3
52 $ hg bookmarks
52 $ hg bookmarks
53 bm1 2:c2e0ac586386
53 bm1 2:c2e0ac586386
54 bm2 2:c2e0ac586386 (svfs !)
54 bm2 2:c2e0ac586386 (svfs !)
55 $ hg book bm3
55 $ hg book bm3
56 $ hg bookmarks
56 $ hg bookmarks
57 bm1 2:c2e0ac586386
57 bm1 2:c2e0ac586386
58 bm2 2:c2e0ac586386 (svfs !)
58 bm2 2:c2e0ac586386 (svfs !)
59 * bm3 2:c2e0ac586386
59 * bm3 2:c2e0ac586386
60 $ cd ../repo1
60 $ cd ../repo1
61 $ hg bookmarks
61 $ hg bookmarks
62 * bm1 2:c2e0ac586386
62 * bm1 2:c2e0ac586386
63 bm2 2:c2e0ac586386 (svfs !)
63 bm2 2:c2e0ac586386 (svfs !)
64 bm3 2:c2e0ac586386
64 bm3 2:c2e0ac586386
65
65
66 check whether HG_PENDING makes pending changes only in relatd
66 check whether HG_PENDING makes pending changes only in relatd
67 repositories visible to an external hook.
67 repositories visible to an external hook.
68
68
69 In "hg share" case, another transaction can't run in other
69 In "hg share" case, another transaction can't run in other
70 repositories sharing same source repository, because starting
70 repositories sharing same source repository, because starting
71 transaction requires locking store of source repository.
71 transaction requires locking store of source repository.
72
72
73 Therefore, this test scenario ignores checking visibility of
73 Therefore, this test scenario ignores checking visibility of
74 .hg/bookmarks.pending in repo2, which shares repo1 without bookmarks.
74 .hg/bookmarks.pending in repo2, which shares repo1 without bookmarks.
75
75
76 $ cat > $TESTTMP/checkbookmarks.sh <<EOF
76 $ cat > $TESTTMP/checkbookmarks.sh <<EOF
77 > echo "@repo1"
77 > echo "@repo1"
78 > hg -R "$TESTTMP/repo1" bookmarks
78 > hg -R "$TESTTMP/repo1" bookmarks
79 > echo "@repo2"
79 > echo "@repo2"
80 > hg -R "$TESTTMP/repo2" bookmarks
80 > hg -R "$TESTTMP/repo2" bookmarks
81 > echo "@repo3"
81 > echo "@repo3"
82 > hg -R "$TESTTMP/repo3" bookmarks
82 > hg -R "$TESTTMP/repo3" bookmarks
83 > exit 1 # to avoid adding new bookmark for subsequent tests
83 > exit 1 # to avoid adding new bookmark for subsequent tests
84 > EOF
84 > EOF
85
85
86 $ cd ../repo1
86 $ cd ../repo1
87 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
87 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
88 @repo1
88 @repo1
89 bm1 2:c2e0ac586386
89 bm1 2:c2e0ac586386
90 bm2 2:c2e0ac586386 (svfs !)
90 bm2 2:c2e0ac586386 (svfs !)
91 bm3 2:c2e0ac586386
91 bm3 2:c2e0ac586386
92 * bmX 2:c2e0ac586386
92 * bmX 2:c2e0ac586386
93 @repo2
93 @repo2
94 bm1 2:c2e0ac586386 (svfs !)
94 bm1 2:c2e0ac586386 (svfs !)
95 * bm2 2:c2e0ac586386
95 * bm2 2:c2e0ac586386
96 bm3 2:c2e0ac586386 (svfs !)
96 bm3 2:c2e0ac586386 (svfs !)
97 @repo3
97 @repo3
98 bm1 2:c2e0ac586386
98 bm1 2:c2e0ac586386
99 bm2 2:c2e0ac586386 (svfs !)
99 bm2 2:c2e0ac586386 (svfs !)
100 * bm3 2:c2e0ac586386
100 * bm3 2:c2e0ac586386
101 bmX 2:c2e0ac586386 (vfs !)
101 bmX 2:c2e0ac586386 (vfs !)
102 transaction abort!
103 rollback completed
104 abort: pretxnclose hook exited with status 1
102 abort: pretxnclose hook exited with status 1
105 [40]
103 [40]
106 $ hg book bm1
104 $ hg book bm1
107
105
108 FYI, in contrast to above test, bmX is invisible in repo1 (= shared
106 FYI, in contrast to above test, bmX is invisible in repo1 (= shared
109 src), because (1) HG_PENDING refers only repo3 and (2)
107 src), because (1) HG_PENDING refers only repo3 and (2)
110 "bookmarks.pending" is written only into repo3.
108 "bookmarks.pending" is written only into repo3.
111
109
112 $ cd ../repo3
110 $ cd ../repo3
113 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
111 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
114 @repo1
112 @repo1
115 * bm1 2:c2e0ac586386
113 * bm1 2:c2e0ac586386
116 bm2 2:c2e0ac586386 (svfs !)
114 bm2 2:c2e0ac586386 (svfs !)
117 bm3 2:c2e0ac586386
115 bm3 2:c2e0ac586386
118 @repo2
116 @repo2
119 bm1 2:c2e0ac586386 (svfs !)
117 bm1 2:c2e0ac586386 (svfs !)
120 * bm2 2:c2e0ac586386
118 * bm2 2:c2e0ac586386
121 bm3 2:c2e0ac586386 (svfs !)
119 bm3 2:c2e0ac586386 (svfs !)
122 @repo3
120 @repo3
123 bm1 2:c2e0ac586386
121 bm1 2:c2e0ac586386
124 bm2 2:c2e0ac586386 (svfs !)
122 bm2 2:c2e0ac586386 (svfs !)
125 bm3 2:c2e0ac586386
123 bm3 2:c2e0ac586386
126 * bmX 2:c2e0ac586386
124 * bmX 2:c2e0ac586386
127 transaction abort!
128 rollback completed
129 abort: pretxnclose hook exited with status 1
125 abort: pretxnclose hook exited with status 1
130 [40]
126 [40]
131 $ hg book bm3
127 $ hg book bm3
132
128
133 clean up bm2 since it's uninteresting (not shared in the vfs case and
129 clean up bm2 since it's uninteresting (not shared in the vfs case and
134 same as bm3 in the svfs case)
130 same as bm3 in the svfs case)
135 $ cd ../repo2
131 $ cd ../repo2
136 $ hg book -d bm2
132 $ hg book -d bm2
137
133
138 $ cd ../repo1
134 $ cd ../repo1
139
135
140 test that commits work
136 test that commits work
141
137
142 $ echo 'shared bookmarks' > a
138 $ echo 'shared bookmarks' > a
143 $ hg commit -m 'testing shared bookmarks'
139 $ hg commit -m 'testing shared bookmarks'
144 $ hg bookmarks
140 $ hg bookmarks
145 * bm1 3:b87954705719
141 * bm1 3:b87954705719
146 bm3 2:c2e0ac586386
142 bm3 2:c2e0ac586386
147 $ cd ../repo3
143 $ cd ../repo3
148 $ hg bookmarks
144 $ hg bookmarks
149 bm1 3:b87954705719
145 bm1 3:b87954705719
150 * bm3 2:c2e0ac586386
146 * bm3 2:c2e0ac586386
151 $ echo 'more shared bookmarks' > a
147 $ echo 'more shared bookmarks' > a
152 $ hg commit -m 'testing shared bookmarks'
148 $ hg commit -m 'testing shared bookmarks'
153 created new head
149 created new head
154 $ hg bookmarks
150 $ hg bookmarks
155 bm1 3:b87954705719
151 bm1 3:b87954705719
156 * bm3 4:62f4ded848e4
152 * bm3 4:62f4ded848e4
157 $ cd ../repo1
153 $ cd ../repo1
158 $ hg bookmarks
154 $ hg bookmarks
159 * bm1 3:b87954705719
155 * bm1 3:b87954705719
160 bm3 4:62f4ded848e4
156 bm3 4:62f4ded848e4
161 $ cd ..
157 $ cd ..
162
158
163 test pushing bookmarks works
159 test pushing bookmarks works
164
160
165 $ hg clone repo3 repo4
161 $ hg clone repo3 repo4
166 updating to branch default
162 updating to branch default
167 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
163 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
168 $ cd repo4
164 $ cd repo4
169 $ hg boo bm4
165 $ hg boo bm4
170 $ echo foo > b
166 $ echo foo > b
171 $ hg commit -m 'foo in b'
167 $ hg commit -m 'foo in b'
172 $ hg boo
168 $ hg boo
173 bm1 3:b87954705719
169 bm1 3:b87954705719
174 bm3 4:62f4ded848e4
170 bm3 4:62f4ded848e4
175 * bm4 5:92793bfc8cad
171 * bm4 5:92793bfc8cad
176 $ hg push -B bm4
172 $ hg push -B bm4
177 pushing to $TESTTMP/repo3
173 pushing to $TESTTMP/repo3
178 searching for changes
174 searching for changes
179 adding changesets
175 adding changesets
180 adding manifests
176 adding manifests
181 adding file changes
177 adding file changes
182 added 1 changesets with 1 changes to 1 files
178 added 1 changesets with 1 changes to 1 files
183 exporting bookmark bm4
179 exporting bookmark bm4
184 $ cd ../repo1
180 $ cd ../repo1
185 $ hg bookmarks
181 $ hg bookmarks
186 * bm1 3:b87954705719
182 * bm1 3:b87954705719
187 bm3 4:62f4ded848e4
183 bm3 4:62f4ded848e4
188 bm4 5:92793bfc8cad
184 bm4 5:92793bfc8cad
189 $ cd ../repo3
185 $ cd ../repo3
190 $ hg bookmarks
186 $ hg bookmarks
191 bm1 3:b87954705719
187 bm1 3:b87954705719
192 * bm3 4:62f4ded848e4
188 * bm3 4:62f4ded848e4
193 bm4 5:92793bfc8cad
189 bm4 5:92793bfc8cad
194 $ cd ..
190 $ cd ..
195
191
196 test behavior when sharing a shared repo
192 test behavior when sharing a shared repo
197
193
198 $ hg share -B repo3 missingdir/repo5
194 $ hg share -B repo3 missingdir/repo5
199 updating working directory
195 updating working directory
200 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
196 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
201 $ cd missingdir/repo5
197 $ cd missingdir/repo5
202 $ hg book
198 $ hg book
203 bm1 3:b87954705719
199 bm1 3:b87954705719
204 bm3 4:62f4ded848e4
200 bm3 4:62f4ded848e4
205 bm4 5:92793bfc8cad
201 bm4 5:92793bfc8cad
206 $ cd ../..
202 $ cd ../..
207
203
208 test what happens when an active bookmark is deleted
204 test what happens when an active bookmark is deleted
209
205
210 $ cd repo1
206 $ cd repo1
211 $ hg boo -d bm3
207 $ hg boo -d bm3
212 $ hg boo
208 $ hg boo
213 * bm1 3:b87954705719
209 * bm1 3:b87954705719
214 bm4 5:92793bfc8cad
210 bm4 5:92793bfc8cad
215 $ cd ../repo3
211 $ cd ../repo3
216 $ hg boo
212 $ hg boo
217 bm1 3:b87954705719
213 bm1 3:b87954705719
218 bm4 5:92793bfc8cad
214 bm4 5:92793bfc8cad
219 $ cd ..
215 $ cd ..
220
216
221 verify that bookmarks are not written on failed transaction
217 verify that bookmarks are not written on failed transaction
222
218
223 $ cat > failpullbookmarks.py << EOF
219 $ cat > failpullbookmarks.py << EOF
224 > """A small extension that makes bookmark pulls fail, for testing"""
220 > """A small extension that makes bookmark pulls fail, for testing"""
225 > from mercurial import (
221 > from mercurial import (
226 > error,
222 > error,
227 > exchange,
223 > exchange,
228 > extensions,
224 > extensions,
229 > )
225 > )
230 > def _pullbookmarks(orig, pullop):
226 > def _pullbookmarks(orig, pullop):
231 > orig(pullop)
227 > orig(pullop)
232 > raise error.HookAbort(b'forced failure by extension')
228 > raise error.HookAbort(b'forced failure by extension')
233 > def extsetup(ui):
229 > def extsetup(ui):
234 > extensions.wrapfunction(exchange, '_pullbookmarks', _pullbookmarks)
230 > extensions.wrapfunction(exchange, '_pullbookmarks', _pullbookmarks)
235 > EOF
231 > EOF
236 $ cd repo4
232 $ cd repo4
237 $ hg boo
233 $ hg boo
238 bm1 3:b87954705719
234 bm1 3:b87954705719
239 bm3 4:62f4ded848e4
235 bm3 4:62f4ded848e4
240 * bm4 5:92793bfc8cad
236 * bm4 5:92793bfc8cad
241 $ cd ../repo3
237 $ cd ../repo3
242 $ hg boo
238 $ hg boo
243 bm1 3:b87954705719
239 bm1 3:b87954705719
244 bm4 5:92793bfc8cad
240 bm4 5:92793bfc8cad
245 $ hg --config "extensions.failpullbookmarks=$TESTTMP/failpullbookmarks.py" pull $TESTTMP/repo4
241 $ hg --config "extensions.failpullbookmarks=$TESTTMP/failpullbookmarks.py" pull $TESTTMP/repo4
246 pulling from $TESTTMP/repo4
242 pulling from $TESTTMP/repo4
247 searching for changes
243 searching for changes
248 no changes found
244 no changes found
249 adding remote bookmark bm3
245 adding remote bookmark bm3
250 abort: forced failure by extension
246 abort: forced failure by extension
251 [40]
247 [40]
252 $ hg boo
248 $ hg boo
253 bm1 3:b87954705719
249 bm1 3:b87954705719
254 bm4 5:92793bfc8cad
250 bm4 5:92793bfc8cad
255 $ hg pull $TESTTMP/repo4
251 $ hg pull $TESTTMP/repo4
256 pulling from $TESTTMP/repo4
252 pulling from $TESTTMP/repo4
257 searching for changes
253 searching for changes
258 no changes found
254 no changes found
259 adding remote bookmark bm3
255 adding remote bookmark bm3
260 1 local changesets published
256 1 local changesets published
261 $ hg boo
257 $ hg boo
262 bm1 3:b87954705719
258 bm1 3:b87954705719
263 * bm3 4:62f4ded848e4
259 * bm3 4:62f4ded848e4
264 bm4 5:92793bfc8cad
260 bm4 5:92793bfc8cad
265 $ cd ..
261 $ cd ..
266
262
267 verify bookmark behavior after unshare
263 verify bookmark behavior after unshare
268
264
269 $ cd repo3
265 $ cd repo3
270 $ hg unshare
266 $ hg unshare
271 $ hg boo
267 $ hg boo
272 bm1 3:b87954705719
268 bm1 3:b87954705719
273 * bm3 4:62f4ded848e4
269 * bm3 4:62f4ded848e4
274 bm4 5:92793bfc8cad
270 bm4 5:92793bfc8cad
275 $ hg boo -d bm4
271 $ hg boo -d bm4
276 $ hg boo bm5
272 $ hg boo bm5
277 $ hg boo
273 $ hg boo
278 bm1 3:b87954705719
274 bm1 3:b87954705719
279 bm3 4:62f4ded848e4
275 bm3 4:62f4ded848e4
280 * bm5 4:62f4ded848e4
276 * bm5 4:62f4ded848e4
281 $ cd ../repo1
277 $ cd ../repo1
282 $ hg boo
278 $ hg boo
283 * bm1 3:b87954705719
279 * bm1 3:b87954705719
284 bm3 4:62f4ded848e4
280 bm3 4:62f4ded848e4
285 bm4 5:92793bfc8cad
281 bm4 5:92793bfc8cad
286 $ cd ..
282 $ cd ..
287
283
288 Test that if store is disabled, we drop the bookmarksinstore requirement
284 Test that if store is disabled, we drop the bookmarksinstore requirement
289
285
290 $ hg init brokenrepo --config format.bookmarks-in-store=True --config format.usestore=false
286 $ hg init brokenrepo --config format.bookmarks-in-store=True --config format.usestore=false
291 ignoring enabled 'format.bookmarks-in-store' config beacuse it is incompatible with disabled 'format.usestore' config
287 ignoring enabled 'format.bookmarks-in-store' config beacuse it is incompatible with disabled 'format.usestore' config
292 ignoring enabled 'format.use-share-safe' config because it is incompatible with disabled 'format.usestore' config (safe !)
288 ignoring enabled 'format.use-share-safe' config because it is incompatible with disabled 'format.usestore' config (safe !)
@@ -1,1148 +1,1146 b''
1 #testcases obsstore-on obsstore-off
1 #testcases obsstore-on obsstore-off
2
2
3 $ cat > $TESTTMP/editor.py <<EOF
3 $ cat > $TESTTMP/editor.py <<EOF
4 > #!"$PYTHON"
4 > #!"$PYTHON"
5 > import os
5 > import os
6 > import sys
6 > import sys
7 > path = os.path.join(os.environ['TESTTMP'], 'messages')
7 > path = os.path.join(os.environ['TESTTMP'], 'messages')
8 > messages = open(path).read().split('--\n')
8 > messages = open(path).read().split('--\n')
9 > prompt = open(sys.argv[1]).read()
9 > prompt = open(sys.argv[1]).read()
10 > sys.stdout.write(''.join('EDITOR: %s' % l for l in prompt.splitlines(True)))
10 > sys.stdout.write(''.join('EDITOR: %s' % l for l in prompt.splitlines(True)))
11 > sys.stdout.flush()
11 > sys.stdout.flush()
12 > with open(sys.argv[1], 'w') as f:
12 > with open(sys.argv[1], 'w') as f:
13 > f.write(messages[0])
13 > f.write(messages[0])
14 > with open(path, 'w') as f:
14 > with open(path, 'w') as f:
15 > f.write('--\n'.join(messages[1:]))
15 > f.write('--\n'.join(messages[1:]))
16 > EOF
16 > EOF
17
17
18 $ cat >> $HGRCPATH <<EOF
18 $ cat >> $HGRCPATH <<EOF
19 > [extensions]
19 > [extensions]
20 > drawdag=$TESTDIR/drawdag.py
20 > drawdag=$TESTDIR/drawdag.py
21 > split=
21 > split=
22 > [ui]
22 > [ui]
23 > interactive=1
23 > interactive=1
24 > color=no
24 > color=no
25 > paginate=never
25 > paginate=never
26 > [diff]
26 > [diff]
27 > git=1
27 > git=1
28 > unified=0
28 > unified=0
29 > [commands]
29 > [commands]
30 > commit.interactive.unified=0
30 > commit.interactive.unified=0
31 > [alias]
31 > [alias]
32 > glog=log -G -T '{rev}:{node|short} {desc} {bookmarks}\n'
32 > glog=log -G -T '{rev}:{node|short} {desc} {bookmarks}\n'
33 > EOF
33 > EOF
34
34
35 #if obsstore-on
35 #if obsstore-on
36 $ cat >> $HGRCPATH <<EOF
36 $ cat >> $HGRCPATH <<EOF
37 > [experimental]
37 > [experimental]
38 > evolution=all
38 > evolution=all
39 > EOF
39 > EOF
40 #endif
40 #endif
41
41
42 $ hg init a
42 $ hg init a
43 $ cd a
43 $ cd a
44
44
45 Nothing to split
45 Nothing to split
46
46
47 $ hg split
47 $ hg split
48 nothing to split
48 nothing to split
49 [1]
49 [1]
50
50
51 $ hg commit -m empty --config ui.allowemptycommit=1
51 $ hg commit -m empty --config ui.allowemptycommit=1
52 $ hg split
52 $ hg split
53 abort: cannot split an empty revision
53 abort: cannot split an empty revision
54 [10]
54 [10]
55
55
56 $ rm -rf .hg
56 $ rm -rf .hg
57 $ hg init
57 $ hg init
58
58
59 Cannot split working directory
59 Cannot split working directory
60
60
61 $ hg split -r 'wdir()'
61 $ hg split -r 'wdir()'
62 abort: cannot split working directory
62 abort: cannot split working directory
63 [10]
63 [10]
64
64
65 Generate some content. The sed filter drop CR on Windows, which is dropped in
65 Generate some content. The sed filter drop CR on Windows, which is dropped in
66 the a > b line.
66 the a > b line.
67
67
68 $ $TESTDIR/seq.py 1 5 | sed 's/\r$//' >> a
68 $ $TESTDIR/seq.py 1 5 | sed 's/\r$//' >> a
69 $ hg ci -m a1 -A a -q
69 $ hg ci -m a1 -A a -q
70 $ hg bookmark -i r1
70 $ hg bookmark -i r1
71 $ sed 's/1/11/;s/3/33/;s/5/55/' a > b
71 $ sed 's/1/11/;s/3/33/;s/5/55/' a > b
72 $ mv b a
72 $ mv b a
73 $ hg ci -m a2 -q
73 $ hg ci -m a2 -q
74 $ hg bookmark -i r2
74 $ hg bookmark -i r2
75
75
76 Cannot split a public changeset
76 Cannot split a public changeset
77
77
78 $ hg phase --public -r 'all()'
78 $ hg phase --public -r 'all()'
79 $ hg split .
79 $ hg split .
80 abort: cannot split public changesets: 1df0d5c5a3ab
80 abort: cannot split public changesets: 1df0d5c5a3ab
81 (see 'hg help phases' for details)
81 (see 'hg help phases' for details)
82 [10]
82 [10]
83
83
84 $ hg phase --draft -f -r 'all()'
84 $ hg phase --draft -f -r 'all()'
85
85
86 Cannot split while working directory is dirty
86 Cannot split while working directory is dirty
87
87
88 $ touch dirty
88 $ touch dirty
89 $ hg add dirty
89 $ hg add dirty
90 $ hg split .
90 $ hg split .
91 abort: uncommitted changes
91 abort: uncommitted changes
92 [20]
92 [20]
93 $ hg forget dirty
93 $ hg forget dirty
94 $ rm dirty
94 $ rm dirty
95
95
96 Make a clean directory for future tests to build off of
96 Make a clean directory for future tests to build off of
97
97
98 $ cp -R . ../clean
98 $ cp -R . ../clean
99
99
100 Split a head
100 Split a head
101
101
102 $ hg bookmark r3
102 $ hg bookmark r3
103
103
104 $ hg split 'all()'
104 $ hg split 'all()'
105 abort: cannot split multiple revisions
105 abort: cannot split multiple revisions
106 [10]
106 [10]
107
107
108 This function splits a bit strangely primarily to avoid changing the behavior of
108 This function splits a bit strangely primarily to avoid changing the behavior of
109 the test after a bug was fixed with how split/commit --interactive handled
109 the test after a bug was fixed with how split/commit --interactive handled
110 `commands.commit.interactive.unified=0`: when there were no context lines,
110 `commands.commit.interactive.unified=0`: when there were no context lines,
111 it kept only the last diff hunk. When running split, this meant that runsplit
111 it kept only the last diff hunk. When running split, this meant that runsplit
112 was always recording three commits, one for each diff hunk, in reverse order
112 was always recording three commits, one for each diff hunk, in reverse order
113 (the base commit was the last diff hunk in the file).
113 (the base commit was the last diff hunk in the file).
114 $ runsplit() {
114 $ runsplit() {
115 > cat > $TESTTMP/messages <<EOF
115 > cat > $TESTTMP/messages <<EOF
116 > split 1
116 > split 1
117 > --
117 > --
118 > split 2
118 > split 2
119 > --
119 > --
120 > split 3
120 > split 3
121 > EOF
121 > EOF
122 > cat <<EOF | hg split "$@"
122 > cat <<EOF | hg split "$@"
123 > y
123 > y
124 > n
124 > n
125 > n
125 > n
126 > y
126 > y
127 > y
127 > y
128 > n
128 > n
129 > y
129 > y
130 > y
130 > y
131 > y
131 > y
132 > EOF
132 > EOF
133 > }
133 > }
134
134
135 $ HGEDITOR=false runsplit
135 $ HGEDITOR=false runsplit
136 diff --git a/a b/a
136 diff --git a/a b/a
137 3 hunks, 3 lines changed
137 3 hunks, 3 lines changed
138 examine changes to 'a'?
138 examine changes to 'a'?
139 (enter ? for help) [Ynesfdaq?] y
139 (enter ? for help) [Ynesfdaq?] y
140
140
141 @@ -1,1 +1,1 @@
141 @@ -1,1 +1,1 @@
142 -1
142 -1
143 +11
143 +11
144 record change 1/3 to 'a'?
144 record change 1/3 to 'a'?
145 (enter ? for help) [Ynesfdaq?] n
145 (enter ? for help) [Ynesfdaq?] n
146
146
147 @@ -3,1 +3,1 @@ 2
147 @@ -3,1 +3,1 @@ 2
148 -3
148 -3
149 +33
149 +33
150 record change 2/3 to 'a'?
150 record change 2/3 to 'a'?
151 (enter ? for help) [Ynesfdaq?] n
151 (enter ? for help) [Ynesfdaq?] n
152
152
153 @@ -5,1 +5,1 @@ 4
153 @@ -5,1 +5,1 @@ 4
154 -5
154 -5
155 +55
155 +55
156 record change 3/3 to 'a'?
156 record change 3/3 to 'a'?
157 (enter ? for help) [Ynesfdaq?] y
157 (enter ? for help) [Ynesfdaq?] y
158
158
159 transaction abort!
160 rollback completed
161 abort: edit failed: false exited with status 1
159 abort: edit failed: false exited with status 1
162 [250]
160 [250]
163 $ hg status
161 $ hg status
164
162
165 $ HGEDITOR="\"$PYTHON\" $TESTTMP/editor.py"
163 $ HGEDITOR="\"$PYTHON\" $TESTTMP/editor.py"
166 $ runsplit
164 $ runsplit
167 diff --git a/a b/a
165 diff --git a/a b/a
168 3 hunks, 3 lines changed
166 3 hunks, 3 lines changed
169 examine changes to 'a'?
167 examine changes to 'a'?
170 (enter ? for help) [Ynesfdaq?] y
168 (enter ? for help) [Ynesfdaq?] y
171
169
172 @@ -1,1 +1,1 @@
170 @@ -1,1 +1,1 @@
173 -1
171 -1
174 +11
172 +11
175 record change 1/3 to 'a'?
173 record change 1/3 to 'a'?
176 (enter ? for help) [Ynesfdaq?] n
174 (enter ? for help) [Ynesfdaq?] n
177
175
178 @@ -3,1 +3,1 @@ 2
176 @@ -3,1 +3,1 @@ 2
179 -3
177 -3
180 +33
178 +33
181 record change 2/3 to 'a'?
179 record change 2/3 to 'a'?
182 (enter ? for help) [Ynesfdaq?] n
180 (enter ? for help) [Ynesfdaq?] n
183
181
184 @@ -5,1 +5,1 @@ 4
182 @@ -5,1 +5,1 @@ 4
185 -5
183 -5
186 +55
184 +55
187 record change 3/3 to 'a'?
185 record change 3/3 to 'a'?
188 (enter ? for help) [Ynesfdaq?] y
186 (enter ? for help) [Ynesfdaq?] y
189
187
190 EDITOR: HG: Splitting 1df0d5c5a3ab. Write commit message for the first split changeset.
188 EDITOR: HG: Splitting 1df0d5c5a3ab. Write commit message for the first split changeset.
191 EDITOR: a2
189 EDITOR: a2
192 EDITOR:
190 EDITOR:
193 EDITOR:
191 EDITOR:
194 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
192 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
195 EDITOR: HG: Leave message empty to abort commit.
193 EDITOR: HG: Leave message empty to abort commit.
196 EDITOR: HG: --
194 EDITOR: HG: --
197 EDITOR: HG: user: test
195 EDITOR: HG: user: test
198 EDITOR: HG: branch 'default'
196 EDITOR: HG: branch 'default'
199 EDITOR: HG: changed a
197 EDITOR: HG: changed a
200 created new head
198 created new head
201 diff --git a/a b/a
199 diff --git a/a b/a
202 2 hunks, 2 lines changed
200 2 hunks, 2 lines changed
203 examine changes to 'a'?
201 examine changes to 'a'?
204 (enter ? for help) [Ynesfdaq?] y
202 (enter ? for help) [Ynesfdaq?] y
205
203
206 @@ -1,1 +1,1 @@
204 @@ -1,1 +1,1 @@
207 -1
205 -1
208 +11
206 +11
209 record change 1/2 to 'a'?
207 record change 1/2 to 'a'?
210 (enter ? for help) [Ynesfdaq?] n
208 (enter ? for help) [Ynesfdaq?] n
211
209
212 @@ -3,1 +3,1 @@ 2
210 @@ -3,1 +3,1 @@ 2
213 -3
211 -3
214 +33
212 +33
215 record change 2/2 to 'a'?
213 record change 2/2 to 'a'?
216 (enter ? for help) [Ynesfdaq?] y
214 (enter ? for help) [Ynesfdaq?] y
217
215
218 EDITOR: HG: Splitting 1df0d5c5a3ab. So far it has been split into:
216 EDITOR: HG: Splitting 1df0d5c5a3ab. So far it has been split into:
219 EDITOR: HG: - 2:e704349bd21b tip "split 1"
217 EDITOR: HG: - 2:e704349bd21b tip "split 1"
220 EDITOR: HG: Write commit message for the next split changeset.
218 EDITOR: HG: Write commit message for the next split changeset.
221 EDITOR: a2
219 EDITOR: a2
222 EDITOR:
220 EDITOR:
223 EDITOR:
221 EDITOR:
224 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
222 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
225 EDITOR: HG: Leave message empty to abort commit.
223 EDITOR: HG: Leave message empty to abort commit.
226 EDITOR: HG: --
224 EDITOR: HG: --
227 EDITOR: HG: user: test
225 EDITOR: HG: user: test
228 EDITOR: HG: branch 'default'
226 EDITOR: HG: branch 'default'
229 EDITOR: HG: changed a
227 EDITOR: HG: changed a
230 diff --git a/a b/a
228 diff --git a/a b/a
231 1 hunks, 1 lines changed
229 1 hunks, 1 lines changed
232 examine changes to 'a'?
230 examine changes to 'a'?
233 (enter ? for help) [Ynesfdaq?] y
231 (enter ? for help) [Ynesfdaq?] y
234
232
235 @@ -1,1 +1,1 @@
233 @@ -1,1 +1,1 @@
236 -1
234 -1
237 +11
235 +11
238 record this change to 'a'?
236 record this change to 'a'?
239 (enter ? for help) [Ynesfdaq?] y
237 (enter ? for help) [Ynesfdaq?] y
240
238
241 EDITOR: HG: Splitting 1df0d5c5a3ab. So far it has been split into:
239 EDITOR: HG: Splitting 1df0d5c5a3ab. So far it has been split into:
242 EDITOR: HG: - 2:e704349bd21b tip "split 1"
240 EDITOR: HG: - 2:e704349bd21b tip "split 1"
243 EDITOR: HG: - 3:a09ad58faae3 "split 2"
241 EDITOR: HG: - 3:a09ad58faae3 "split 2"
244 EDITOR: HG: Write commit message for the next split changeset.
242 EDITOR: HG: Write commit message for the next split changeset.
245 EDITOR: a2
243 EDITOR: a2
246 EDITOR:
244 EDITOR:
247 EDITOR:
245 EDITOR:
248 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
246 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
249 EDITOR: HG: Leave message empty to abort commit.
247 EDITOR: HG: Leave message empty to abort commit.
250 EDITOR: HG: --
248 EDITOR: HG: --
251 EDITOR: HG: user: test
249 EDITOR: HG: user: test
252 EDITOR: HG: branch 'default'
250 EDITOR: HG: branch 'default'
253 EDITOR: HG: changed a
251 EDITOR: HG: changed a
254 saved backup bundle to $TESTTMP/a/.hg/strip-backup/1df0d5c5a3ab-8341b760-split.hg (obsstore-off !)
252 saved backup bundle to $TESTTMP/a/.hg/strip-backup/1df0d5c5a3ab-8341b760-split.hg (obsstore-off !)
255
253
256 #if obsstore-off
254 #if obsstore-off
257 $ hg bookmark
255 $ hg bookmark
258 r1 0:a61bcde8c529
256 r1 0:a61bcde8c529
259 r2 3:00eebaf8d2e2
257 r2 3:00eebaf8d2e2
260 * r3 3:00eebaf8d2e2
258 * r3 3:00eebaf8d2e2
261 $ hg glog -p
259 $ hg glog -p
262 @ 3:00eebaf8d2e2 split 3 r2 r3
260 @ 3:00eebaf8d2e2 split 3 r2 r3
263 | diff --git a/a b/a
261 | diff --git a/a b/a
264 | --- a/a
262 | --- a/a
265 | +++ b/a
263 | +++ b/a
266 | @@ -1,1 +1,1 @@
264 | @@ -1,1 +1,1 @@
267 | -1
265 | -1
268 | +11
266 | +11
269 |
267 |
270 o 2:a09ad58faae3 split 2
268 o 2:a09ad58faae3 split 2
271 | diff --git a/a b/a
269 | diff --git a/a b/a
272 | --- a/a
270 | --- a/a
273 | +++ b/a
271 | +++ b/a
274 | @@ -3,1 +3,1 @@
272 | @@ -3,1 +3,1 @@
275 | -3
273 | -3
276 | +33
274 | +33
277 |
275 |
278 o 1:e704349bd21b split 1
276 o 1:e704349bd21b split 1
279 | diff --git a/a b/a
277 | diff --git a/a b/a
280 | --- a/a
278 | --- a/a
281 | +++ b/a
279 | +++ b/a
282 | @@ -5,1 +5,1 @@
280 | @@ -5,1 +5,1 @@
283 | -5
281 | -5
284 | +55
282 | +55
285 |
283 |
286 o 0:a61bcde8c529 a1 r1
284 o 0:a61bcde8c529 a1 r1
287 diff --git a/a b/a
285 diff --git a/a b/a
288 new file mode 100644
286 new file mode 100644
289 --- /dev/null
287 --- /dev/null
290 +++ b/a
288 +++ b/a
291 @@ -0,0 +1,5 @@
289 @@ -0,0 +1,5 @@
292 +1
290 +1
293 +2
291 +2
294 +3
292 +3
295 +4
293 +4
296 +5
294 +5
297
295
298 #else
296 #else
299 $ hg bookmark
297 $ hg bookmark
300 r1 0:a61bcde8c529
298 r1 0:a61bcde8c529
301 r2 4:00eebaf8d2e2
299 r2 4:00eebaf8d2e2
302 * r3 4:00eebaf8d2e2
300 * r3 4:00eebaf8d2e2
303 $ hg glog
301 $ hg glog
304 @ 4:00eebaf8d2e2 split 3 r2 r3
302 @ 4:00eebaf8d2e2 split 3 r2 r3
305 |
303 |
306 o 3:a09ad58faae3 split 2
304 o 3:a09ad58faae3 split 2
307 |
305 |
308 o 2:e704349bd21b split 1
306 o 2:e704349bd21b split 1
309 |
307 |
310 o 0:a61bcde8c529 a1 r1
308 o 0:a61bcde8c529 a1 r1
311
309
312 #endif
310 #endif
313
311
314 Split a head while working parent is not that head
312 Split a head while working parent is not that head
315
313
316 $ cp -R $TESTTMP/clean $TESTTMP/b
314 $ cp -R $TESTTMP/clean $TESTTMP/b
317 $ cd $TESTTMP/b
315 $ cd $TESTTMP/b
318
316
319 $ hg up 0 -q
317 $ hg up 0 -q
320 $ hg bookmark r3
318 $ hg bookmark r3
321
319
322 $ runsplit tip >/dev/null
320 $ runsplit tip >/dev/null
323
321
324 #if obsstore-off
322 #if obsstore-off
325 $ hg bookmark
323 $ hg bookmark
326 r1 0:a61bcde8c529
324 r1 0:a61bcde8c529
327 r2 3:00eebaf8d2e2
325 r2 3:00eebaf8d2e2
328 * r3 0:a61bcde8c529
326 * r3 0:a61bcde8c529
329 $ hg glog
327 $ hg glog
330 o 3:00eebaf8d2e2 split 3 r2
328 o 3:00eebaf8d2e2 split 3 r2
331 |
329 |
332 o 2:a09ad58faae3 split 2
330 o 2:a09ad58faae3 split 2
333 |
331 |
334 o 1:e704349bd21b split 1
332 o 1:e704349bd21b split 1
335 |
333 |
336 @ 0:a61bcde8c529 a1 r1 r3
334 @ 0:a61bcde8c529 a1 r1 r3
337
335
338 #else
336 #else
339 $ hg bookmark
337 $ hg bookmark
340 r1 0:a61bcde8c529
338 r1 0:a61bcde8c529
341 r2 4:00eebaf8d2e2
339 r2 4:00eebaf8d2e2
342 * r3 0:a61bcde8c529
340 * r3 0:a61bcde8c529
343 $ hg glog
341 $ hg glog
344 o 4:00eebaf8d2e2 split 3 r2
342 o 4:00eebaf8d2e2 split 3 r2
345 |
343 |
346 o 3:a09ad58faae3 split 2
344 o 3:a09ad58faae3 split 2
347 |
345 |
348 o 2:e704349bd21b split 1
346 o 2:e704349bd21b split 1
349 |
347 |
350 @ 0:a61bcde8c529 a1 r1 r3
348 @ 0:a61bcde8c529 a1 r1 r3
351
349
352 #endif
350 #endif
353
351
354 Split a non-head
352 Split a non-head
355
353
356 $ cp -R $TESTTMP/clean $TESTTMP/c
354 $ cp -R $TESTTMP/clean $TESTTMP/c
357 $ cd $TESTTMP/c
355 $ cd $TESTTMP/c
358 $ echo d > d
356 $ echo d > d
359 $ hg ci -m d1 -A d
357 $ hg ci -m d1 -A d
360 $ hg bookmark -i d1
358 $ hg bookmark -i d1
361 $ echo 2 >> d
359 $ echo 2 >> d
362 $ hg ci -m d2
360 $ hg ci -m d2
363 $ echo 3 >> d
361 $ echo 3 >> d
364 $ hg ci -m d3
362 $ hg ci -m d3
365 $ hg bookmark -i d3
363 $ hg bookmark -i d3
366 $ hg up '.^' -q
364 $ hg up '.^' -q
367 $ hg bookmark d2
365 $ hg bookmark d2
368 $ cp -R . ../d
366 $ cp -R . ../d
369
367
370 $ runsplit -r 1 | grep rebasing
368 $ runsplit -r 1 | grep rebasing
371 rebasing 2:b5c5ea414030 d1 "d1"
369 rebasing 2:b5c5ea414030 d1 "d1"
372 rebasing 3:f4a0a8d004cc d2 "d2"
370 rebasing 3:f4a0a8d004cc d2 "d2"
373 rebasing 4:777940761eba d3 "d3"
371 rebasing 4:777940761eba d3 "d3"
374 #if obsstore-off
372 #if obsstore-off
375 $ hg bookmark
373 $ hg bookmark
376 d1 4:c4b449ef030e
374 d1 4:c4b449ef030e
377 * d2 5:c9dd00ab36a3
375 * d2 5:c9dd00ab36a3
378 d3 6:19f476bc865c
376 d3 6:19f476bc865c
379 r1 0:a61bcde8c529
377 r1 0:a61bcde8c529
380 r2 3:00eebaf8d2e2
378 r2 3:00eebaf8d2e2
381 $ hg glog -p
379 $ hg glog -p
382 o 6:19f476bc865c d3 d3
380 o 6:19f476bc865c d3 d3
383 | diff --git a/d b/d
381 | diff --git a/d b/d
384 | --- a/d
382 | --- a/d
385 | +++ b/d
383 | +++ b/d
386 | @@ -2,0 +3,1 @@
384 | @@ -2,0 +3,1 @@
387 | +3
385 | +3
388 |
386 |
389 @ 5:c9dd00ab36a3 d2 d2
387 @ 5:c9dd00ab36a3 d2 d2
390 | diff --git a/d b/d
388 | diff --git a/d b/d
391 | --- a/d
389 | --- a/d
392 | +++ b/d
390 | +++ b/d
393 | @@ -1,0 +2,1 @@
391 | @@ -1,0 +2,1 @@
394 | +2
392 | +2
395 |
393 |
396 o 4:c4b449ef030e d1 d1
394 o 4:c4b449ef030e d1 d1
397 | diff --git a/d b/d
395 | diff --git a/d b/d
398 | new file mode 100644
396 | new file mode 100644
399 | --- /dev/null
397 | --- /dev/null
400 | +++ b/d
398 | +++ b/d
401 | @@ -0,0 +1,1 @@
399 | @@ -0,0 +1,1 @@
402 | +d
400 | +d
403 |
401 |
404 o 3:00eebaf8d2e2 split 3 r2
402 o 3:00eebaf8d2e2 split 3 r2
405 | diff --git a/a b/a
403 | diff --git a/a b/a
406 | --- a/a
404 | --- a/a
407 | +++ b/a
405 | +++ b/a
408 | @@ -1,1 +1,1 @@
406 | @@ -1,1 +1,1 @@
409 | -1
407 | -1
410 | +11
408 | +11
411 |
409 |
412 o 2:a09ad58faae3 split 2
410 o 2:a09ad58faae3 split 2
413 | diff --git a/a b/a
411 | diff --git a/a b/a
414 | --- a/a
412 | --- a/a
415 | +++ b/a
413 | +++ b/a
416 | @@ -3,1 +3,1 @@
414 | @@ -3,1 +3,1 @@
417 | -3
415 | -3
418 | +33
416 | +33
419 |
417 |
420 o 1:e704349bd21b split 1
418 o 1:e704349bd21b split 1
421 | diff --git a/a b/a
419 | diff --git a/a b/a
422 | --- a/a
420 | --- a/a
423 | +++ b/a
421 | +++ b/a
424 | @@ -5,1 +5,1 @@
422 | @@ -5,1 +5,1 @@
425 | -5
423 | -5
426 | +55
424 | +55
427 |
425 |
428 o 0:a61bcde8c529 a1 r1
426 o 0:a61bcde8c529 a1 r1
429 diff --git a/a b/a
427 diff --git a/a b/a
430 new file mode 100644
428 new file mode 100644
431 --- /dev/null
429 --- /dev/null
432 +++ b/a
430 +++ b/a
433 @@ -0,0 +1,5 @@
431 @@ -0,0 +1,5 @@
434 +1
432 +1
435 +2
433 +2
436 +3
434 +3
437 +4
435 +4
438 +5
436 +5
439
437
440 #else
438 #else
441 $ hg bookmark
439 $ hg bookmark
442 d1 8:c4b449ef030e
440 d1 8:c4b449ef030e
443 * d2 9:c9dd00ab36a3
441 * d2 9:c9dd00ab36a3
444 d3 10:19f476bc865c
442 d3 10:19f476bc865c
445 r1 0:a61bcde8c529
443 r1 0:a61bcde8c529
446 r2 7:00eebaf8d2e2
444 r2 7:00eebaf8d2e2
447 $ hg glog
445 $ hg glog
448 o 10:19f476bc865c d3 d3
446 o 10:19f476bc865c d3 d3
449 |
447 |
450 @ 9:c9dd00ab36a3 d2 d2
448 @ 9:c9dd00ab36a3 d2 d2
451 |
449 |
452 o 8:c4b449ef030e d1 d1
450 o 8:c4b449ef030e d1 d1
453 |
451 |
454 o 7:00eebaf8d2e2 split 3 r2
452 o 7:00eebaf8d2e2 split 3 r2
455 |
453 |
456 o 6:a09ad58faae3 split 2
454 o 6:a09ad58faae3 split 2
457 |
455 |
458 o 5:e704349bd21b split 1
456 o 5:e704349bd21b split 1
459 |
457 |
460 o 0:a61bcde8c529 a1 r1
458 o 0:a61bcde8c529 a1 r1
461
459
462 #endif
460 #endif
463
461
464 Split a non-head without rebase
462 Split a non-head without rebase
465
463
466 $ cd $TESTTMP/d
464 $ cd $TESTTMP/d
467 #if obsstore-off
465 #if obsstore-off
468 $ runsplit -r 1 --no-rebase
466 $ runsplit -r 1 --no-rebase
469 abort: cannot split changeset, as that will orphan 3 descendants
467 abort: cannot split changeset, as that will orphan 3 descendants
470 (see 'hg help evolution.instability')
468 (see 'hg help evolution.instability')
471 [10]
469 [10]
472 #else
470 #else
473 $ runsplit -r 1 --no-rebase >/dev/null
471 $ runsplit -r 1 --no-rebase >/dev/null
474 3 new orphan changesets
472 3 new orphan changesets
475 $ hg bookmark
473 $ hg bookmark
476 d1 2:b5c5ea414030
474 d1 2:b5c5ea414030
477 * d2 3:f4a0a8d004cc
475 * d2 3:f4a0a8d004cc
478 d3 4:777940761eba
476 d3 4:777940761eba
479 r1 0:a61bcde8c529
477 r1 0:a61bcde8c529
480 r2 7:00eebaf8d2e2
478 r2 7:00eebaf8d2e2
481
479
482 $ hg glog
480 $ hg glog
483 o 7:00eebaf8d2e2 split 3 r2
481 o 7:00eebaf8d2e2 split 3 r2
484 |
482 |
485 o 6:a09ad58faae3 split 2
483 o 6:a09ad58faae3 split 2
486 |
484 |
487 o 5:e704349bd21b split 1
485 o 5:e704349bd21b split 1
488 |
486 |
489 | * 4:777940761eba d3 d3
487 | * 4:777940761eba d3 d3
490 | |
488 | |
491 | @ 3:f4a0a8d004cc d2 d2
489 | @ 3:f4a0a8d004cc d2 d2
492 | |
490 | |
493 | * 2:b5c5ea414030 d1 d1
491 | * 2:b5c5ea414030 d1 d1
494 | |
492 | |
495 | x 1:1df0d5c5a3ab a2
493 | x 1:1df0d5c5a3ab a2
496 |/
494 |/
497 o 0:a61bcde8c529 a1 r1
495 o 0:a61bcde8c529 a1 r1
498
496
499 #endif
497 #endif
500
498
501 Split a non-head with obsoleted descendants
499 Split a non-head with obsoleted descendants
502
500
503 #if obsstore-on
501 #if obsstore-on
504 $ hg init $TESTTMP/e
502 $ hg init $TESTTMP/e
505 $ cd $TESTTMP/e
503 $ cd $TESTTMP/e
506 $ hg debugdrawdag <<'EOS'
504 $ hg debugdrawdag <<'EOS'
507 > H I J
505 > H I J
508 > | | |
506 > | | |
509 > F G1 G2 # amend: G1 -> G2
507 > F G1 G2 # amend: G1 -> G2
510 > | | / # prune: F
508 > | | / # prune: F
511 > C D E
509 > C D E
512 > \|/
510 > \|/
513 > B
511 > B
514 > |
512 > |
515 > A
513 > A
516 > EOS
514 > EOS
517 2 new orphan changesets
515 2 new orphan changesets
518 $ eval `hg tags -T '{tag}={node}\n'`
516 $ eval `hg tags -T '{tag}={node}\n'`
519 $ rm .hg/localtags
517 $ rm .hg/localtags
520 $ hg split $B --config experimental.evolution=createmarkers
518 $ hg split $B --config experimental.evolution=createmarkers
521 abort: cannot split changeset, as that will orphan 4 descendants
519 abort: cannot split changeset, as that will orphan 4 descendants
522 (see 'hg help evolution.instability')
520 (see 'hg help evolution.instability')
523 [10]
521 [10]
524 $ cat > $TESTTMP/messages <<EOF
522 $ cat > $TESTTMP/messages <<EOF
525 > Split B
523 > Split B
526 > EOF
524 > EOF
527 $ cat <<EOF | hg split $B
525 $ cat <<EOF | hg split $B
528 > y
526 > y
529 > y
527 > y
530 > EOF
528 > EOF
531 diff --git a/B b/B
529 diff --git a/B b/B
532 new file mode 100644
530 new file mode 100644
533 examine changes to 'B'?
531 examine changes to 'B'?
534 (enter ? for help) [Ynesfdaq?] y
532 (enter ? for help) [Ynesfdaq?] y
535
533
536 @@ -0,0 +1,1 @@
534 @@ -0,0 +1,1 @@
537 +B
535 +B
538 \ No newline at end of file
536 \ No newline at end of file
539 record this change to 'B'?
537 record this change to 'B'?
540 (enter ? for help) [Ynesfdaq?] y
538 (enter ? for help) [Ynesfdaq?] y
541
539
542 EDITOR: HG: Splitting 112478962961. Write commit message for the first split changeset.
540 EDITOR: HG: Splitting 112478962961. Write commit message for the first split changeset.
543 EDITOR: B
541 EDITOR: B
544 EDITOR:
542 EDITOR:
545 EDITOR:
543 EDITOR:
546 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
544 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
547 EDITOR: HG: Leave message empty to abort commit.
545 EDITOR: HG: Leave message empty to abort commit.
548 EDITOR: HG: --
546 EDITOR: HG: --
549 EDITOR: HG: user: test
547 EDITOR: HG: user: test
550 EDITOR: HG: branch 'default'
548 EDITOR: HG: branch 'default'
551 EDITOR: HG: added B
549 EDITOR: HG: added B
552 created new head
550 created new head
553 rebasing 2:26805aba1e60 "C"
551 rebasing 2:26805aba1e60 "C"
554 rebasing 3:be0ef73c17ad "D"
552 rebasing 3:be0ef73c17ad "D"
555 rebasing 4:49cb92066bfd "E"
553 rebasing 4:49cb92066bfd "E"
556 rebasing 7:97a6268cc7ef "G2"
554 rebasing 7:97a6268cc7ef "G2"
557 rebasing 10:e2f1e425c0db "J"
555 rebasing 10:e2f1e425c0db "J"
558 $ hg glog -r 'sort(all(), topo)'
556 $ hg glog -r 'sort(all(), topo)'
559 o 16:556c085f8b52 J
557 o 16:556c085f8b52 J
560 |
558 |
561 o 15:8761f6c9123f G2
559 o 15:8761f6c9123f G2
562 |
560 |
563 o 14:a7aeffe59b65 E
561 o 14:a7aeffe59b65 E
564 |
562 |
565 | o 13:e1e914ede9ab D
563 | o 13:e1e914ede9ab D
566 |/
564 |/
567 | o 12:01947e9b98aa C
565 | o 12:01947e9b98aa C
568 |/
566 |/
569 o 11:0947baa74d47 Split B
567 o 11:0947baa74d47 Split B
570 |
568 |
571 | * 9:88ede1d5ee13 I
569 | * 9:88ede1d5ee13 I
572 | |
570 | |
573 | x 6:af8cbf225b7b G1
571 | x 6:af8cbf225b7b G1
574 | |
572 | |
575 | x 3:be0ef73c17ad D
573 | x 3:be0ef73c17ad D
576 | |
574 | |
577 | | * 8:74863e5b5074 H
575 | | * 8:74863e5b5074 H
578 | | |
576 | | |
579 | | x 5:ee481a2a1e69 F
577 | | x 5:ee481a2a1e69 F
580 | | |
578 | | |
581 | | x 2:26805aba1e60 C
579 | | x 2:26805aba1e60 C
582 | |/
580 | |/
583 | x 1:112478962961 B
581 | x 1:112478962961 B
584 |/
582 |/
585 o 0:426bada5c675 A
583 o 0:426bada5c675 A
586
584
587 #endif
585 #endif
588
586
589 Preserve secret phase in split
587 Preserve secret phase in split
590
588
591 $ cp -R $TESTTMP/clean $TESTTMP/phases1
589 $ cp -R $TESTTMP/clean $TESTTMP/phases1
592 $ cd $TESTTMP/phases1
590 $ cd $TESTTMP/phases1
593 $ hg phase --secret -fr tip
591 $ hg phase --secret -fr tip
594 $ hg log -T '{short(node)} {phase}\n'
592 $ hg log -T '{short(node)} {phase}\n'
595 1df0d5c5a3ab secret
593 1df0d5c5a3ab secret
596 a61bcde8c529 draft
594 a61bcde8c529 draft
597 $ runsplit tip >/dev/null
595 $ runsplit tip >/dev/null
598 $ hg log -T '{short(node)} {phase}\n'
596 $ hg log -T '{short(node)} {phase}\n'
599 00eebaf8d2e2 secret
597 00eebaf8d2e2 secret
600 a09ad58faae3 secret
598 a09ad58faae3 secret
601 e704349bd21b secret
599 e704349bd21b secret
602 a61bcde8c529 draft
600 a61bcde8c529 draft
603
601
604 Do not move things to secret even if phases.new-commit=secret
602 Do not move things to secret even if phases.new-commit=secret
605
603
606 $ cp -R $TESTTMP/clean $TESTTMP/phases2
604 $ cp -R $TESTTMP/clean $TESTTMP/phases2
607 $ cd $TESTTMP/phases2
605 $ cd $TESTTMP/phases2
608 $ cat >> .hg/hgrc <<EOF
606 $ cat >> .hg/hgrc <<EOF
609 > [phases]
607 > [phases]
610 > new-commit=secret
608 > new-commit=secret
611 > EOF
609 > EOF
612 $ hg log -T '{short(node)} {phase}\n'
610 $ hg log -T '{short(node)} {phase}\n'
613 1df0d5c5a3ab draft
611 1df0d5c5a3ab draft
614 a61bcde8c529 draft
612 a61bcde8c529 draft
615 $ runsplit tip >/dev/null
613 $ runsplit tip >/dev/null
616 $ hg log -T '{short(node)} {phase}\n'
614 $ hg log -T '{short(node)} {phase}\n'
617 00eebaf8d2e2 draft
615 00eebaf8d2e2 draft
618 a09ad58faae3 draft
616 a09ad58faae3 draft
619 e704349bd21b draft
617 e704349bd21b draft
620 a61bcde8c529 draft
618 a61bcde8c529 draft
621
619
622 `hg split` with ignoreblanklines=1 does not infinite loop
620 `hg split` with ignoreblanklines=1 does not infinite loop
623
621
624 $ mkdir $TESTTMP/f
622 $ mkdir $TESTTMP/f
625 $ hg init $TESTTMP/f/a
623 $ hg init $TESTTMP/f/a
626 $ cd $TESTTMP/f/a
624 $ cd $TESTTMP/f/a
627 $ printf '1\n2\n3\n4\n5\n' > foo
625 $ printf '1\n2\n3\n4\n5\n' > foo
628 $ cp foo bar
626 $ cp foo bar
629 $ hg ci -qAm initial
627 $ hg ci -qAm initial
630 $ printf '1\n\n2\n3\ntest\n4\n5\n' > bar
628 $ printf '1\n\n2\n3\ntest\n4\n5\n' > bar
631 $ printf '1\n2\n3\ntest\n4\n5\n' > foo
629 $ printf '1\n2\n3\ntest\n4\n5\n' > foo
632 $ hg ci -qm splitme
630 $ hg ci -qm splitme
633 $ cat > $TESTTMP/messages <<EOF
631 $ cat > $TESTTMP/messages <<EOF
634 > split 1
632 > split 1
635 > --
633 > --
636 > split 2
634 > split 2
637 > EOF
635 > EOF
638 $ printf 'f\nn\nf\n' | hg --config extensions.split= --config diff.ignoreblanklines=1 split
636 $ printf 'f\nn\nf\n' | hg --config extensions.split= --config diff.ignoreblanklines=1 split
639 diff --git a/bar b/bar
637 diff --git a/bar b/bar
640 2 hunks, 2 lines changed
638 2 hunks, 2 lines changed
641 examine changes to 'bar'?
639 examine changes to 'bar'?
642 (enter ? for help) [Ynesfdaq?] f
640 (enter ? for help) [Ynesfdaq?] f
643
641
644 diff --git a/foo b/foo
642 diff --git a/foo b/foo
645 1 hunks, 1 lines changed
643 1 hunks, 1 lines changed
646 examine changes to 'foo'?
644 examine changes to 'foo'?
647 (enter ? for help) [Ynesfdaq?] n
645 (enter ? for help) [Ynesfdaq?] n
648
646
649 EDITOR: HG: Splitting dd3c45017cbf. Write commit message for the first split changeset.
647 EDITOR: HG: Splitting dd3c45017cbf. Write commit message for the first split changeset.
650 EDITOR: splitme
648 EDITOR: splitme
651 EDITOR:
649 EDITOR:
652 EDITOR:
650 EDITOR:
653 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
651 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
654 EDITOR: HG: Leave message empty to abort commit.
652 EDITOR: HG: Leave message empty to abort commit.
655 EDITOR: HG: --
653 EDITOR: HG: --
656 EDITOR: HG: user: test
654 EDITOR: HG: user: test
657 EDITOR: HG: branch 'default'
655 EDITOR: HG: branch 'default'
658 EDITOR: HG: changed bar
656 EDITOR: HG: changed bar
659 created new head
657 created new head
660 diff --git a/foo b/foo
658 diff --git a/foo b/foo
661 1 hunks, 1 lines changed
659 1 hunks, 1 lines changed
662 examine changes to 'foo'?
660 examine changes to 'foo'?
663 (enter ? for help) [Ynesfdaq?] f
661 (enter ? for help) [Ynesfdaq?] f
664
662
665 EDITOR: HG: Splitting dd3c45017cbf. So far it has been split into:
663 EDITOR: HG: Splitting dd3c45017cbf. So far it has been split into:
666 EDITOR: HG: - 2:f205aea1c624 tip "split 1"
664 EDITOR: HG: - 2:f205aea1c624 tip "split 1"
667 EDITOR: HG: Write commit message for the next split changeset.
665 EDITOR: HG: Write commit message for the next split changeset.
668 EDITOR: splitme
666 EDITOR: splitme
669 EDITOR:
667 EDITOR:
670 EDITOR:
668 EDITOR:
671 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
669 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
672 EDITOR: HG: Leave message empty to abort commit.
670 EDITOR: HG: Leave message empty to abort commit.
673 EDITOR: HG: --
671 EDITOR: HG: --
674 EDITOR: HG: user: test
672 EDITOR: HG: user: test
675 EDITOR: HG: branch 'default'
673 EDITOR: HG: branch 'default'
676 EDITOR: HG: changed foo
674 EDITOR: HG: changed foo
677 saved backup bundle to $TESTTMP/f/a/.hg/strip-backup/dd3c45017cbf-463441b5-split.hg (obsstore-off !)
675 saved backup bundle to $TESTTMP/f/a/.hg/strip-backup/dd3c45017cbf-463441b5-split.hg (obsstore-off !)
678
676
679 Let's try that again, with a slightly different set of patches, to ensure that
677 Let's try that again, with a slightly different set of patches, to ensure that
680 the ignoreblanklines thing isn't somehow position dependent.
678 the ignoreblanklines thing isn't somehow position dependent.
681
679
682 $ hg init $TESTTMP/f/b
680 $ hg init $TESTTMP/f/b
683 $ cd $TESTTMP/f/b
681 $ cd $TESTTMP/f/b
684 $ printf '1\n2\n3\n4\n5\n' > foo
682 $ printf '1\n2\n3\n4\n5\n' > foo
685 $ cp foo bar
683 $ cp foo bar
686 $ hg ci -qAm initial
684 $ hg ci -qAm initial
687 $ printf '1\n2\n3\ntest\n4\n5\n' > bar
685 $ printf '1\n2\n3\ntest\n4\n5\n' > bar
688 $ printf '1\n2\n3\ntest\n4\n\n5\n' > foo
686 $ printf '1\n2\n3\ntest\n4\n\n5\n' > foo
689 $ hg ci -qm splitme
687 $ hg ci -qm splitme
690 $ cat > $TESTTMP/messages <<EOF
688 $ cat > $TESTTMP/messages <<EOF
691 > split 1
689 > split 1
692 > --
690 > --
693 > split 2
691 > split 2
694 > EOF
692 > EOF
695 $ printf 'f\nn\nf\n' | hg --config extensions.split= --config diff.ignoreblanklines=1 split
693 $ printf 'f\nn\nf\n' | hg --config extensions.split= --config diff.ignoreblanklines=1 split
696 diff --git a/bar b/bar
694 diff --git a/bar b/bar
697 1 hunks, 1 lines changed
695 1 hunks, 1 lines changed
698 examine changes to 'bar'?
696 examine changes to 'bar'?
699 (enter ? for help) [Ynesfdaq?] f
697 (enter ? for help) [Ynesfdaq?] f
700
698
701 diff --git a/foo b/foo
699 diff --git a/foo b/foo
702 2 hunks, 2 lines changed
700 2 hunks, 2 lines changed
703 examine changes to 'foo'?
701 examine changes to 'foo'?
704 (enter ? for help) [Ynesfdaq?] n
702 (enter ? for help) [Ynesfdaq?] n
705
703
706 EDITOR: HG: Splitting 904c80b40a4a. Write commit message for the first split changeset.
704 EDITOR: HG: Splitting 904c80b40a4a. Write commit message for the first split changeset.
707 EDITOR: splitme
705 EDITOR: splitme
708 EDITOR:
706 EDITOR:
709 EDITOR:
707 EDITOR:
710 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
708 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
711 EDITOR: HG: Leave message empty to abort commit.
709 EDITOR: HG: Leave message empty to abort commit.
712 EDITOR: HG: --
710 EDITOR: HG: --
713 EDITOR: HG: user: test
711 EDITOR: HG: user: test
714 EDITOR: HG: branch 'default'
712 EDITOR: HG: branch 'default'
715 EDITOR: HG: changed bar
713 EDITOR: HG: changed bar
716 created new head
714 created new head
717 diff --git a/foo b/foo
715 diff --git a/foo b/foo
718 2 hunks, 2 lines changed
716 2 hunks, 2 lines changed
719 examine changes to 'foo'?
717 examine changes to 'foo'?
720 (enter ? for help) [Ynesfdaq?] f
718 (enter ? for help) [Ynesfdaq?] f
721
719
722 EDITOR: HG: Splitting 904c80b40a4a. So far it has been split into:
720 EDITOR: HG: Splitting 904c80b40a4a. So far it has been split into:
723 EDITOR: HG: - 2:ffecf40fa954 tip "split 1"
721 EDITOR: HG: - 2:ffecf40fa954 tip "split 1"
724 EDITOR: HG: Write commit message for the next split changeset.
722 EDITOR: HG: Write commit message for the next split changeset.
725 EDITOR: splitme
723 EDITOR: splitme
726 EDITOR:
724 EDITOR:
727 EDITOR:
725 EDITOR:
728 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
726 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
729 EDITOR: HG: Leave message empty to abort commit.
727 EDITOR: HG: Leave message empty to abort commit.
730 EDITOR: HG: --
728 EDITOR: HG: --
731 EDITOR: HG: user: test
729 EDITOR: HG: user: test
732 EDITOR: HG: branch 'default'
730 EDITOR: HG: branch 'default'
733 EDITOR: HG: changed foo
731 EDITOR: HG: changed foo
734 saved backup bundle to $TESTTMP/f/b/.hg/strip-backup/904c80b40a4a-47fb907f-split.hg (obsstore-off !)
732 saved backup bundle to $TESTTMP/f/b/.hg/strip-backup/904c80b40a4a-47fb907f-split.hg (obsstore-off !)
735
733
736
734
737 Testing the case in split when commiting flag-only file changes (issue5864)
735 Testing the case in split when commiting flag-only file changes (issue5864)
738 ---------------------------------------------------------------------------
736 ---------------------------------------------------------------------------
739 $ hg init $TESTTMP/issue5864
737 $ hg init $TESTTMP/issue5864
740 $ cd $TESTTMP/issue5864
738 $ cd $TESTTMP/issue5864
741 $ echo foo > foo
739 $ echo foo > foo
742 $ hg add foo
740 $ hg add foo
743 $ hg ci -m "initial"
741 $ hg ci -m "initial"
744 $ hg import -q --bypass -m "make executable" - <<EOF
742 $ hg import -q --bypass -m "make executable" - <<EOF
745 > diff --git a/foo b/foo
743 > diff --git a/foo b/foo
746 > old mode 100644
744 > old mode 100644
747 > new mode 100755
745 > new mode 100755
748 > EOF
746 > EOF
749 $ hg up -q
747 $ hg up -q
750
748
751 $ hg glog
749 $ hg glog
752 @ 1:3a2125f0f4cb make executable
750 @ 1:3a2125f0f4cb make executable
753 |
751 |
754 o 0:51f273a58d82 initial
752 o 0:51f273a58d82 initial
755
753
756
754
757 #if no-windows
755 #if no-windows
758 $ cat > $TESTTMP/messages <<EOF
756 $ cat > $TESTTMP/messages <<EOF
759 > split 1
757 > split 1
760 > EOF
758 > EOF
761 $ printf 'y\n' | hg split
759 $ printf 'y\n' | hg split
762 diff --git a/foo b/foo
760 diff --git a/foo b/foo
763 old mode 100644
761 old mode 100644
764 new mode 100755
762 new mode 100755
765 examine changes to 'foo'?
763 examine changes to 'foo'?
766 (enter ? for help) [Ynesfdaq?] y
764 (enter ? for help) [Ynesfdaq?] y
767
765
768 EDITOR: HG: Splitting 3a2125f0f4cb. Write commit message for the first split changeset.
766 EDITOR: HG: Splitting 3a2125f0f4cb. Write commit message for the first split changeset.
769 EDITOR: make executable
767 EDITOR: make executable
770 EDITOR:
768 EDITOR:
771 EDITOR:
769 EDITOR:
772 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
770 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
773 EDITOR: HG: Leave message empty to abort commit.
771 EDITOR: HG: Leave message empty to abort commit.
774 EDITOR: HG: --
772 EDITOR: HG: --
775 EDITOR: HG: user: test
773 EDITOR: HG: user: test
776 EDITOR: HG: branch 'default'
774 EDITOR: HG: branch 'default'
777 EDITOR: HG: changed foo
775 EDITOR: HG: changed foo
778 created new head
776 created new head
779 saved backup bundle to $TESTTMP/issue5864/.hg/strip-backup/3a2125f0f4cb-629e4432-split.hg (obsstore-off !)
777 saved backup bundle to $TESTTMP/issue5864/.hg/strip-backup/3a2125f0f4cb-629e4432-split.hg (obsstore-off !)
780
778
781 $ hg log -G -T "{node|short} {desc}\n"
779 $ hg log -G -T "{node|short} {desc}\n"
782 @ b154670c87da split 1
780 @ b154670c87da split 1
783 |
781 |
784 o 51f273a58d82 initial
782 o 51f273a58d82 initial
785
783
786 #else
784 #else
787
785
788 TODO: Fix this on Windows. See issue 2020 and 5883
786 TODO: Fix this on Windows. See issue 2020 and 5883
789
787
790 $ printf 'y\ny\ny\n' | hg split
788 $ printf 'y\ny\ny\n' | hg split
791 abort: cannot split an empty revision
789 abort: cannot split an empty revision
792 [10]
790 [10]
793 #endif
791 #endif
794
792
795 Test that splitting moves works properly (issue5723)
793 Test that splitting moves works properly (issue5723)
796 ----------------------------------------------------
794 ----------------------------------------------------
797
795
798 $ hg init $TESTTMP/issue5723-mv
796 $ hg init $TESTTMP/issue5723-mv
799 $ cd $TESTTMP/issue5723-mv
797 $ cd $TESTTMP/issue5723-mv
800 $ printf '1\n2\n' > file
798 $ printf '1\n2\n' > file
801 $ hg ci -qAm initial
799 $ hg ci -qAm initial
802 $ hg mv file file2
800 $ hg mv file file2
803 $ printf 'a\nb\n1\n2\n3\n4\n' > file2
801 $ printf 'a\nb\n1\n2\n3\n4\n' > file2
804 $ cat > $TESTTMP/messages <<EOF
802 $ cat > $TESTTMP/messages <<EOF
805 > split1, keeping only the numbered lines
803 > split1, keeping only the numbered lines
806 > --
804 > --
807 > split2, keeping the lettered lines
805 > split2, keeping the lettered lines
808 > EOF
806 > EOF
809 $ hg ci -m 'move and modify'
807 $ hg ci -m 'move and modify'
810 $ printf 'y\nn\na\na\n' | hg split
808 $ printf 'y\nn\na\na\n' | hg split
811 diff --git a/file b/file2
809 diff --git a/file b/file2
812 rename from file
810 rename from file
813 rename to file2
811 rename to file2
814 2 hunks, 4 lines changed
812 2 hunks, 4 lines changed
815 examine changes to 'file' and 'file2'?
813 examine changes to 'file' and 'file2'?
816 (enter ? for help) [Ynesfdaq?] y
814 (enter ? for help) [Ynesfdaq?] y
817
815
818 @@ -0,0 +1,2 @@
816 @@ -0,0 +1,2 @@
819 +a
817 +a
820 +b
818 +b
821 record change 1/2 to 'file2'?
819 record change 1/2 to 'file2'?
822 (enter ? for help) [Ynesfdaq?] n
820 (enter ? for help) [Ynesfdaq?] n
823
821
824 @@ -2,0 +5,2 @@ 2
822 @@ -2,0 +5,2 @@ 2
825 +3
823 +3
826 +4
824 +4
827 record change 2/2 to 'file2'?
825 record change 2/2 to 'file2'?
828 (enter ? for help) [Ynesfdaq?] a
826 (enter ? for help) [Ynesfdaq?] a
829
827
830 EDITOR: HG: Splitting 8c42fa635116. Write commit message for the first split changeset.
828 EDITOR: HG: Splitting 8c42fa635116. Write commit message for the first split changeset.
831 EDITOR: move and modify
829 EDITOR: move and modify
832 EDITOR:
830 EDITOR:
833 EDITOR:
831 EDITOR:
834 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
832 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
835 EDITOR: HG: Leave message empty to abort commit.
833 EDITOR: HG: Leave message empty to abort commit.
836 EDITOR: HG: --
834 EDITOR: HG: --
837 EDITOR: HG: user: test
835 EDITOR: HG: user: test
838 EDITOR: HG: branch 'default'
836 EDITOR: HG: branch 'default'
839 EDITOR: HG: added file2
837 EDITOR: HG: added file2
840 EDITOR: HG: removed file
838 EDITOR: HG: removed file
841 created new head
839 created new head
842 diff --git a/file2 b/file2
840 diff --git a/file2 b/file2
843 1 hunks, 2 lines changed
841 1 hunks, 2 lines changed
844 examine changes to 'file2'?
842 examine changes to 'file2'?
845 (enter ? for help) [Ynesfdaq?] a
843 (enter ? for help) [Ynesfdaq?] a
846
844
847 EDITOR: HG: Splitting 8c42fa635116. So far it has been split into:
845 EDITOR: HG: Splitting 8c42fa635116. So far it has been split into:
848 EDITOR: HG: - 2:478be2a70c27 tip "split1, keeping only the numbered lines"
846 EDITOR: HG: - 2:478be2a70c27 tip "split1, keeping only the numbered lines"
849 EDITOR: HG: Write commit message for the next split changeset.
847 EDITOR: HG: Write commit message for the next split changeset.
850 EDITOR: move and modify
848 EDITOR: move and modify
851 EDITOR:
849 EDITOR:
852 EDITOR:
850 EDITOR:
853 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
851 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
854 EDITOR: HG: Leave message empty to abort commit.
852 EDITOR: HG: Leave message empty to abort commit.
855 EDITOR: HG: --
853 EDITOR: HG: --
856 EDITOR: HG: user: test
854 EDITOR: HG: user: test
857 EDITOR: HG: branch 'default'
855 EDITOR: HG: branch 'default'
858 EDITOR: HG: changed file2
856 EDITOR: HG: changed file2
859 saved backup bundle to $TESTTMP/issue5723-mv/.hg/strip-backup/8c42fa635116-a38044d4-split.hg (obsstore-off !)
857 saved backup bundle to $TESTTMP/issue5723-mv/.hg/strip-backup/8c42fa635116-a38044d4-split.hg (obsstore-off !)
860 $ hg log -T '{desc}: {files%"{file} "}\n'
858 $ hg log -T '{desc}: {files%"{file} "}\n'
861 split2, keeping the lettered lines: file2
859 split2, keeping the lettered lines: file2
862 split1, keeping only the numbered lines: file file2
860 split1, keeping only the numbered lines: file file2
863 initial: file
861 initial: file
864 $ cat file2
862 $ cat file2
865 a
863 a
866 b
864 b
867 1
865 1
868 2
866 2
869 3
867 3
870 4
868 4
871 $ hg cat -r ".^" file2
869 $ hg cat -r ".^" file2
872 1
870 1
873 2
871 2
874 3
872 3
875 4
873 4
876 $ hg cat -r . file2
874 $ hg cat -r . file2
877 a
875 a
878 b
876 b
879 1
877 1
880 2
878 2
881 3
879 3
882 4
880 4
883
881
884
882
885 Test that splitting copies works properly (issue5723)
883 Test that splitting copies works properly (issue5723)
886 ----------------------------------------------------
884 ----------------------------------------------------
887
885
888 $ hg init $TESTTMP/issue5723-cp
886 $ hg init $TESTTMP/issue5723-cp
889 $ cd $TESTTMP/issue5723-cp
887 $ cd $TESTTMP/issue5723-cp
890 $ printf '1\n2\n' > file
888 $ printf '1\n2\n' > file
891 $ hg ci -qAm initial
889 $ hg ci -qAm initial
892 $ hg cp file file2
890 $ hg cp file file2
893 $ printf 'a\nb\n1\n2\n3\n4\n' > file2
891 $ printf 'a\nb\n1\n2\n3\n4\n' > file2
894 Also modify 'file' to prove that the changes aren't being pulled in
892 Also modify 'file' to prove that the changes aren't being pulled in
895 accidentally.
893 accidentally.
896 $ printf 'this is the new contents of "file"' > file
894 $ printf 'this is the new contents of "file"' > file
897 $ cat > $TESTTMP/messages <<EOF
895 $ cat > $TESTTMP/messages <<EOF
898 > split1, keeping "file" and only the numbered lines in file2
896 > split1, keeping "file" and only the numbered lines in file2
899 > --
897 > --
900 > split2, keeping the lettered lines in file2
898 > split2, keeping the lettered lines in file2
901 > EOF
899 > EOF
902 $ hg ci -m 'copy file->file2, modify both'
900 $ hg ci -m 'copy file->file2, modify both'
903 $ printf 'f\ny\nn\na\na\n' | hg split
901 $ printf 'f\ny\nn\na\na\n' | hg split
904 diff --git a/file b/file
902 diff --git a/file b/file
905 1 hunks, 2 lines changed
903 1 hunks, 2 lines changed
906 examine changes to 'file'?
904 examine changes to 'file'?
907 (enter ? for help) [Ynesfdaq?] f
905 (enter ? for help) [Ynesfdaq?] f
908
906
909 diff --git a/file b/file2
907 diff --git a/file b/file2
910 copy from file
908 copy from file
911 copy to file2
909 copy to file2
912 2 hunks, 4 lines changed
910 2 hunks, 4 lines changed
913 examine changes to 'file' and 'file2'?
911 examine changes to 'file' and 'file2'?
914 (enter ? for help) [Ynesfdaq?] y
912 (enter ? for help) [Ynesfdaq?] y
915
913
916 @@ -0,0 +1,2 @@
914 @@ -0,0 +1,2 @@
917 +a
915 +a
918 +b
916 +b
919 record change 2/3 to 'file2'?
917 record change 2/3 to 'file2'?
920 (enter ? for help) [Ynesfdaq?] n
918 (enter ? for help) [Ynesfdaq?] n
921
919
922 @@ -2,0 +5,2 @@ 2
920 @@ -2,0 +5,2 @@ 2
923 +3
921 +3
924 +4
922 +4
925 record change 3/3 to 'file2'?
923 record change 3/3 to 'file2'?
926 (enter ? for help) [Ynesfdaq?] a
924 (enter ? for help) [Ynesfdaq?] a
927
925
928 EDITOR: HG: Splitting 41c861dfa61e. Write commit message for the first split changeset.
926 EDITOR: HG: Splitting 41c861dfa61e. Write commit message for the first split changeset.
929 EDITOR: copy file->file2, modify both
927 EDITOR: copy file->file2, modify both
930 EDITOR:
928 EDITOR:
931 EDITOR:
929 EDITOR:
932 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
930 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
933 EDITOR: HG: Leave message empty to abort commit.
931 EDITOR: HG: Leave message empty to abort commit.
934 EDITOR: HG: --
932 EDITOR: HG: --
935 EDITOR: HG: user: test
933 EDITOR: HG: user: test
936 EDITOR: HG: branch 'default'
934 EDITOR: HG: branch 'default'
937 EDITOR: HG: added file2
935 EDITOR: HG: added file2
938 EDITOR: HG: changed file
936 EDITOR: HG: changed file
939 created new head
937 created new head
940 diff --git a/file2 b/file2
938 diff --git a/file2 b/file2
941 1 hunks, 2 lines changed
939 1 hunks, 2 lines changed
942 examine changes to 'file2'?
940 examine changes to 'file2'?
943 (enter ? for help) [Ynesfdaq?] a
941 (enter ? for help) [Ynesfdaq?] a
944
942
945 EDITOR: HG: Splitting 41c861dfa61e. So far it has been split into:
943 EDITOR: HG: Splitting 41c861dfa61e. So far it has been split into:
946 EDITOR: HG: - 2:4b19e06610eb tip "split1, keeping "file" and only the numbered lines in file2"
944 EDITOR: HG: - 2:4b19e06610eb tip "split1, keeping "file" and only the numbered lines in file2"
947 EDITOR: HG: Write commit message for the next split changeset.
945 EDITOR: HG: Write commit message for the next split changeset.
948 EDITOR: copy file->file2, modify both
946 EDITOR: copy file->file2, modify both
949 EDITOR:
947 EDITOR:
950 EDITOR:
948 EDITOR:
951 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
949 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
952 EDITOR: HG: Leave message empty to abort commit.
950 EDITOR: HG: Leave message empty to abort commit.
953 EDITOR: HG: --
951 EDITOR: HG: --
954 EDITOR: HG: user: test
952 EDITOR: HG: user: test
955 EDITOR: HG: branch 'default'
953 EDITOR: HG: branch 'default'
956 EDITOR: HG: changed file2
954 EDITOR: HG: changed file2
957 saved backup bundle to $TESTTMP/issue5723-cp/.hg/strip-backup/41c861dfa61e-467e8d3c-split.hg (obsstore-off !)
955 saved backup bundle to $TESTTMP/issue5723-cp/.hg/strip-backup/41c861dfa61e-467e8d3c-split.hg (obsstore-off !)
958 $ hg log -T '{desc}: {files%"{file} "}\n'
956 $ hg log -T '{desc}: {files%"{file} "}\n'
959 split2, keeping the lettered lines in file2: file2
957 split2, keeping the lettered lines in file2: file2
960 split1, keeping "file" and only the numbered lines in file2: file file2
958 split1, keeping "file" and only the numbered lines in file2: file file2
961 initial: file
959 initial: file
962 $ cat file2
960 $ cat file2
963 a
961 a
964 b
962 b
965 1
963 1
966 2
964 2
967 3
965 3
968 4
966 4
969 $ hg cat -r ".^" file2
967 $ hg cat -r ".^" file2
970 1
968 1
971 2
969 2
972 3
970 3
973 4
971 4
974 $ hg cat -r . file2
972 $ hg cat -r . file2
975 a
973 a
976 b
974 b
977 1
975 1
978 2
976 2
979 3
977 3
980 4
978 4
981
979
982 Test that color codes don't end up in the commit message template
980 Test that color codes don't end up in the commit message template
983 ----------------------------------------------------
981 ----------------------------------------------------
984
982
985 $ hg init $TESTTMP/colorless
983 $ hg init $TESTTMP/colorless
986 $ cd $TESTTMP/colorless
984 $ cd $TESTTMP/colorless
987 $ echo 1 > file1
985 $ echo 1 > file1
988 $ echo 1 > file2
986 $ echo 1 > file2
989 $ hg ci -qAm initial
987 $ hg ci -qAm initial
990 $ echo 2 > file1
988 $ echo 2 > file1
991 $ echo 2 > file2
989 $ echo 2 > file2
992 $ cat > $TESTTMP/messages <<EOF
990 $ cat > $TESTTMP/messages <<EOF
993 > split1, modifying file1
991 > split1, modifying file1
994 > --
992 > --
995 > split2, modifying file2
993 > split2, modifying file2
996 > EOF
994 > EOF
997 $ hg ci
995 $ hg ci
998 EDITOR:
996 EDITOR:
999 EDITOR:
997 EDITOR:
1000 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
998 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
1001 EDITOR: HG: Leave message empty to abort commit.
999 EDITOR: HG: Leave message empty to abort commit.
1002 EDITOR: HG: --
1000 EDITOR: HG: --
1003 EDITOR: HG: user: test
1001 EDITOR: HG: user: test
1004 EDITOR: HG: branch 'default'
1002 EDITOR: HG: branch 'default'
1005 EDITOR: HG: changed file1
1003 EDITOR: HG: changed file1
1006 EDITOR: HG: changed file2
1004 EDITOR: HG: changed file2
1007 $ printf 'f\nn\na\n' | hg split --color=debug \
1005 $ printf 'f\nn\na\n' | hg split --color=debug \
1008 > --config command-templates.oneline-summary='{label("rev", rev)} {desc}'
1006 > --config command-templates.oneline-summary='{label("rev", rev)} {desc}'
1009 [diff.diffline|diff --git a/file1 b/file1]
1007 [diff.diffline|diff --git a/file1 b/file1]
1010 1 hunks, 1 lines changed
1008 1 hunks, 1 lines changed
1011 [ ui.prompt|examine changes to 'file1'?
1009 [ ui.prompt|examine changes to 'file1'?
1012 (enter ? for help) [Ynesfdaq?]] [ ui.promptecho|f]
1010 (enter ? for help) [Ynesfdaq?]] [ ui.promptecho|f]
1013
1011
1014 [diff.diffline|diff --git a/file2 b/file2]
1012 [diff.diffline|diff --git a/file2 b/file2]
1015 1 hunks, 1 lines changed
1013 1 hunks, 1 lines changed
1016 [ ui.prompt|examine changes to 'file2'?
1014 [ ui.prompt|examine changes to 'file2'?
1017 (enter ? for help) [Ynesfdaq?]] [ ui.promptecho|n]
1015 (enter ? for help) [Ynesfdaq?]] [ ui.promptecho|n]
1018
1016
1019 EDITOR: HG: Splitting 6432c65c3078. Write commit message for the first split changeset.
1017 EDITOR: HG: Splitting 6432c65c3078. Write commit message for the first split changeset.
1020 EDITOR: split1, modifying file1
1018 EDITOR: split1, modifying file1
1021 EDITOR:
1019 EDITOR:
1022 EDITOR:
1020 EDITOR:
1023 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
1021 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
1024 EDITOR: HG: Leave message empty to abort commit.
1022 EDITOR: HG: Leave message empty to abort commit.
1025 EDITOR: HG: --
1023 EDITOR: HG: --
1026 EDITOR: HG: user: test
1024 EDITOR: HG: user: test
1027 EDITOR: HG: branch 'default'
1025 EDITOR: HG: branch 'default'
1028 EDITOR: HG: changed file1
1026 EDITOR: HG: changed file1
1029 [ ui.status|created new head]
1027 [ ui.status|created new head]
1030 [diff.diffline|diff --git a/file2 b/file2]
1028 [diff.diffline|diff --git a/file2 b/file2]
1031 1 hunks, 1 lines changed
1029 1 hunks, 1 lines changed
1032 [ ui.prompt|examine changes to 'file2'?
1030 [ ui.prompt|examine changes to 'file2'?
1033 (enter ? for help) [Ynesfdaq?]] [ ui.promptecho|a]
1031 (enter ? for help) [Ynesfdaq?]] [ ui.promptecho|a]
1034
1032
1035 EDITOR: HG: Splitting 6432c65c3078. So far it has been split into:
1033 EDITOR: HG: Splitting 6432c65c3078. So far it has been split into:
1036 EDITOR: HG: - 2 split2, modifying file2
1034 EDITOR: HG: - 2 split2, modifying file2
1037 EDITOR: HG: Write commit message for the next split changeset.
1035 EDITOR: HG: Write commit message for the next split changeset.
1038 EDITOR: split1, modifying file1
1036 EDITOR: split1, modifying file1
1039 EDITOR:
1037 EDITOR:
1040 EDITOR:
1038 EDITOR:
1041 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
1039 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
1042 EDITOR: HG: Leave message empty to abort commit.
1040 EDITOR: HG: Leave message empty to abort commit.
1043 EDITOR: HG: --
1041 EDITOR: HG: --
1044 EDITOR: HG: user: test
1042 EDITOR: HG: user: test
1045 EDITOR: HG: branch 'default'
1043 EDITOR: HG: branch 'default'
1046 EDITOR: HG: changed file2
1044 EDITOR: HG: changed file2
1047 [ ui.warning|transaction abort!]
1045 [ ui.warning|transaction abort!]
1048 [ ui.warning|rollback completed]
1046 [ ui.warning|rollback completed]
1049 [ ui.error|abort: empty commit message]
1047 [ ui.error|abort: empty commit message]
1050 [10]
1048 [10]
1051
1049
1052 Test that creating an empty split or "no-op"
1050 Test that creating an empty split or "no-op"
1053 (identical to original) commit doesn't cause chaos
1051 (identical to original) commit doesn't cause chaos
1054 --------------------------------------------------
1052 --------------------------------------------------
1055
1053
1056 $ hg init $TESTTMP/noop
1054 $ hg init $TESTTMP/noop
1057 $ cd $TESTTMP/noop
1055 $ cd $TESTTMP/noop
1058 $ echo r0 > r0
1056 $ echo r0 > r0
1059 $ hg ci -qAm r0
1057 $ hg ci -qAm r0
1060 $ hg phase -p
1058 $ hg phase -p
1061 $ echo foo > foo
1059 $ echo foo > foo
1062 $ hg ci -qAm foo
1060 $ hg ci -qAm foo
1063 $ hg log -G -T'{phase} {rev}:{node|short} {desc}'
1061 $ hg log -G -T'{phase} {rev}:{node|short} {desc}'
1064 @ draft 1:ae694b2901bb foo
1062 @ draft 1:ae694b2901bb foo
1065 |
1063 |
1066 o public 0:222799e2f90b r0
1064 o public 0:222799e2f90b r0
1067
1065
1068 $ printf 'd\na\n' | HGEDITOR=cat hg split || true
1066 $ printf 'd\na\n' | HGEDITOR=cat hg split || true
1069 diff --git a/foo b/foo
1067 diff --git a/foo b/foo
1070 new file mode 100644
1068 new file mode 100644
1071 examine changes to 'foo'?
1069 examine changes to 'foo'?
1072 (enter ? for help) [Ynesfdaq?] d
1070 (enter ? for help) [Ynesfdaq?] d
1073
1071
1074 no changes to record
1072 no changes to record
1075 diff --git a/foo b/foo
1073 diff --git a/foo b/foo
1076 new file mode 100644
1074 new file mode 100644
1077 examine changes to 'foo'?
1075 examine changes to 'foo'?
1078 (enter ? for help) [Ynesfdaq?] a
1076 (enter ? for help) [Ynesfdaq?] a
1079
1077
1080 HG: Splitting ae694b2901bb. Write commit message for the first split changeset.
1078 HG: Splitting ae694b2901bb. Write commit message for the first split changeset.
1081 foo
1079 foo
1082
1080
1083
1081
1084 HG: Enter commit message. Lines beginning with 'HG:' are removed.
1082 HG: Enter commit message. Lines beginning with 'HG:' are removed.
1085 HG: Leave message empty to abort commit.
1083 HG: Leave message empty to abort commit.
1086 HG: --
1084 HG: --
1087 HG: user: test
1085 HG: user: test
1088 HG: branch 'default'
1086 HG: branch 'default'
1089 HG: added foo
1087 HG: added foo
1090 warning: commit already existed in the repository!
1088 warning: commit already existed in the repository!
1091 $ hg log -G -T'{phase} {rev}:{node|short} {desc}'
1089 $ hg log -G -T'{phase} {rev}:{node|short} {desc}'
1092 @ draft 1:ae694b2901bb foo
1090 @ draft 1:ae694b2901bb foo
1093 |
1091 |
1094 o public 0:222799e2f90b r0
1092 o public 0:222799e2f90b r0
1095
1093
1096
1094
1097 Now try the same thing but modifying the message so we don't trigger the
1095 Now try the same thing but modifying the message so we don't trigger the
1098 identical changeset failures
1096 identical changeset failures
1099
1097
1100 $ hg init $TESTTMP/noop2
1098 $ hg init $TESTTMP/noop2
1101 $ cd $TESTTMP/noop2
1099 $ cd $TESTTMP/noop2
1102 $ echo r0 > r0
1100 $ echo r0 > r0
1103 $ hg ci -qAm r0
1101 $ hg ci -qAm r0
1104 $ hg phase -p
1102 $ hg phase -p
1105 $ echo foo > foo
1103 $ echo foo > foo
1106 $ hg ci -qAm foo
1104 $ hg ci -qAm foo
1107 $ hg log -G -T'{phase} {rev}:{node|short} {desc}'
1105 $ hg log -G -T'{phase} {rev}:{node|short} {desc}'
1108 @ draft 1:ae694b2901bb foo
1106 @ draft 1:ae694b2901bb foo
1109 |
1107 |
1110 o public 0:222799e2f90b r0
1108 o public 0:222799e2f90b r0
1111
1109
1112 $ cat > $TESTTMP/messages <<EOF
1110 $ cat > $TESTTMP/messages <<EOF
1113 > message1
1111 > message1
1114 > EOF
1112 > EOF
1115 $ printf 'd\na\n' | HGEDITOR="\"$PYTHON\" $TESTTMP/editor.py" hg split
1113 $ printf 'd\na\n' | HGEDITOR="\"$PYTHON\" $TESTTMP/editor.py" hg split
1116 diff --git a/foo b/foo
1114 diff --git a/foo b/foo
1117 new file mode 100644
1115 new file mode 100644
1118 examine changes to 'foo'?
1116 examine changes to 'foo'?
1119 (enter ? for help) [Ynesfdaq?] d
1117 (enter ? for help) [Ynesfdaq?] d
1120
1118
1121 no changes to record
1119 no changes to record
1122 diff --git a/foo b/foo
1120 diff --git a/foo b/foo
1123 new file mode 100644
1121 new file mode 100644
1124 examine changes to 'foo'?
1122 examine changes to 'foo'?
1125 (enter ? for help) [Ynesfdaq?] a
1123 (enter ? for help) [Ynesfdaq?] a
1126
1124
1127 EDITOR: HG: Splitting ae694b2901bb. Write commit message for the first split changeset.
1125 EDITOR: HG: Splitting ae694b2901bb. Write commit message for the first split changeset.
1128 EDITOR: foo
1126 EDITOR: foo
1129 EDITOR:
1127 EDITOR:
1130 EDITOR:
1128 EDITOR:
1131 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
1129 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
1132 EDITOR: HG: Leave message empty to abort commit.
1130 EDITOR: HG: Leave message empty to abort commit.
1133 EDITOR: HG: --
1131 EDITOR: HG: --
1134 EDITOR: HG: user: test
1132 EDITOR: HG: user: test
1135 EDITOR: HG: branch 'default'
1133 EDITOR: HG: branch 'default'
1136 EDITOR: HG: added foo
1134 EDITOR: HG: added foo
1137 created new head
1135 created new head
1138 saved backup bundle to $TESTTMP/noop2/.hg/strip-backup/ae694b2901bb-28e0b457-split.hg (obsstore-off !)
1136 saved backup bundle to $TESTTMP/noop2/.hg/strip-backup/ae694b2901bb-28e0b457-split.hg (obsstore-off !)
1139 $ hg log -G -T'{phase} {rev}:{node|short} {desc}'
1137 $ hg log -G -T'{phase} {rev}:{node|short} {desc}'
1140 @ draft 1:de675559d3f9 message1 (obsstore-off !)
1138 @ draft 1:de675559d3f9 message1 (obsstore-off !)
1141 @ draft 2:de675559d3f9 message1 (obsstore-on !)
1139 @ draft 2:de675559d3f9 message1 (obsstore-on !)
1142 |
1140 |
1143 o public 0:222799e2f90b r0
1141 o public 0:222799e2f90b r0
1144
1142
1145 #if obsstore-on
1143 #if obsstore-on
1146 $ hg debugobsolete
1144 $ hg debugobsolete
1147 ae694b2901bb8b0f8c4b5e075ddec0d63468d57a de675559d3f93ffc822c6eb7490e5c73033f17c7 0 * (glob)
1145 ae694b2901bb8b0f8c4b5e075ddec0d63468d57a de675559d3f93ffc822c6eb7490e5c73033f17c7 0 * (glob)
1148 #endif
1146 #endif
General Comments 0
You need to be logged in to leave comments. Login now