##// END OF EJS Templates
transaction: use a ".bck" extension for all backup file...
marmoute -
r51358:63dc24be default
parent child Browse files
Show More
@@ -1,960 +1,960 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 import errno
14 import errno
15 import os
15 import os
16
16
17 from .i18n import _
17 from .i18n import _
18 from . import (
18 from . import (
19 error,
19 error,
20 pycompat,
20 pycompat,
21 util,
21 util,
22 )
22 )
23 from .utils import stringutil
23 from .utils import stringutil
24
24
25 version = 2
25 version = 2
26
26
27 GEN_GROUP_ALL = b'all'
27 GEN_GROUP_ALL = b'all'
28 GEN_GROUP_PRE_FINALIZE = b'prefinalize'
28 GEN_GROUP_PRE_FINALIZE = b'prefinalize'
29 GEN_GROUP_POST_FINALIZE = b'postfinalize'
29 GEN_GROUP_POST_FINALIZE = b'postfinalize'
30
30
31
31
32 def active(func):
32 def active(func):
33 def _active(self, *args, **kwds):
33 def _active(self, *args, **kwds):
34 if self._count == 0:
34 if self._count == 0:
35 raise error.ProgrammingError(
35 raise error.ProgrammingError(
36 b'cannot use transaction when it is already committed/aborted'
36 b'cannot use transaction when it is already committed/aborted'
37 )
37 )
38 return func(self, *args, **kwds)
38 return func(self, *args, **kwds)
39
39
40 return _active
40 return _active
41
41
42
42
43 UNDO_BACKUP = b'%s.backupfiles'
43 UNDO_BACKUP = b'%s.backupfiles'
44
44
45 UNDO_FILES_MAY_NEED_CLEANUP = [
45 UNDO_FILES_MAY_NEED_CLEANUP = [
46 # legacy entries that might exists on disk from previous version:
46 # legacy entries that might exists on disk from previous version:
47 (b'store', b'%s.narrowspec'),
47 (b'store', b'%s.narrowspec'),
48 (b'plain', b'%s.narrowspec.dirstate'),
48 (b'plain', b'%s.narrowspec.dirstate'),
49 (b'plain', b'%s.branch'),
49 (b'plain', b'%s.branch'),
50 (b'plain', b'%s.bookmarks'),
50 (b'plain', b'%s.bookmarks'),
51 (b'store', b'%s.phaseroots'),
51 (b'store', b'%s.phaseroots'),
52 (b'plain', b'%s.dirstate'),
52 (b'plain', b'%s.dirstate'),
53 # files actually in uses today:
53 # files actually in uses today:
54 (b'plain', b'%s.desc'),
54 (b'plain', b'%s.desc'),
55 # Always delete undo last to make sure we detect that a clean up is needed if
55 # Always delete undo last to make sure we detect that a clean up is needed if
56 # the process is interrupted.
56 # the process is interrupted.
57 (b'store', b'%s'),
57 (b'store', b'%s'),
58 ]
58 ]
59
59
60
60
61 def cleanup_undo_files(report, vfsmap, undo_prefix=b'undo'):
61 def cleanup_undo_files(report, vfsmap, undo_prefix=b'undo'):
62 """remove "undo" files used by the rollback logic
62 """remove "undo" files used by the rollback logic
63
63
64 This is useful to prevent rollback running in situation were it does not
64 This is useful to prevent rollback running in situation were it does not
65 make sense. For example after a strip.
65 make sense. For example after a strip.
66 """
66 """
67 backup_listing = UNDO_BACKUP % undo_prefix
67 backup_listing = UNDO_BACKUP % undo_prefix
68
68
69 backup_entries = []
69 backup_entries = []
70 undo_files = []
70 undo_files = []
71 svfs = vfsmap[b'store']
71 svfs = vfsmap[b'store']
72 try:
72 try:
73 with svfs(backup_listing) as f:
73 with svfs(backup_listing) as f:
74 backup_entries = read_backup_files(report, f)
74 backup_entries = read_backup_files(report, f)
75 except OSError as e:
75 except OSError as e:
76 if e.errno != errno.ENOENT:
76 if e.errno != errno.ENOENT:
77 msg = _(b'could not read %s: %s\n')
77 msg = _(b'could not read %s: %s\n')
78 msg %= (svfs.join(backup_listing), stringutil.forcebytestr(e))
78 msg %= (svfs.join(backup_listing), stringutil.forcebytestr(e))
79 report(msg)
79 report(msg)
80
80
81 for location, f, backup_path, c in backup_entries:
81 for location, f, backup_path, c in backup_entries:
82 if location in vfsmap and backup_path:
82 if location in vfsmap and backup_path:
83 undo_files.append((vfsmap[location], backup_path))
83 undo_files.append((vfsmap[location], backup_path))
84
84
85 undo_files.append((svfs, backup_listing))
85 undo_files.append((svfs, backup_listing))
86 for location, undo_path in UNDO_FILES_MAY_NEED_CLEANUP:
86 for location, undo_path in UNDO_FILES_MAY_NEED_CLEANUP:
87 undo_files.append((vfsmap[location], undo_path % undo_prefix))
87 undo_files.append((vfsmap[location], undo_path % undo_prefix))
88 for undovfs, undofile in undo_files:
88 for undovfs, undofile in undo_files:
89 try:
89 try:
90 undovfs.unlink(undofile)
90 undovfs.unlink(undofile)
91 except OSError as e:
91 except OSError as e:
92 if e.errno != errno.ENOENT:
92 if e.errno != errno.ENOENT:
93 msg = _(b'error removing %s: %s\n')
93 msg = _(b'error removing %s: %s\n')
94 msg %= (undovfs.join(undofile), stringutil.forcebytestr(e))
94 msg %= (undovfs.join(undofile), stringutil.forcebytestr(e))
95 report(msg)
95 report(msg)
96
96
97
97
98 def _playback(
98 def _playback(
99 journal,
99 journal,
100 report,
100 report,
101 opener,
101 opener,
102 vfsmap,
102 vfsmap,
103 entries,
103 entries,
104 backupentries,
104 backupentries,
105 unlink=True,
105 unlink=True,
106 checkambigfiles=None,
106 checkambigfiles=None,
107 ):
107 ):
108 """rollback a transaction :
108 """rollback a transaction :
109 - truncate files that have been appended to
109 - truncate files that have been appended to
110 - restore file backups
110 - restore file backups
111 - delete temporary files
111 - delete temporary files
112 """
112 """
113 backupfiles = []
113 backupfiles = []
114
114
115 def restore_one_backup(vfs, f, b, checkambig):
115 def restore_one_backup(vfs, f, b, checkambig):
116 filepath = vfs.join(f)
116 filepath = vfs.join(f)
117 backuppath = vfs.join(b)
117 backuppath = vfs.join(b)
118 try:
118 try:
119 util.copyfile(backuppath, filepath, checkambig=checkambig)
119 util.copyfile(backuppath, filepath, checkambig=checkambig)
120 backupfiles.append((vfs, b))
120 backupfiles.append((vfs, b))
121 except IOError as exc:
121 except IOError as exc:
122 e_msg = stringutil.forcebytestr(exc)
122 e_msg = stringutil.forcebytestr(exc)
123 report(_(b"failed to recover %s (%s)\n") % (f, e_msg))
123 report(_(b"failed to recover %s (%s)\n") % (f, e_msg))
124 raise
124 raise
125
125
126 # gather all backup files that impact the store
126 # gather all backup files that impact the store
127 # (we need this to detect files that are both backed up and truncated)
127 # (we need this to detect files that are both backed up and truncated)
128 store_backup = {}
128 store_backup = {}
129 for entry in backupentries:
129 for entry in backupentries:
130 location, file_path, backup_path, cache = entry
130 location, file_path, backup_path, cache = entry
131 vfs = vfsmap[location]
131 vfs = vfsmap[location]
132 is_store = vfs.join(b'') == opener.join(b'')
132 is_store = vfs.join(b'') == opener.join(b'')
133 if is_store and file_path and backup_path:
133 if is_store and file_path and backup_path:
134 store_backup[file_path] = entry
134 store_backup[file_path] = entry
135 copy_done = set()
135 copy_done = set()
136
136
137 # truncate all file `f` to offset `o`
137 # truncate all file `f` to offset `o`
138 for f, o in sorted(dict(entries).items()):
138 for f, o in sorted(dict(entries).items()):
139 # if we have a backup for `f`, we should restore it first and truncate
139 # if we have a backup for `f`, we should restore it first and truncate
140 # the restored file
140 # the restored file
141 bck_entry = store_backup.get(f)
141 bck_entry = store_backup.get(f)
142 if bck_entry is not None:
142 if bck_entry is not None:
143 location, file_path, backup_path, cache = bck_entry
143 location, file_path, backup_path, cache = bck_entry
144 checkambig = False
144 checkambig = False
145 if checkambigfiles:
145 if checkambigfiles:
146 checkambig = (file_path, location) in checkambigfiles
146 checkambig = (file_path, location) in checkambigfiles
147 restore_one_backup(opener, file_path, backup_path, checkambig)
147 restore_one_backup(opener, file_path, backup_path, checkambig)
148 copy_done.add(bck_entry)
148 copy_done.add(bck_entry)
149 # truncate the file to its pre-transaction size
149 # truncate the file to its pre-transaction size
150 if o or not unlink:
150 if o or not unlink:
151 checkambig = checkambigfiles and (f, b'') in checkambigfiles
151 checkambig = checkambigfiles and (f, b'') in checkambigfiles
152 try:
152 try:
153 fp = opener(f, b'a', checkambig=checkambig)
153 fp = opener(f, b'a', checkambig=checkambig)
154 if fp.tell() < o:
154 if fp.tell() < o:
155 raise error.Abort(
155 raise error.Abort(
156 _(
156 _(
157 b"attempted to truncate %s to %d bytes, but it was "
157 b"attempted to truncate %s to %d bytes, but it was "
158 b"already %d bytes\n"
158 b"already %d bytes\n"
159 )
159 )
160 % (f, o, fp.tell())
160 % (f, o, fp.tell())
161 )
161 )
162 fp.truncate(o)
162 fp.truncate(o)
163 fp.close()
163 fp.close()
164 except IOError:
164 except IOError:
165 report(_(b"failed to truncate %s\n") % f)
165 report(_(b"failed to truncate %s\n") % f)
166 raise
166 raise
167 else:
167 else:
168 # delete empty file
168 # delete empty file
169 try:
169 try:
170 opener.unlink(f)
170 opener.unlink(f)
171 except FileNotFoundError:
171 except FileNotFoundError:
172 pass
172 pass
173 # restore backed up files and clean up temporary files
173 # restore backed up files and clean up temporary files
174 for entry in backupentries:
174 for entry in backupentries:
175 if entry in copy_done:
175 if entry in copy_done:
176 continue
176 continue
177 l, f, b, c = entry
177 l, f, b, c = entry
178 if l not in vfsmap and c:
178 if l not in vfsmap and c:
179 report(b"couldn't handle %s: unknown cache location %s\n" % (b, l))
179 report(b"couldn't handle %s: unknown cache location %s\n" % (b, l))
180 vfs = vfsmap[l]
180 vfs = vfsmap[l]
181 try:
181 try:
182 checkambig = checkambigfiles and (f, l) in checkambigfiles
182 checkambig = checkambigfiles and (f, l) in checkambigfiles
183 if f and b:
183 if f and b:
184 restore_one_backup(vfs, f, b, checkambig)
184 restore_one_backup(vfs, f, b, checkambig)
185 else:
185 else:
186 target = f or b
186 target = f or b
187 try:
187 try:
188 vfs.unlink(target)
188 vfs.unlink(target)
189 except FileNotFoundError:
189 except FileNotFoundError:
190 # This is fine because
190 # This is fine because
191 #
191 #
192 # either we are trying to delete the main file, and it is
192 # either we are trying to delete the main file, and it is
193 # already deleted.
193 # already deleted.
194 #
194 #
195 # or we are trying to delete a temporary file and it is
195 # or we are trying to delete a temporary file and it is
196 # already deleted.
196 # already deleted.
197 #
197 #
198 # in both case, our target result (delete the file) is
198 # in both case, our target result (delete the file) is
199 # already achieved.
199 # already achieved.
200 pass
200 pass
201 except (IOError, OSError, error.Abort):
201 except (IOError, OSError, error.Abort):
202 if not c:
202 if not c:
203 raise
203 raise
204
204
205 # cleanup transaction state file and the backups file
205 # cleanup transaction state file and the backups file
206 backuppath = b"%s.backupfiles" % journal
206 backuppath = b"%s.backupfiles" % journal
207 if opener.exists(backuppath):
207 if opener.exists(backuppath):
208 opener.unlink(backuppath)
208 opener.unlink(backuppath)
209 opener.unlink(journal)
209 opener.unlink(journal)
210 try:
210 try:
211 for vfs, f in backupfiles:
211 for vfs, f in backupfiles:
212 if vfs.exists(f):
212 if vfs.exists(f):
213 vfs.unlink(f)
213 vfs.unlink(f)
214 except (IOError, OSError, error.Abort):
214 except (IOError, OSError, error.Abort):
215 # only pure backup file remains, it is sage to ignore any error
215 # only pure backup file remains, it is sage to ignore any error
216 pass
216 pass
217
217
218
218
219 class transaction(util.transactional):
219 class transaction(util.transactional):
220 def __init__(
220 def __init__(
221 self,
221 self,
222 report,
222 report,
223 opener,
223 opener,
224 vfsmap,
224 vfsmap,
225 journalname,
225 journalname,
226 undoname=None,
226 undoname=None,
227 after=None,
227 after=None,
228 createmode=None,
228 createmode=None,
229 validator=None,
229 validator=None,
230 releasefn=None,
230 releasefn=None,
231 checkambigfiles=None,
231 checkambigfiles=None,
232 name='<unnamed>',
232 name='<unnamed>',
233 ):
233 ):
234 """Begin a new transaction
234 """Begin a new transaction
235
235
236 Begins a new transaction that allows rolling back writes in the event of
236 Begins a new transaction that allows rolling back writes in the event of
237 an exception.
237 an exception.
238
238
239 * `after`: called after the transaction has been committed
239 * `after`: called after the transaction has been committed
240 * `createmode`: the mode of the journal file that will be created
240 * `createmode`: the mode of the journal file that will be created
241 * `releasefn`: called after releasing (with transaction and result)
241 * `releasefn`: called after releasing (with transaction and result)
242
242
243 `checkambigfiles` is a set of (path, vfs-location) tuples,
243 `checkambigfiles` is a set of (path, vfs-location) tuples,
244 which determine whether file stat ambiguity should be avoided
244 which determine whether file stat ambiguity should be avoided
245 for corresponded files.
245 for corresponded files.
246 """
246 """
247 self._count = 1
247 self._count = 1
248 self._usages = 1
248 self._usages = 1
249 self._report = report
249 self._report = report
250 # a vfs to the store content
250 # a vfs to the store content
251 self._opener = opener
251 self._opener = opener
252 # a map to access file in various {location -> vfs}
252 # a map to access file in various {location -> vfs}
253 vfsmap = vfsmap.copy()
253 vfsmap = vfsmap.copy()
254 vfsmap[b''] = opener # set default value
254 vfsmap[b''] = opener # set default value
255 self._vfsmap = vfsmap
255 self._vfsmap = vfsmap
256 self._after = after
256 self._after = after
257 self._offsetmap = {}
257 self._offsetmap = {}
258 self._newfiles = set()
258 self._newfiles = set()
259 self._journal = journalname
259 self._journal = journalname
260 self._journal_files = []
260 self._journal_files = []
261 self._undoname = undoname
261 self._undoname = undoname
262 self._queue = []
262 self._queue = []
263 # A callback to do something just after releasing transaction.
263 # A callback to do something just after releasing transaction.
264 if releasefn is None:
264 if releasefn is None:
265 releasefn = lambda tr, success: None
265 releasefn = lambda tr, success: None
266 self._releasefn = releasefn
266 self._releasefn = releasefn
267
267
268 self._checkambigfiles = set()
268 self._checkambigfiles = set()
269 if checkambigfiles:
269 if checkambigfiles:
270 self._checkambigfiles.update(checkambigfiles)
270 self._checkambigfiles.update(checkambigfiles)
271
271
272 self._names = [name]
272 self._names = [name]
273
273
274 # A dict dedicated to precisely tracking the changes introduced in the
274 # A dict dedicated to precisely tracking the changes introduced in the
275 # transaction.
275 # transaction.
276 self.changes = {}
276 self.changes = {}
277
277
278 # a dict of arguments to be passed to hooks
278 # a dict of arguments to be passed to hooks
279 self.hookargs = {}
279 self.hookargs = {}
280 self._file = opener.open(self._journal, b"w+")
280 self._file = opener.open(self._journal, b"w+")
281
281
282 # a list of ('location', 'path', 'backuppath', cache) entries.
282 # a list of ('location', 'path', 'backuppath', cache) entries.
283 # - if 'backuppath' is empty, no file existed at backup time
283 # - if 'backuppath' is empty, no file existed at backup time
284 # - if 'path' is empty, this is a temporary transaction file
284 # - if 'path' is empty, this is a temporary transaction file
285 # - if 'location' is not empty, the path is outside main opener reach.
285 # - if 'location' is not empty, the path is outside main opener reach.
286 # use 'location' value as a key in a vfsmap to find the right 'vfs'
286 # use 'location' value as a key in a vfsmap to find the right 'vfs'
287 # (cache is currently unused)
287 # (cache is currently unused)
288 self._backupentries = []
288 self._backupentries = []
289 self._backupmap = {}
289 self._backupmap = {}
290 self._backupjournal = b"%s.backupfiles" % self._journal
290 self._backupjournal = b"%s.backupfiles" % self._journal
291 self._backupsfile = opener.open(self._backupjournal, b'w')
291 self._backupsfile = opener.open(self._backupjournal, b'w')
292 self._backupsfile.write(b'%d\n' % version)
292 self._backupsfile.write(b'%d\n' % version)
293
293
294 if createmode is not None:
294 if createmode is not None:
295 opener.chmod(self._journal, createmode & 0o666)
295 opener.chmod(self._journal, createmode & 0o666)
296 opener.chmod(self._backupjournal, createmode & 0o666)
296 opener.chmod(self._backupjournal, createmode & 0o666)
297
297
298 # hold file generations to be performed on commit
298 # hold file generations to be performed on commit
299 self._filegenerators = {}
299 self._filegenerators = {}
300 # hold callback to write pending data for hooks
300 # hold callback to write pending data for hooks
301 self._pendingcallback = {}
301 self._pendingcallback = {}
302 # True is any pending data have been written ever
302 # True is any pending data have been written ever
303 self._anypending = False
303 self._anypending = False
304 # holds callback to call when writing the transaction
304 # holds callback to call when writing the transaction
305 self._finalizecallback = {}
305 self._finalizecallback = {}
306 # holds callback to call when validating the transaction
306 # holds callback to call when validating the transaction
307 # should raise exception if anything is wrong
307 # should raise exception if anything is wrong
308 self._validatecallback = {}
308 self._validatecallback = {}
309 if validator is not None:
309 if validator is not None:
310 self._validatecallback[b'001-userhooks'] = validator
310 self._validatecallback[b'001-userhooks'] = validator
311 # hold callback for post transaction close
311 # hold callback for post transaction close
312 self._postclosecallback = {}
312 self._postclosecallback = {}
313 # holds callbacks to call during abort
313 # holds callbacks to call during abort
314 self._abortcallback = {}
314 self._abortcallback = {}
315
315
316 def __repr__(self):
316 def __repr__(self):
317 name = b'/'.join(self._names)
317 name = b'/'.join(self._names)
318 return '<transaction name=%s, count=%d, usages=%d>' % (
318 return '<transaction name=%s, count=%d, usages=%d>' % (
319 name,
319 name,
320 self._count,
320 self._count,
321 self._usages,
321 self._usages,
322 )
322 )
323
323
324 def __del__(self):
324 def __del__(self):
325 if self._journal:
325 if self._journal:
326 self._abort()
326 self._abort()
327
327
328 @property
328 @property
329 def finalized(self):
329 def finalized(self):
330 return self._finalizecallback is None
330 return self._finalizecallback is None
331
331
332 @active
332 @active
333 def startgroup(self):
333 def startgroup(self):
334 """delay registration of file entry
334 """delay registration of file entry
335
335
336 This is used by strip to delay vision of strip offset. The transaction
336 This is used by strip to delay vision of strip offset. The transaction
337 sees either none or all of the strip actions to be done."""
337 sees either none or all of the strip actions to be done."""
338 self._queue.append([])
338 self._queue.append([])
339
339
340 @active
340 @active
341 def endgroup(self):
341 def endgroup(self):
342 """apply delayed registration of file entry.
342 """apply delayed registration of file entry.
343
343
344 This is used by strip to delay vision of strip offset. The transaction
344 This is used by strip to delay vision of strip offset. The transaction
345 sees either none or all of the strip actions to be done."""
345 sees either none or all of the strip actions to be done."""
346 q = self._queue.pop()
346 q = self._queue.pop()
347 for f, o in q:
347 for f, o in q:
348 self._addentry(f, o)
348 self._addentry(f, o)
349
349
350 @active
350 @active
351 def add(self, file, offset):
351 def add(self, file, offset):
352 """record the state of an append-only file before update"""
352 """record the state of an append-only file before update"""
353 if (
353 if (
354 file in self._newfiles
354 file in self._newfiles
355 or file in self._offsetmap
355 or file in self._offsetmap
356 or file in self._backupmap
356 or file in self._backupmap
357 ):
357 ):
358 return
358 return
359 if self._queue:
359 if self._queue:
360 self._queue[-1].append((file, offset))
360 self._queue[-1].append((file, offset))
361 return
361 return
362
362
363 self._addentry(file, offset)
363 self._addentry(file, offset)
364
364
365 def _addentry(self, file, offset):
365 def _addentry(self, file, offset):
366 """add a append-only entry to memory and on-disk state"""
366 """add a append-only entry to memory and on-disk state"""
367 if (
367 if (
368 file in self._newfiles
368 file in self._newfiles
369 or file in self._offsetmap
369 or file in self._offsetmap
370 or file in self._backupmap
370 or file in self._backupmap
371 ):
371 ):
372 return
372 return
373 if offset:
373 if offset:
374 self._offsetmap[file] = offset
374 self._offsetmap[file] = offset
375 else:
375 else:
376 self._newfiles.add(file)
376 self._newfiles.add(file)
377 # add enough data to the journal to do the truncate
377 # add enough data to the journal to do the truncate
378 self._file.write(b"%s\0%d\n" % (file, offset))
378 self._file.write(b"%s\0%d\n" % (file, offset))
379 self._file.flush()
379 self._file.flush()
380
380
381 @active
381 @active
382 def addbackup(self, file, hardlink=True, location=b'', for_offset=False):
382 def addbackup(self, file, hardlink=True, location=b'', for_offset=False):
383 """Adds a backup of the file to the transaction
383 """Adds a backup of the file to the transaction
384
384
385 Calling addbackup() creates a hardlink backup of the specified file
385 Calling addbackup() creates a hardlink backup of the specified file
386 that is used to recover the file in the event of the transaction
386 that is used to recover the file in the event of the transaction
387 aborting.
387 aborting.
388
388
389 * `file`: the file path, relative to .hg/store
389 * `file`: the file path, relative to .hg/store
390 * `hardlink`: use a hardlink to quickly create the backup
390 * `hardlink`: use a hardlink to quickly create the backup
391
391
392 If `for_offset` is set, we expect a offset for this file to have been previously recorded
392 If `for_offset` is set, we expect a offset for this file to have been previously recorded
393 """
393 """
394 if self._queue:
394 if self._queue:
395 msg = b'cannot use transaction.addbackup inside "group"'
395 msg = b'cannot use transaction.addbackup inside "group"'
396 raise error.ProgrammingError(msg)
396 raise error.ProgrammingError(msg)
397
397
398 if file in self._newfiles or file in self._backupmap:
398 if file in self._newfiles or file in self._backupmap:
399 return
399 return
400 elif file in self._offsetmap and not for_offset:
400 elif file in self._offsetmap and not for_offset:
401 return
401 return
402 elif for_offset and file not in self._offsetmap:
402 elif for_offset and file not in self._offsetmap:
403 msg = (
403 msg = (
404 'calling `addbackup` with `for_offmap=True`, '
404 'calling `addbackup` with `for_offmap=True`, '
405 'but no offset recorded: [%r] %r'
405 'but no offset recorded: [%r] %r'
406 )
406 )
407 msg %= (location, file)
407 msg %= (location, file)
408 raise error.ProgrammingError(msg)
408 raise error.ProgrammingError(msg)
409
409
410 vfs = self._vfsmap[location]
410 vfs = self._vfsmap[location]
411 dirname, filename = vfs.split(file)
411 dirname, filename = vfs.split(file)
412 backupfilename = b"%s.backup.%s" % (self._journal, filename)
412 backupfilename = b"%s.backup.%s.bck" % (self._journal, filename)
413 backupfile = vfs.reljoin(dirname, backupfilename)
413 backupfile = vfs.reljoin(dirname, backupfilename)
414 if vfs.exists(file):
414 if vfs.exists(file):
415 filepath = vfs.join(file)
415 filepath = vfs.join(file)
416 backuppath = vfs.join(backupfile)
416 backuppath = vfs.join(backupfile)
417 # store encoding may result in different directory here.
417 # store encoding may result in different directory here.
418 # so we have to ensure the destination directory exist
418 # so we have to ensure the destination directory exist
419 final_dir_name = os.path.dirname(backuppath)
419 final_dir_name = os.path.dirname(backuppath)
420 util.makedirs(final_dir_name, mode=vfs.createmode, notindexed=True)
420 util.makedirs(final_dir_name, mode=vfs.createmode, notindexed=True)
421 # then we can copy the backup
421 # then we can copy the backup
422 util.copyfile(filepath, backuppath, hardlink=hardlink)
422 util.copyfile(filepath, backuppath, hardlink=hardlink)
423 else:
423 else:
424 backupfile = b''
424 backupfile = b''
425
425
426 self._addbackupentry((location, file, backupfile, False))
426 self._addbackupentry((location, file, backupfile, False))
427
427
428 def _addbackupentry(self, entry):
428 def _addbackupentry(self, entry):
429 """register a new backup entry and write it to disk"""
429 """register a new backup entry and write it to disk"""
430 self._backupentries.append(entry)
430 self._backupentries.append(entry)
431 self._backupmap[entry[1]] = len(self._backupentries) - 1
431 self._backupmap[entry[1]] = len(self._backupentries) - 1
432 self._backupsfile.write(b"%s\0%s\0%s\0%d\n" % entry)
432 self._backupsfile.write(b"%s\0%s\0%s\0%d\n" % entry)
433 self._backupsfile.flush()
433 self._backupsfile.flush()
434
434
435 @active
435 @active
436 def registertmp(self, tmpfile, location=b''):
436 def registertmp(self, tmpfile, location=b''):
437 """register a temporary transaction file
437 """register a temporary transaction file
438
438
439 Such files will be deleted when the transaction exits (on both
439 Such files will be deleted when the transaction exits (on both
440 failure and success).
440 failure and success).
441 """
441 """
442 self._addbackupentry((location, b'', tmpfile, False))
442 self._addbackupentry((location, b'', tmpfile, False))
443
443
444 @active
444 @active
445 def addfilegenerator(
445 def addfilegenerator(
446 self,
446 self,
447 genid,
447 genid,
448 filenames,
448 filenames,
449 genfunc,
449 genfunc,
450 order=0,
450 order=0,
451 location=b'',
451 location=b'',
452 post_finalize=False,
452 post_finalize=False,
453 ):
453 ):
454 """add a function to generates some files at transaction commit
454 """add a function to generates some files at transaction commit
455
455
456 The `genfunc` argument is a function capable of generating proper
456 The `genfunc` argument is a function capable of generating proper
457 content of each entry in the `filename` tuple.
457 content of each entry in the `filename` tuple.
458
458
459 At transaction close time, `genfunc` will be called with one file
459 At transaction close time, `genfunc` will be called with one file
460 object argument per entries in `filenames`.
460 object argument per entries in `filenames`.
461
461
462 The transaction itself is responsible for the backup, creation and
462 The transaction itself is responsible for the backup, creation and
463 final write of such file.
463 final write of such file.
464
464
465 The `genid` argument is used to ensure the same set of file is only
465 The `genid` argument is used to ensure the same set of file is only
466 generated once. Call to `addfilegenerator` for a `genid` already
466 generated once. Call to `addfilegenerator` for a `genid` already
467 present will overwrite the old entry.
467 present will overwrite the old entry.
468
468
469 The `order` argument may be used to control the order in which multiple
469 The `order` argument may be used to control the order in which multiple
470 generator will be executed.
470 generator will be executed.
471
471
472 The `location` arguments may be used to indicate the files are located
472 The `location` arguments may be used to indicate the files are located
473 outside of the the standard directory for transaction. It should match
473 outside of the the standard directory for transaction. It should match
474 one of the key of the `transaction.vfsmap` dictionary.
474 one of the key of the `transaction.vfsmap` dictionary.
475
475
476 The `post_finalize` argument can be set to `True` for file generation
476 The `post_finalize` argument can be set to `True` for file generation
477 that must be run after the transaction has been finalized.
477 that must be run after the transaction has been finalized.
478 """
478 """
479 # For now, we are unable to do proper backup and restore of custom vfs
479 # For now, we are unable to do proper backup and restore of custom vfs
480 # but for bookmarks that are handled outside this mechanism.
480 # but for bookmarks that are handled outside this mechanism.
481 entry = (order, filenames, genfunc, location, post_finalize)
481 entry = (order, filenames, genfunc, location, post_finalize)
482 self._filegenerators[genid] = entry
482 self._filegenerators[genid] = entry
483
483
484 @active
484 @active
485 def removefilegenerator(self, genid):
485 def removefilegenerator(self, genid):
486 """reverse of addfilegenerator, remove a file generator function"""
486 """reverse of addfilegenerator, remove a file generator function"""
487 if genid in self._filegenerators:
487 if genid in self._filegenerators:
488 del self._filegenerators[genid]
488 del self._filegenerators[genid]
489
489
490 def _generatefiles(self, suffix=b'', group=GEN_GROUP_ALL):
490 def _generatefiles(self, suffix=b'', group=GEN_GROUP_ALL):
491 # write files registered for generation
491 # write files registered for generation
492 any = False
492 any = False
493
493
494 if group == GEN_GROUP_ALL:
494 if group == GEN_GROUP_ALL:
495 skip_post = skip_pre = False
495 skip_post = skip_pre = False
496 else:
496 else:
497 skip_pre = group == GEN_GROUP_POST_FINALIZE
497 skip_pre = group == GEN_GROUP_POST_FINALIZE
498 skip_post = group == GEN_GROUP_PRE_FINALIZE
498 skip_post = group == GEN_GROUP_PRE_FINALIZE
499
499
500 for id, entry in sorted(self._filegenerators.items()):
500 for id, entry in sorted(self._filegenerators.items()):
501 any = True
501 any = True
502 order, filenames, genfunc, location, post_finalize = entry
502 order, filenames, genfunc, location, post_finalize = entry
503
503
504 # for generation at closing, check if it's before or after finalize
504 # for generation at closing, check if it's before or after finalize
505 if skip_post and post_finalize:
505 if skip_post and post_finalize:
506 continue
506 continue
507 elif skip_pre and not post_finalize:
507 elif skip_pre and not post_finalize:
508 continue
508 continue
509
509
510 vfs = self._vfsmap[location]
510 vfs = self._vfsmap[location]
511 files = []
511 files = []
512 try:
512 try:
513 for name in filenames:
513 for name in filenames:
514 name += suffix
514 name += suffix
515 if suffix:
515 if suffix:
516 self.registertmp(name, location=location)
516 self.registertmp(name, location=location)
517 checkambig = False
517 checkambig = False
518 else:
518 else:
519 self.addbackup(name, location=location)
519 self.addbackup(name, location=location)
520 checkambig = (name, location) in self._checkambigfiles
520 checkambig = (name, location) in self._checkambigfiles
521 files.append(
521 files.append(
522 vfs(name, b'w', atomictemp=True, checkambig=checkambig)
522 vfs(name, b'w', atomictemp=True, checkambig=checkambig)
523 )
523 )
524 genfunc(*files)
524 genfunc(*files)
525 for f in files:
525 for f in files:
526 f.close()
526 f.close()
527 # skip discard() loop since we're sure no open file remains
527 # skip discard() loop since we're sure no open file remains
528 del files[:]
528 del files[:]
529 finally:
529 finally:
530 for f in files:
530 for f in files:
531 f.discard()
531 f.discard()
532 return any
532 return any
533
533
534 @active
534 @active
535 def findoffset(self, file):
535 def findoffset(self, file):
536 if file in self._newfiles:
536 if file in self._newfiles:
537 return 0
537 return 0
538 return self._offsetmap.get(file)
538 return self._offsetmap.get(file)
539
539
540 @active
540 @active
541 def readjournal(self):
541 def readjournal(self):
542 self._file.seek(0)
542 self._file.seek(0)
543 entries = []
543 entries = []
544 for l in self._file.readlines():
544 for l in self._file.readlines():
545 file, troffset = l.split(b'\0')
545 file, troffset = l.split(b'\0')
546 entries.append((file, int(troffset)))
546 entries.append((file, int(troffset)))
547 return entries
547 return entries
548
548
549 @active
549 @active
550 def replace(self, file, offset):
550 def replace(self, file, offset):
551 """
551 """
552 replace can only replace already committed entries
552 replace can only replace already committed entries
553 that are not pending in the queue
553 that are not pending in the queue
554 """
554 """
555 if file in self._newfiles:
555 if file in self._newfiles:
556 if not offset:
556 if not offset:
557 return
557 return
558 self._newfiles.remove(file)
558 self._newfiles.remove(file)
559 self._offsetmap[file] = offset
559 self._offsetmap[file] = offset
560 elif file in self._offsetmap:
560 elif file in self._offsetmap:
561 if not offset:
561 if not offset:
562 del self._offsetmap[file]
562 del self._offsetmap[file]
563 self._newfiles.add(file)
563 self._newfiles.add(file)
564 else:
564 else:
565 self._offsetmap[file] = offset
565 self._offsetmap[file] = offset
566 else:
566 else:
567 raise KeyError(file)
567 raise KeyError(file)
568 self._file.write(b"%s\0%d\n" % (file, offset))
568 self._file.write(b"%s\0%d\n" % (file, offset))
569 self._file.flush()
569 self._file.flush()
570
570
571 @active
571 @active
572 def nest(self, name='<unnamed>'):
572 def nest(self, name='<unnamed>'):
573 self._count += 1
573 self._count += 1
574 self._usages += 1
574 self._usages += 1
575 self._names.append(name)
575 self._names.append(name)
576 return self
576 return self
577
577
578 def release(self):
578 def release(self):
579 if self._count > 0:
579 if self._count > 0:
580 self._usages -= 1
580 self._usages -= 1
581 if self._names:
581 if self._names:
582 self._names.pop()
582 self._names.pop()
583 # if the transaction scopes are left without being closed, fail
583 # if the transaction scopes are left without being closed, fail
584 if self._count > 0 and self._usages == 0:
584 if self._count > 0 and self._usages == 0:
585 self._abort()
585 self._abort()
586
586
587 def running(self):
587 def running(self):
588 return self._count > 0
588 return self._count > 0
589
589
590 def addpending(self, category, callback):
590 def addpending(self, category, callback):
591 """add a callback to be called when the transaction is pending
591 """add a callback to be called when the transaction is pending
592
592
593 The transaction will be given as callback's first argument.
593 The transaction will be given as callback's first argument.
594
594
595 Category is a unique identifier to allow overwriting an old callback
595 Category is a unique identifier to allow overwriting an old callback
596 with a newer callback.
596 with a newer callback.
597 """
597 """
598 self._pendingcallback[category] = callback
598 self._pendingcallback[category] = callback
599
599
600 @active
600 @active
601 def writepending(self):
601 def writepending(self):
602 """write pending file to temporary version
602 """write pending file to temporary version
603
603
604 This is used to allow hooks to view a transaction before commit"""
604 This is used to allow hooks to view a transaction before commit"""
605 categories = sorted(self._pendingcallback)
605 categories = sorted(self._pendingcallback)
606 for cat in categories:
606 for cat in categories:
607 # remove callback since the data will have been flushed
607 # remove callback since the data will have been flushed
608 any = self._pendingcallback.pop(cat)(self)
608 any = self._pendingcallback.pop(cat)(self)
609 self._anypending = self._anypending or any
609 self._anypending = self._anypending or any
610 self._anypending |= self._generatefiles(suffix=b'.pending')
610 self._anypending |= self._generatefiles(suffix=b'.pending')
611 return self._anypending
611 return self._anypending
612
612
613 @active
613 @active
614 def hasfinalize(self, category):
614 def hasfinalize(self, category):
615 """check is a callback already exist for a category"""
615 """check is a callback already exist for a category"""
616 return category in self._finalizecallback
616 return category in self._finalizecallback
617
617
618 @active
618 @active
619 def addfinalize(self, category, callback):
619 def addfinalize(self, category, callback):
620 """add a callback to be called when the transaction is closed
620 """add a callback to be called when the transaction is closed
621
621
622 The transaction will be given as callback's first argument.
622 The transaction will be given as callback's first argument.
623
623
624 Category is a unique identifier to allow overwriting old callbacks with
624 Category is a unique identifier to allow overwriting old callbacks with
625 newer callbacks.
625 newer callbacks.
626 """
626 """
627 self._finalizecallback[category] = callback
627 self._finalizecallback[category] = callback
628
628
629 @active
629 @active
630 def addpostclose(self, category, callback):
630 def addpostclose(self, category, callback):
631 """add or replace a callback to be called after the transaction closed
631 """add or replace a callback to be called after the transaction closed
632
632
633 The transaction will be given as callback's first argument.
633 The transaction will be given as callback's first argument.
634
634
635 Category is a unique identifier to allow overwriting an old callback
635 Category is a unique identifier to allow overwriting an old callback
636 with a newer callback.
636 with a newer callback.
637 """
637 """
638 self._postclosecallback[category] = callback
638 self._postclosecallback[category] = callback
639
639
640 @active
640 @active
641 def getpostclose(self, category):
641 def getpostclose(self, category):
642 """return a postclose callback added before, or None"""
642 """return a postclose callback added before, or None"""
643 return self._postclosecallback.get(category, None)
643 return self._postclosecallback.get(category, None)
644
644
645 @active
645 @active
646 def addabort(self, category, callback):
646 def addabort(self, category, callback):
647 """add a callback to be called when the transaction is aborted.
647 """add a callback to be called when the transaction is aborted.
648
648
649 The transaction will be given as the first argument to the callback.
649 The transaction will be given as the first argument to the callback.
650
650
651 Category is a unique identifier to allow overwriting an old callback
651 Category is a unique identifier to allow overwriting an old callback
652 with a newer callback.
652 with a newer callback.
653 """
653 """
654 self._abortcallback[category] = callback
654 self._abortcallback[category] = callback
655
655
656 @active
656 @active
657 def addvalidator(self, category, callback):
657 def addvalidator(self, category, callback):
658 """adds a callback to be called when validating the transaction.
658 """adds a callback to be called when validating the transaction.
659
659
660 The transaction will be given as the first argument to the callback.
660 The transaction will be given as the first argument to the callback.
661
661
662 callback should raise exception if to abort transaction"""
662 callback should raise exception if to abort transaction"""
663 self._validatecallback[category] = callback
663 self._validatecallback[category] = callback
664
664
665 @active
665 @active
666 def close(self):
666 def close(self):
667 '''commit the transaction'''
667 '''commit the transaction'''
668 if self._count == 1:
668 if self._count == 1:
669 for category in sorted(self._validatecallback):
669 for category in sorted(self._validatecallback):
670 self._validatecallback[category](self)
670 self._validatecallback[category](self)
671 self._validatecallback = None # Help prevent cycles.
671 self._validatecallback = None # Help prevent cycles.
672 self._generatefiles(group=GEN_GROUP_PRE_FINALIZE)
672 self._generatefiles(group=GEN_GROUP_PRE_FINALIZE)
673 while self._finalizecallback:
673 while self._finalizecallback:
674 callbacks = self._finalizecallback
674 callbacks = self._finalizecallback
675 self._finalizecallback = {}
675 self._finalizecallback = {}
676 categories = sorted(callbacks)
676 categories = sorted(callbacks)
677 for cat in categories:
677 for cat in categories:
678 callbacks[cat](self)
678 callbacks[cat](self)
679 # Prevent double usage and help clear cycles.
679 # Prevent double usage and help clear cycles.
680 self._finalizecallback = None
680 self._finalizecallback = None
681 self._generatefiles(group=GEN_GROUP_POST_FINALIZE)
681 self._generatefiles(group=GEN_GROUP_POST_FINALIZE)
682
682
683 self._count -= 1
683 self._count -= 1
684 if self._count != 0:
684 if self._count != 0:
685 return
685 return
686 self._file.close()
686 self._file.close()
687 self._backupsfile.close()
687 self._backupsfile.close()
688 # cleanup temporary files
688 # cleanup temporary files
689 for l, f, b, c in self._backupentries:
689 for l, f, b, c in self._backupentries:
690 if l not in self._vfsmap and c:
690 if l not in self._vfsmap and c:
691 self._report(
691 self._report(
692 b"couldn't remove %s: unknown cache location %s\n" % (b, l)
692 b"couldn't remove %s: unknown cache location %s\n" % (b, l)
693 )
693 )
694 continue
694 continue
695 vfs = self._vfsmap[l]
695 vfs = self._vfsmap[l]
696 if not f and b and vfs.exists(b):
696 if not f and b and vfs.exists(b):
697 try:
697 try:
698 vfs.unlink(b)
698 vfs.unlink(b)
699 except (IOError, OSError, error.Abort) as inst:
699 except (IOError, OSError, error.Abort) as inst:
700 if not c:
700 if not c:
701 raise
701 raise
702 # Abort may be raise by read only opener
702 # Abort may be raise by read only opener
703 self._report(
703 self._report(
704 b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
704 b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
705 )
705 )
706 self._offsetmap = {}
706 self._offsetmap = {}
707 self._newfiles = set()
707 self._newfiles = set()
708 self._writeundo()
708 self._writeundo()
709 if self._after:
709 if self._after:
710 self._after()
710 self._after()
711 self._after = None # Help prevent cycles.
711 self._after = None # Help prevent cycles.
712 if self._opener.isfile(self._backupjournal):
712 if self._opener.isfile(self._backupjournal):
713 self._opener.unlink(self._backupjournal)
713 self._opener.unlink(self._backupjournal)
714 if self._opener.isfile(self._journal):
714 if self._opener.isfile(self._journal):
715 self._opener.unlink(self._journal)
715 self._opener.unlink(self._journal)
716 for l, _f, b, c in self._backupentries:
716 for l, _f, b, c in self._backupentries:
717 if l not in self._vfsmap and c:
717 if l not in self._vfsmap and c:
718 self._report(
718 self._report(
719 b"couldn't remove %s: unknown cache location"
719 b"couldn't remove %s: unknown cache location"
720 b"%s\n" % (b, l)
720 b"%s\n" % (b, l)
721 )
721 )
722 continue
722 continue
723 vfs = self._vfsmap[l]
723 vfs = self._vfsmap[l]
724 if b and vfs.exists(b):
724 if b and vfs.exists(b):
725 try:
725 try:
726 vfs.unlink(b)
726 vfs.unlink(b)
727 except (IOError, OSError, error.Abort) as inst:
727 except (IOError, OSError, error.Abort) as inst:
728 if not c:
728 if not c:
729 raise
729 raise
730 # Abort may be raise by read only opener
730 # Abort may be raise by read only opener
731 self._report(
731 self._report(
732 b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
732 b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
733 )
733 )
734 self._backupentries = []
734 self._backupentries = []
735 self._journal = None
735 self._journal = None
736
736
737 self._releasefn(self, True) # notify success of closing transaction
737 self._releasefn(self, True) # notify success of closing transaction
738 self._releasefn = None # Help prevent cycles.
738 self._releasefn = None # Help prevent cycles.
739
739
740 # run post close action
740 # run post close action
741 categories = sorted(self._postclosecallback)
741 categories = sorted(self._postclosecallback)
742 for cat in categories:
742 for cat in categories:
743 self._postclosecallback[cat](self)
743 self._postclosecallback[cat](self)
744 # Prevent double usage and help clear cycles.
744 # Prevent double usage and help clear cycles.
745 self._postclosecallback = None
745 self._postclosecallback = None
746
746
747 @active
747 @active
748 def abort(self):
748 def abort(self):
749 """abort the transaction (generally called on error, or when the
749 """abort the transaction (generally called on error, or when the
750 transaction is not explicitly committed before going out of
750 transaction is not explicitly committed before going out of
751 scope)"""
751 scope)"""
752 self._abort()
752 self._abort()
753
753
754 @active
754 @active
755 def add_journal(self, vfs_id, path):
755 def add_journal(self, vfs_id, path):
756 self._journal_files.append((vfs_id, path))
756 self._journal_files.append((vfs_id, path))
757
757
758 def _writeundo(self):
758 def _writeundo(self):
759 """write transaction data for possible future undo call"""
759 """write transaction data for possible future undo call"""
760 if self._undoname is None:
760 if self._undoname is None:
761 return
761 return
762 cleanup_undo_files(
762 cleanup_undo_files(
763 self._report,
763 self._report,
764 self._vfsmap,
764 self._vfsmap,
765 undo_prefix=self._undoname,
765 undo_prefix=self._undoname,
766 )
766 )
767
767
768 def undoname(fn: bytes) -> bytes:
768 def undoname(fn: bytes) -> bytes:
769 base, name = os.path.split(fn)
769 base, name = os.path.split(fn)
770 assert name.startswith(self._journal)
770 assert name.startswith(self._journal)
771 new_name = name.replace(self._journal, self._undoname, 1)
771 new_name = name.replace(self._journal, self._undoname, 1)
772 return os.path.join(base, new_name)
772 return os.path.join(base, new_name)
773
773
774 undo_backup_path = b"%s.backupfiles" % self._undoname
774 undo_backup_path = b"%s.backupfiles" % self._undoname
775 undobackupfile = self._opener.open(undo_backup_path, b'w')
775 undobackupfile = self._opener.open(undo_backup_path, b'w')
776 undobackupfile.write(b'%d\n' % version)
776 undobackupfile.write(b'%d\n' % version)
777 for l, f, b, c in self._backupentries:
777 for l, f, b, c in self._backupentries:
778 if not f: # temporary file
778 if not f: # temporary file
779 continue
779 continue
780 if not b:
780 if not b:
781 u = b''
781 u = b''
782 else:
782 else:
783 if l not in self._vfsmap and c:
783 if l not in self._vfsmap and c:
784 self._report(
784 self._report(
785 b"couldn't remove %s: unknown cache location"
785 b"couldn't remove %s: unknown cache location"
786 b"%s\n" % (b, l)
786 b"%s\n" % (b, l)
787 )
787 )
788 continue
788 continue
789 vfs = self._vfsmap[l]
789 vfs = self._vfsmap[l]
790 u = undoname(b)
790 u = undoname(b)
791 util.copyfile(vfs.join(b), vfs.join(u), hardlink=True)
791 util.copyfile(vfs.join(b), vfs.join(u), hardlink=True)
792 undobackupfile.write(b"%s\0%s\0%s\0%d\n" % (l, f, u, c))
792 undobackupfile.write(b"%s\0%s\0%s\0%d\n" % (l, f, u, c))
793 undobackupfile.close()
793 undobackupfile.close()
794 for vfs, src in self._journal_files:
794 for vfs, src in self._journal_files:
795 dest = undoname(src)
795 dest = undoname(src)
796 # if src and dest refer to a same file, vfs.rename is a no-op,
796 # if src and dest refer to a same file, vfs.rename is a no-op,
797 # leaving both src and dest on disk. delete dest to make sure
797 # leaving both src and dest on disk. delete dest to make sure
798 # the rename couldn't be such a no-op.
798 # the rename couldn't be such a no-op.
799 vfs.tryunlink(dest)
799 vfs.tryunlink(dest)
800 try:
800 try:
801 vfs.rename(src, dest)
801 vfs.rename(src, dest)
802 except FileNotFoundError: # journal file does not yet exist
802 except FileNotFoundError: # journal file does not yet exist
803 pass
803 pass
804
804
805 def _abort(self):
805 def _abort(self):
806 entries = self.readjournal()
806 entries = self.readjournal()
807 self._count = 0
807 self._count = 0
808 self._usages = 0
808 self._usages = 0
809 self._file.close()
809 self._file.close()
810 self._backupsfile.close()
810 self._backupsfile.close()
811
811
812 quick = self._can_quick_abort(entries)
812 quick = self._can_quick_abort(entries)
813 try:
813 try:
814 if not quick:
814 if not quick:
815 self._report(_(b"transaction abort!\n"))
815 self._report(_(b"transaction abort!\n"))
816 for cat in sorted(self._abortcallback):
816 for cat in sorted(self._abortcallback):
817 self._abortcallback[cat](self)
817 self._abortcallback[cat](self)
818 # Prevent double usage and help clear cycles.
818 # Prevent double usage and help clear cycles.
819 self._abortcallback = None
819 self._abortcallback = None
820 if quick:
820 if quick:
821 self._do_quick_abort(entries)
821 self._do_quick_abort(entries)
822 else:
822 else:
823 self._do_full_abort(entries)
823 self._do_full_abort(entries)
824 finally:
824 finally:
825 self._journal = None
825 self._journal = None
826 self._releasefn(self, False) # notify failure of transaction
826 self._releasefn(self, False) # notify failure of transaction
827 self._releasefn = None # Help prevent cycles.
827 self._releasefn = None # Help prevent cycles.
828
828
829 def _can_quick_abort(self, entries):
829 def _can_quick_abort(self, entries):
830 """False if any semantic content have been written on disk
830 """False if any semantic content have been written on disk
831
831
832 True if nothing, except temporary files has been writen on disk."""
832 True if nothing, except temporary files has been writen on disk."""
833 if entries:
833 if entries:
834 return False
834 return False
835 for e in self._backupentries:
835 for e in self._backupentries:
836 if e[1]:
836 if e[1]:
837 return False
837 return False
838 return True
838 return True
839
839
840 def _do_quick_abort(self, entries):
840 def _do_quick_abort(self, entries):
841 """(Silently) do a quick cleanup (see _can_quick_abort)"""
841 """(Silently) do a quick cleanup (see _can_quick_abort)"""
842 assert self._can_quick_abort(entries)
842 assert self._can_quick_abort(entries)
843 tmp_files = [e for e in self._backupentries if not e[1]]
843 tmp_files = [e for e in self._backupentries if not e[1]]
844 for vfs_id, old_path, tmp_path, xxx in tmp_files:
844 for vfs_id, old_path, tmp_path, xxx in tmp_files:
845 vfs = self._vfsmap[vfs_id]
845 vfs = self._vfsmap[vfs_id]
846 try:
846 try:
847 vfs.unlink(tmp_path)
847 vfs.unlink(tmp_path)
848 except FileNotFoundError:
848 except FileNotFoundError:
849 pass
849 pass
850 if self._backupjournal:
850 if self._backupjournal:
851 self._opener.unlink(self._backupjournal)
851 self._opener.unlink(self._backupjournal)
852 if self._journal:
852 if self._journal:
853 self._opener.unlink(self._journal)
853 self._opener.unlink(self._journal)
854
854
855 def _do_full_abort(self, entries):
855 def _do_full_abort(self, entries):
856 """(Noisily) rollback all the change introduced by the transaction"""
856 """(Noisily) rollback all the change introduced by the transaction"""
857 try:
857 try:
858 _playback(
858 _playback(
859 self._journal,
859 self._journal,
860 self._report,
860 self._report,
861 self._opener,
861 self._opener,
862 self._vfsmap,
862 self._vfsmap,
863 entries,
863 entries,
864 self._backupentries,
864 self._backupentries,
865 False,
865 False,
866 checkambigfiles=self._checkambigfiles,
866 checkambigfiles=self._checkambigfiles,
867 )
867 )
868 self._report(_(b"rollback completed\n"))
868 self._report(_(b"rollback completed\n"))
869 except BaseException as exc:
869 except BaseException as exc:
870 self._report(_(b"rollback failed - please run hg recover\n"))
870 self._report(_(b"rollback failed - please run hg recover\n"))
871 self._report(
871 self._report(
872 _(b"(failure reason: %s)\n") % stringutil.forcebytestr(exc)
872 _(b"(failure reason: %s)\n") % stringutil.forcebytestr(exc)
873 )
873 )
874
874
875
875
876 BAD_VERSION_MSG = _(
876 BAD_VERSION_MSG = _(
877 b"journal was created by a different version of Mercurial\n"
877 b"journal was created by a different version of Mercurial\n"
878 )
878 )
879
879
880
880
881 def read_backup_files(report, fp):
881 def read_backup_files(report, fp):
882 """parse an (already open) backup file an return contained backup entries
882 """parse an (already open) backup file an return contained backup entries
883
883
884 entries are in the form: (location, file, backupfile, xxx)
884 entries are in the form: (location, file, backupfile, xxx)
885
885
886 :location: the vfs identifier (vfsmap's key)
886 :location: the vfs identifier (vfsmap's key)
887 :file: original file path (in the vfs)
887 :file: original file path (in the vfs)
888 :backupfile: path of the backup (in the vfs)
888 :backupfile: path of the backup (in the vfs)
889 :cache: a boolean currently always set to False
889 :cache: a boolean currently always set to False
890 """
890 """
891 lines = fp.readlines()
891 lines = fp.readlines()
892 backupentries = []
892 backupentries = []
893 if lines:
893 if lines:
894 ver = lines[0][:-1]
894 ver = lines[0][:-1]
895 if ver != (b'%d' % version):
895 if ver != (b'%d' % version):
896 report(BAD_VERSION_MSG)
896 report(BAD_VERSION_MSG)
897 else:
897 else:
898 for line in lines[1:]:
898 for line in lines[1:]:
899 if line:
899 if line:
900 # Shave off the trailing newline
900 # Shave off the trailing newline
901 line = line[:-1]
901 line = line[:-1]
902 l, f, b, c = line.split(b'\0')
902 l, f, b, c = line.split(b'\0')
903 backupentries.append((l, f, b, bool(c)))
903 backupentries.append((l, f, b, bool(c)))
904 return backupentries
904 return backupentries
905
905
906
906
907 def rollback(
907 def rollback(
908 opener,
908 opener,
909 vfsmap,
909 vfsmap,
910 file,
910 file,
911 report,
911 report,
912 checkambigfiles=None,
912 checkambigfiles=None,
913 skip_journal_pattern=None,
913 skip_journal_pattern=None,
914 ):
914 ):
915 """Rolls back the transaction contained in the given file
915 """Rolls back the transaction contained in the given file
916
916
917 Reads the entries in the specified file, and the corresponding
917 Reads the entries in the specified file, and the corresponding
918 '*.backupfiles' file, to recover from an incomplete transaction.
918 '*.backupfiles' file, to recover from an incomplete transaction.
919
919
920 * `file`: a file containing a list of entries, specifying where
920 * `file`: a file containing a list of entries, specifying where
921 to truncate each file. The file should contain a list of
921 to truncate each file. The file should contain a list of
922 file\0offset pairs, delimited by newlines. The corresponding
922 file\0offset pairs, delimited by newlines. The corresponding
923 '*.backupfiles' file should contain a list of file\0backupfile
923 '*.backupfiles' file should contain a list of file\0backupfile
924 pairs, delimited by \0.
924 pairs, delimited by \0.
925
925
926 `checkambigfiles` is a set of (path, vfs-location) tuples,
926 `checkambigfiles` is a set of (path, vfs-location) tuples,
927 which determine whether file stat ambiguity should be avoided at
927 which determine whether file stat ambiguity should be avoided at
928 restoring corresponded files.
928 restoring corresponded files.
929 """
929 """
930 entries = []
930 entries = []
931 backupentries = []
931 backupentries = []
932
932
933 with opener.open(file) as fp:
933 with opener.open(file) as fp:
934 lines = fp.readlines()
934 lines = fp.readlines()
935 for l in lines:
935 for l in lines:
936 try:
936 try:
937 f, o = l.split(b'\0')
937 f, o = l.split(b'\0')
938 entries.append((f, int(o)))
938 entries.append((f, int(o)))
939 except ValueError:
939 except ValueError:
940 report(
940 report(
941 _(b"couldn't read journal entry %r!\n") % pycompat.bytestr(l)
941 _(b"couldn't read journal entry %r!\n") % pycompat.bytestr(l)
942 )
942 )
943
943
944 backupjournal = b"%s.backupfiles" % file
944 backupjournal = b"%s.backupfiles" % file
945 if opener.exists(backupjournal):
945 if opener.exists(backupjournal):
946 with opener.open(backupjournal) as fp:
946 with opener.open(backupjournal) as fp:
947 backupentries = read_backup_files(report, fp)
947 backupentries = read_backup_files(report, fp)
948 if skip_journal_pattern is not None:
948 if skip_journal_pattern is not None:
949 keep = lambda x: not skip_journal_pattern.match(x[1])
949 keep = lambda x: not skip_journal_pattern.match(x[1])
950 backupentries = [x for x in backupentries if keep(x)]
950 backupentries = [x for x in backupentries if keep(x)]
951
951
952 _playback(
952 _playback(
953 file,
953 file,
954 report,
954 report,
955 opener,
955 opener,
956 vfsmap,
956 vfsmap,
957 entries,
957 entries,
958 backupentries,
958 backupentries,
959 checkambigfiles=checkambigfiles,
959 checkambigfiles=checkambigfiles,
960 )
960 )
@@ -1,531 +1,531 b''
1 #require repofncache
1 #require repofncache
2
2
3 An extension which will set fncache chunksize to 1 byte to make sure that logic
3 An extension which will set fncache chunksize to 1 byte to make sure that logic
4 does not break
4 does not break
5
5
6 $ cat > chunksize.py <<EOF
6 $ cat > chunksize.py <<EOF
7 > from mercurial import store
7 > from mercurial import store
8 > store.fncache_chunksize = 1
8 > store.fncache_chunksize = 1
9 > EOF
9 > EOF
10
10
11 $ cat >> $HGRCPATH <<EOF
11 $ cat >> $HGRCPATH <<EOF
12 > [extensions]
12 > [extensions]
13 > chunksize = $TESTTMP/chunksize.py
13 > chunksize = $TESTTMP/chunksize.py
14 > EOF
14 > EOF
15
15
16 Init repo1:
16 Init repo1:
17
17
18 $ hg init repo1
18 $ hg init repo1
19 $ cd repo1
19 $ cd repo1
20 $ echo "some text" > a
20 $ echo "some text" > a
21 $ hg add
21 $ hg add
22 adding a
22 adding a
23 $ hg ci -m first
23 $ hg ci -m first
24 $ cat .hg/store/fncache | sort
24 $ cat .hg/store/fncache | sort
25 data/a.i
25 data/a.i
26
26
27 Testing a.i/b:
27 Testing a.i/b:
28
28
29 $ mkdir a.i
29 $ mkdir a.i
30 $ echo "some other text" > a.i/b
30 $ echo "some other text" > a.i/b
31 $ hg add
31 $ hg add
32 adding a.i/b
32 adding a.i/b
33 $ hg ci -m second
33 $ hg ci -m second
34 $ cat .hg/store/fncache | sort
34 $ cat .hg/store/fncache | sort
35 data/a.i
35 data/a.i
36 data/a.i.hg/b.i
36 data/a.i.hg/b.i
37
37
38 Testing a.i.hg/c:
38 Testing a.i.hg/c:
39
39
40 $ mkdir a.i.hg
40 $ mkdir a.i.hg
41 $ echo "yet another text" > a.i.hg/c
41 $ echo "yet another text" > a.i.hg/c
42 $ hg add
42 $ hg add
43 adding a.i.hg/c
43 adding a.i.hg/c
44 $ hg ci -m third
44 $ hg ci -m third
45 $ cat .hg/store/fncache | sort
45 $ cat .hg/store/fncache | sort
46 data/a.i
46 data/a.i
47 data/a.i.hg.hg/c.i
47 data/a.i.hg.hg/c.i
48 data/a.i.hg/b.i
48 data/a.i.hg/b.i
49
49
50 Testing verify:
50 Testing verify:
51
51
52 $ hg verify -q
52 $ hg verify -q
53
53
54 $ rm .hg/store/fncache
54 $ rm .hg/store/fncache
55
55
56 $ hg verify
56 $ hg verify
57 checking changesets
57 checking changesets
58 checking manifests
58 checking manifests
59 crosschecking files in changesets and manifests
59 crosschecking files in changesets and manifests
60 checking files
60 checking files
61 warning: revlog 'data/a.i' not in fncache!
61 warning: revlog 'data/a.i' not in fncache!
62 warning: revlog 'data/a.i.hg/c.i' not in fncache!
62 warning: revlog 'data/a.i.hg/c.i' not in fncache!
63 warning: revlog 'data/a.i/b.i' not in fncache!
63 warning: revlog 'data/a.i/b.i' not in fncache!
64 checking dirstate
64 checking dirstate
65 checked 3 changesets with 3 changes to 3 files
65 checked 3 changesets with 3 changes to 3 files
66 3 warnings encountered!
66 3 warnings encountered!
67 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
67 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
68
68
69 Follow the hint to make sure it works
69 Follow the hint to make sure it works
70
70
71 $ hg debugrebuildfncache
71 $ hg debugrebuildfncache
72 adding data/a.i
72 adding data/a.i
73 adding data/a.i.hg/c.i
73 adding data/a.i.hg/c.i
74 adding data/a.i/b.i
74 adding data/a.i/b.i
75 3 items added, 0 removed from fncache
75 3 items added, 0 removed from fncache
76
76
77 $ hg verify -q
77 $ hg verify -q
78
78
79 $ cd ..
79 $ cd ..
80
80
81 Non store repo:
81 Non store repo:
82
82
83 $ hg --config format.usestore=False init foo
83 $ hg --config format.usestore=False init foo
84 $ cd foo
84 $ cd foo
85 $ mkdir tst.d
85 $ mkdir tst.d
86 $ echo foo > tst.d/foo
86 $ echo foo > tst.d/foo
87 $ hg ci -Amfoo
87 $ hg ci -Amfoo
88 adding tst.d/foo
88 adding tst.d/foo
89 $ find .hg | sort
89 $ find .hg | sort
90 .hg
90 .hg
91 .hg/00changelog.i
91 .hg/00changelog.i
92 .hg/00manifest.i
92 .hg/00manifest.i
93 .hg/branch
93 .hg/branch
94 .hg/cache
94 .hg/cache
95 .hg/cache/branch2-served
95 .hg/cache/branch2-served
96 .hg/cache/rbc-names-v1
96 .hg/cache/rbc-names-v1
97 .hg/cache/rbc-revs-v1
97 .hg/cache/rbc-revs-v1
98 .hg/data
98 .hg/data
99 .hg/data/tst.d.hg
99 .hg/data/tst.d.hg
100 .hg/data/tst.d.hg/foo.i
100 .hg/data/tst.d.hg/foo.i
101 .hg/dirstate
101 .hg/dirstate
102 .hg/fsmonitor.state (fsmonitor !)
102 .hg/fsmonitor.state (fsmonitor !)
103 .hg/last-message.txt
103 .hg/last-message.txt
104 .hg/phaseroots
104 .hg/phaseroots
105 .hg/requires
105 .hg/requires
106 .hg/undo
106 .hg/undo
107 .hg/undo.backup.branch
107 .hg/undo.backup.branch.bck
108 .hg/undo.backupfiles
108 .hg/undo.backupfiles
109 .hg/undo.desc
109 .hg/undo.desc
110 .hg/wcache
110 .hg/wcache
111 .hg/wcache/checkisexec (execbit !)
111 .hg/wcache/checkisexec (execbit !)
112 .hg/wcache/checklink (symlink !)
112 .hg/wcache/checklink (symlink !)
113 .hg/wcache/checklink-target (symlink !)
113 .hg/wcache/checklink-target (symlink !)
114 .hg/wcache/manifestfulltextcache (reporevlogstore !)
114 .hg/wcache/manifestfulltextcache (reporevlogstore !)
115 $ cd ..
115 $ cd ..
116
116
117 Non fncache repo:
117 Non fncache repo:
118
118
119 $ hg --config format.usefncache=False init bar
119 $ hg --config format.usefncache=False init bar
120 $ cd bar
120 $ cd bar
121 $ mkdir tst.d
121 $ mkdir tst.d
122 $ echo foo > tst.d/Foo
122 $ echo foo > tst.d/Foo
123 $ hg ci -Amfoo
123 $ hg ci -Amfoo
124 adding tst.d/Foo
124 adding tst.d/Foo
125 $ find .hg | sort
125 $ find .hg | sort
126 .hg
126 .hg
127 .hg/00changelog.i
127 .hg/00changelog.i
128 .hg/branch
128 .hg/branch
129 .hg/cache
129 .hg/cache
130 .hg/cache/branch2-served
130 .hg/cache/branch2-served
131 .hg/cache/rbc-names-v1
131 .hg/cache/rbc-names-v1
132 .hg/cache/rbc-revs-v1
132 .hg/cache/rbc-revs-v1
133 .hg/dirstate
133 .hg/dirstate
134 .hg/fsmonitor.state (fsmonitor !)
134 .hg/fsmonitor.state (fsmonitor !)
135 .hg/last-message.txt
135 .hg/last-message.txt
136 .hg/requires
136 .hg/requires
137 .hg/store
137 .hg/store
138 .hg/store/00changelog.i
138 .hg/store/00changelog.i
139 .hg/store/00manifest.i
139 .hg/store/00manifest.i
140 .hg/store/data
140 .hg/store/data
141 .hg/store/data/tst.d.hg
141 .hg/store/data/tst.d.hg
142 .hg/store/data/tst.d.hg/_foo.i
142 .hg/store/data/tst.d.hg/_foo.i
143 .hg/store/phaseroots
143 .hg/store/phaseroots
144 .hg/store/requires
144 .hg/store/requires
145 .hg/store/undo
145 .hg/store/undo
146 .hg/store/undo.backupfiles
146 .hg/store/undo.backupfiles
147 .hg/undo.backup.branch
147 .hg/undo.backup.branch.bck
148 .hg/undo.desc
148 .hg/undo.desc
149 .hg/wcache
149 .hg/wcache
150 .hg/wcache/checkisexec (execbit !)
150 .hg/wcache/checkisexec (execbit !)
151 .hg/wcache/checklink (symlink !)
151 .hg/wcache/checklink (symlink !)
152 .hg/wcache/checklink-target (symlink !)
152 .hg/wcache/checklink-target (symlink !)
153 .hg/wcache/manifestfulltextcache (reporevlogstore !)
153 .hg/wcache/manifestfulltextcache (reporevlogstore !)
154 $ cd ..
154 $ cd ..
155
155
156 Encoding of reserved / long paths in the store
156 Encoding of reserved / long paths in the store
157
157
158 $ hg init r2
158 $ hg init r2
159 $ cd r2
159 $ cd r2
160 $ cat <<EOF > .hg/hgrc
160 $ cat <<EOF > .hg/hgrc
161 > [ui]
161 > [ui]
162 > portablefilenames = ignore
162 > portablefilenames = ignore
163 > EOF
163 > EOF
164
164
165 $ hg import -q --bypass - <<EOF
165 $ hg import -q --bypass - <<EOF
166 > # HG changeset patch
166 > # HG changeset patch
167 > # User test
167 > # User test
168 > # Date 0 0
168 > # Date 0 0
169 > # Node ID 1c7a2f7cb77be1a0def34e4c7cabc562ad98fbd7
169 > # Node ID 1c7a2f7cb77be1a0def34e4c7cabc562ad98fbd7
170 > # Parent 0000000000000000000000000000000000000000
170 > # Parent 0000000000000000000000000000000000000000
171 > 1
171 > 1
172 >
172 >
173 > diff --git a/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
173 > diff --git a/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
174 > new file mode 100644
174 > new file mode 100644
175 > --- /dev/null
175 > --- /dev/null
176 > +++ b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
176 > +++ b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
177 > @@ -0,0 +1,1 @@
177 > @@ -0,0 +1,1 @@
178 > +foo
178 > +foo
179 > diff --git a/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
179 > diff --git a/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
180 > new file mode 100644
180 > new file mode 100644
181 > --- /dev/null
181 > --- /dev/null
182 > +++ b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
182 > +++ b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
183 > @@ -0,0 +1,1 @@
183 > @@ -0,0 +1,1 @@
184 > +foo
184 > +foo
185 > diff --git a/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
185 > diff --git a/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
186 > new file mode 100644
186 > new file mode 100644
187 > --- /dev/null
187 > --- /dev/null
188 > +++ b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
188 > +++ b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
189 > @@ -0,0 +1,1 @@
189 > @@ -0,0 +1,1 @@
190 > +foo
190 > +foo
191 > diff --git a/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
191 > diff --git a/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
192 > new file mode 100644
192 > new file mode 100644
193 > --- /dev/null
193 > --- /dev/null
194 > +++ b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
194 > +++ b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
195 > @@ -0,0 +1,1 @@
195 > @@ -0,0 +1,1 @@
196 > +foo
196 > +foo
197 > diff --git a/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
197 > diff --git a/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
198 > new file mode 100644
198 > new file mode 100644
199 > --- /dev/null
199 > --- /dev/null
200 > +++ b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
200 > +++ b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
201 > @@ -0,0 +1,1 @@
201 > @@ -0,0 +1,1 @@
202 > +foo
202 > +foo
203 > EOF
203 > EOF
204
204
205 $ find .hg/store -name *.i | sort
205 $ find .hg/store -name *.i | sort
206 .hg/store/00changelog.i
206 .hg/store/00changelog.i
207 .hg/store/00manifest.i
207 .hg/store/00manifest.i
208 .hg/store/data/bla.aux/pr~6e/_p_r_n/lpt/co~6d3/nu~6c/coma/foo._n_u_l/normal.c.i
208 .hg/store/data/bla.aux/pr~6e/_p_r_n/lpt/co~6d3/nu~6c/coma/foo._n_u_l/normal.c.i
209 .hg/store/dh/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxx168e07b38e65eff86ab579afaaa8e30bfbe0f35f.i
209 .hg/store/dh/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxx168e07b38e65eff86ab579afaaa8e30bfbe0f35f.i
210 .hg/store/dh/au~78/second/x.prn/fourth/fi~3afth/sixth/seventh/eighth/nineth/tenth/loremia20419e358ddff1bf8751e38288aff1d7c32ec05.i
210 .hg/store/dh/au~78/second/x.prn/fourth/fi~3afth/sixth/seventh/eighth/nineth/tenth/loremia20419e358ddff1bf8751e38288aff1d7c32ec05.i
211 .hg/store/dh/enterpri/openesba/contrib-/corba-bc/netbeans/wsdlexte/src/main/java/org.net7018f27961fdf338a598a40c4683429e7ffb9743.i
211 .hg/store/dh/enterpri/openesba/contrib-/corba-bc/netbeans/wsdlexte/src/main/java/org.net7018f27961fdf338a598a40c4683429e7ffb9743.i
212 .hg/store/dh/project_/resource/anotherl/followed/andanoth/andthenanextremelylongfilename0d8e1f4187c650e2f1fdca9fd90f786bc0976b6b.i
212 .hg/store/dh/project_/resource/anotherl/followed/andanoth/andthenanextremelylongfilename0d8e1f4187c650e2f1fdca9fd90f786bc0976b6b.i
213
213
214 $ cd ..
214 $ cd ..
215
215
216 Aborting lock does not prevent fncache writes
216 Aborting lock does not prevent fncache writes
217
217
218 $ cat > exceptionext.py <<EOF
218 $ cat > exceptionext.py <<EOF
219 > import os
219 > import os
220 > from mercurial import commands, error, extensions
220 > from mercurial import commands, error, extensions
221 >
221 >
222 > def lockexception(orig, vfs, lockname, wait, releasefn, *args, **kwargs):
222 > def lockexception(orig, vfs, lockname, wait, releasefn, *args, **kwargs):
223 > def releasewrap():
223 > def releasewrap():
224 > l.held = False # ensure __del__ is a noop
224 > l.held = False # ensure __del__ is a noop
225 > raise error.Abort(b"forced lock failure")
225 > raise error.Abort(b"forced lock failure")
226 > l = orig(vfs, lockname, wait, releasewrap, *args, **kwargs)
226 > l = orig(vfs, lockname, wait, releasewrap, *args, **kwargs)
227 > return l
227 > return l
228 >
228 >
229 > def reposetup(ui, repo):
229 > def reposetup(ui, repo):
230 > extensions.wrapfunction(repo, '_lock', lockexception)
230 > extensions.wrapfunction(repo, '_lock', lockexception)
231 >
231 >
232 > cmdtable = {}
232 > cmdtable = {}
233 >
233 >
234 > # wrap "commit" command to prevent wlock from being '__del__()'-ed
234 > # wrap "commit" command to prevent wlock from being '__del__()'-ed
235 > # at the end of dispatching (for intentional "forced lcok failure")
235 > # at the end of dispatching (for intentional "forced lcok failure")
236 > def commitwrap(orig, ui, repo, *pats, **opts):
236 > def commitwrap(orig, ui, repo, *pats, **opts):
237 > repo = repo.unfiltered() # to use replaced repo._lock certainly
237 > repo = repo.unfiltered() # to use replaced repo._lock certainly
238 > wlock = repo.wlock()
238 > wlock = repo.wlock()
239 > try:
239 > try:
240 > return orig(ui, repo, *pats, **opts)
240 > return orig(ui, repo, *pats, **opts)
241 > finally:
241 > finally:
242 > # multiple 'relase()' is needed for complete releasing wlock,
242 > # multiple 'relase()' is needed for complete releasing wlock,
243 > # because "forced" abort at last releasing store lock
243 > # because "forced" abort at last releasing store lock
244 > # prevents wlock from being released at same 'lockmod.release()'
244 > # prevents wlock from being released at same 'lockmod.release()'
245 > for i in range(wlock.held):
245 > for i in range(wlock.held):
246 > wlock.release()
246 > wlock.release()
247 >
247 >
248 > def extsetup(ui):
248 > def extsetup(ui):
249 > extensions.wrapcommand(commands.table, b"commit", commitwrap)
249 > extensions.wrapcommand(commands.table, b"commit", commitwrap)
250 > EOF
250 > EOF
251 $ extpath=`pwd`/exceptionext.py
251 $ extpath=`pwd`/exceptionext.py
252 $ hg init fncachetxn
252 $ hg init fncachetxn
253 $ cd fncachetxn
253 $ cd fncachetxn
254 $ printf "[extensions]\nexceptionext=$extpath\n" >> .hg/hgrc
254 $ printf "[extensions]\nexceptionext=$extpath\n" >> .hg/hgrc
255 $ touch y
255 $ touch y
256 $ hg ci -qAm y
256 $ hg ci -qAm y
257 abort: forced lock failure
257 abort: forced lock failure
258 [255]
258 [255]
259 $ cat .hg/store/fncache
259 $ cat .hg/store/fncache
260 data/y.i
260 data/y.i
261
261
262 Aborting transaction prevents fncache change
262 Aborting transaction prevents fncache change
263
263
264 $ cat > ../exceptionext.py <<EOF
264 $ cat > ../exceptionext.py <<EOF
265 > import os
265 > import os
266 > from mercurial import commands, error, extensions, localrepo
266 > from mercurial import commands, error, extensions, localrepo
267 >
267 >
268 > def wrapper(orig, self, *args, **kwargs):
268 > def wrapper(orig, self, *args, **kwargs):
269 > tr = orig(self, *args, **kwargs)
269 > tr = orig(self, *args, **kwargs)
270 > def fail(tr):
270 > def fail(tr):
271 > raise error.Abort(b"forced transaction failure")
271 > raise error.Abort(b"forced transaction failure")
272 > # zzz prefix to ensure it sorted after store.write
272 > # zzz prefix to ensure it sorted after store.write
273 > tr.addfinalize(b'zzz-forcefails', fail)
273 > tr.addfinalize(b'zzz-forcefails', fail)
274 > return tr
274 > return tr
275 >
275 >
276 > def uisetup(ui):
276 > def uisetup(ui):
277 > extensions.wrapfunction(
277 > extensions.wrapfunction(
278 > localrepo.localrepository, b'transaction', wrapper)
278 > localrepo.localrepository, b'transaction', wrapper)
279 >
279 >
280 > cmdtable = {}
280 > cmdtable = {}
281 >
281 >
282 > EOF
282 > EOF
283
283
284 Clean cached version
284 Clean cached version
285 $ rm -f "${extpath}c"
285 $ rm -f "${extpath}c"
286 $ rm -Rf "`dirname $extpath`/__pycache__"
286 $ rm -Rf "`dirname $extpath`/__pycache__"
287
287
288 $ touch z
288 $ touch z
289 $ hg ci -qAm z
289 $ hg ci -qAm z
290 transaction abort!
290 transaction abort!
291 rollback completed
291 rollback completed
292 abort: forced transaction failure
292 abort: forced transaction failure
293 [255]
293 [255]
294 $ cat .hg/store/fncache
294 $ cat .hg/store/fncache
295 data/y.i
295 data/y.i
296
296
297 Aborted transactions can be recovered later
297 Aborted transactions can be recovered later
298
298
299 $ cat > ../exceptionext.py <<EOF
299 $ cat > ../exceptionext.py <<EOF
300 > import os
300 > import os
301 > import signal
301 > import signal
302 > from mercurial import (
302 > from mercurial import (
303 > commands,
303 > commands,
304 > error,
304 > error,
305 > extensions,
305 > extensions,
306 > localrepo,
306 > localrepo,
307 > transaction,
307 > transaction,
308 > )
308 > )
309 >
309 >
310 > def trwrapper(orig, self, *args, **kwargs):
310 > def trwrapper(orig, self, *args, **kwargs):
311 > tr = orig(self, *args, **kwargs)
311 > tr = orig(self, *args, **kwargs)
312 > def fail(tr):
312 > def fail(tr):
313 > os.kill(os.getpid(), signal.SIGKILL)
313 > os.kill(os.getpid(), signal.SIGKILL)
314 > # zzz prefix to ensure it sorted after store.write
314 > # zzz prefix to ensure it sorted after store.write
315 > tr.addfinalize(b'zzz-forcefails', fail)
315 > tr.addfinalize(b'zzz-forcefails', fail)
316 > return tr
316 > return tr
317 >
317 >
318 > def uisetup(ui):
318 > def uisetup(ui):
319 > extensions.wrapfunction(localrepo.localrepository, 'transaction',
319 > extensions.wrapfunction(localrepo.localrepository, 'transaction',
320 > trwrapper)
320 > trwrapper)
321 >
321 >
322 > cmdtable = {}
322 > cmdtable = {}
323 >
323 >
324 > EOF
324 > EOF
325
325
326 Clean cached versions
326 Clean cached versions
327 $ rm -f "${extpath}c"
327 $ rm -f "${extpath}c"
328 $ rm -Rf "`dirname $extpath`/__pycache__"
328 $ rm -Rf "`dirname $extpath`/__pycache__"
329
329
330 $ hg up -q 1
330 $ hg up -q 1
331 $ touch z
331 $ touch z
332 # Cannot rely on the return code value as chg use a different one.
332 # Cannot rely on the return code value as chg use a different one.
333 # So we use a `|| echo` trick
333 # So we use a `|| echo` trick
334 # XXX-CHG fixing chg behavior would be nice here.
334 # XXX-CHG fixing chg behavior would be nice here.
335 $ hg ci -qAm z || echo "He's Dead, Jim." 2>/dev/null
335 $ hg ci -qAm z || echo "He's Dead, Jim." 2>/dev/null
336 *Killed* (glob) (?)
336 *Killed* (glob) (?)
337 He's Dead, Jim.
337 He's Dead, Jim.
338 $ cat .hg/store/fncache | sort
338 $ cat .hg/store/fncache | sort
339 data/y.i
339 data/y.i
340 data/z.i
340 data/z.i
341 $ hg recover --verify
341 $ hg recover --verify
342 rolling back interrupted transaction
342 rolling back interrupted transaction
343 checking changesets
343 checking changesets
344 checking manifests
344 checking manifests
345 crosschecking files in changesets and manifests
345 crosschecking files in changesets and manifests
346 checking files
346 checking files
347 checking dirstate
347 checking dirstate
348 checked 1 changesets with 1 changes to 1 files
348 checked 1 changesets with 1 changes to 1 files
349 $ cat .hg/store/fncache
349 $ cat .hg/store/fncache
350 data/y.i
350 data/y.i
351
351
352 $ cd ..
352 $ cd ..
353
353
354 debugrebuildfncache does nothing unless repo has fncache requirement
354 debugrebuildfncache does nothing unless repo has fncache requirement
355
355
356 $ hg --config format.usefncache=false init nofncache
356 $ hg --config format.usefncache=false init nofncache
357 $ cd nofncache
357 $ cd nofncache
358 $ hg debugrebuildfncache
358 $ hg debugrebuildfncache
359 (not rebuilding fncache because repository does not support fncache)
359 (not rebuilding fncache because repository does not support fncache)
360
360
361 $ cd ..
361 $ cd ..
362
362
363 debugrebuildfncache works on empty repository
363 debugrebuildfncache works on empty repository
364
364
365 $ hg init empty
365 $ hg init empty
366 $ cd empty
366 $ cd empty
367 $ hg debugrebuildfncache
367 $ hg debugrebuildfncache
368 fncache already up to date
368 fncache already up to date
369 $ cd ..
369 $ cd ..
370
370
371 debugrebuildfncache on an up to date repository no-ops
371 debugrebuildfncache on an up to date repository no-ops
372
372
373 $ hg init repo
373 $ hg init repo
374 $ cd repo
374 $ cd repo
375 $ echo initial > foo
375 $ echo initial > foo
376 $ echo initial > .bar
376 $ echo initial > .bar
377 $ hg commit -A -m initial
377 $ hg commit -A -m initial
378 adding .bar
378 adding .bar
379 adding foo
379 adding foo
380
380
381 $ cat .hg/store/fncache | sort
381 $ cat .hg/store/fncache | sort
382 data/.bar.i
382 data/.bar.i
383 data/foo.i
383 data/foo.i
384
384
385 $ hg debugrebuildfncache
385 $ hg debugrebuildfncache
386 fncache already up to date
386 fncache already up to date
387
387
388 debugrebuildfncache restores deleted fncache file
388 debugrebuildfncache restores deleted fncache file
389
389
390 $ rm -f .hg/store/fncache
390 $ rm -f .hg/store/fncache
391 $ hg debugrebuildfncache
391 $ hg debugrebuildfncache
392 adding data/.bar.i
392 adding data/.bar.i
393 adding data/foo.i
393 adding data/foo.i
394 2 items added, 0 removed from fncache
394 2 items added, 0 removed from fncache
395
395
396 $ cat .hg/store/fncache | sort
396 $ cat .hg/store/fncache | sort
397 data/.bar.i
397 data/.bar.i
398 data/foo.i
398 data/foo.i
399
399
400 Rebuild after rebuild should no-op
400 Rebuild after rebuild should no-op
401
401
402 $ hg debugrebuildfncache
402 $ hg debugrebuildfncache
403 fncache already up to date
403 fncache already up to date
404
404
405 A single missing file should get restored, an extra file should be removed
405 A single missing file should get restored, an extra file should be removed
406
406
407 $ cat > .hg/store/fncache << EOF
407 $ cat > .hg/store/fncache << EOF
408 > data/foo.i
408 > data/foo.i
409 > data/bad-entry.i
409 > data/bad-entry.i
410 > EOF
410 > EOF
411
411
412 $ hg debugrebuildfncache
412 $ hg debugrebuildfncache
413 removing data/bad-entry.i
413 removing data/bad-entry.i
414 adding data/.bar.i
414 adding data/.bar.i
415 1 items added, 1 removed from fncache
415 1 items added, 1 removed from fncache
416
416
417 $ cat .hg/store/fncache | sort
417 $ cat .hg/store/fncache | sort
418 data/.bar.i
418 data/.bar.i
419 data/foo.i
419 data/foo.i
420
420
421 debugrebuildfncache recovers from truncated line in fncache
421 debugrebuildfncache recovers from truncated line in fncache
422
422
423 $ printf a > .hg/store/fncache
423 $ printf a > .hg/store/fncache
424 $ hg debugrebuildfncache
424 $ hg debugrebuildfncache
425 fncache does not ends with a newline
425 fncache does not ends with a newline
426 adding data/.bar.i
426 adding data/.bar.i
427 adding data/foo.i
427 adding data/foo.i
428 2 items added, 0 removed from fncache
428 2 items added, 0 removed from fncache
429
429
430 $ cat .hg/store/fncache | sort
430 $ cat .hg/store/fncache | sort
431 data/.bar.i
431 data/.bar.i
432 data/foo.i
432 data/foo.i
433
433
434 $ cd ..
434 $ cd ..
435
435
436 Try a simple variation without dotencode to ensure fncache is ignorant of encoding
436 Try a simple variation without dotencode to ensure fncache is ignorant of encoding
437
437
438 $ hg --config format.dotencode=false init nodotencode
438 $ hg --config format.dotencode=false init nodotencode
439 $ cd nodotencode
439 $ cd nodotencode
440 $ echo initial > foo
440 $ echo initial > foo
441 $ echo initial > .bar
441 $ echo initial > .bar
442 $ hg commit -A -m initial
442 $ hg commit -A -m initial
443 adding .bar
443 adding .bar
444 adding foo
444 adding foo
445
445
446 $ cat .hg/store/fncache | sort
446 $ cat .hg/store/fncache | sort
447 data/.bar.i
447 data/.bar.i
448 data/foo.i
448 data/foo.i
449
449
450 $ rm .hg/store/fncache
450 $ rm .hg/store/fncache
451 $ hg debugrebuildfncache
451 $ hg debugrebuildfncache
452 adding data/.bar.i
452 adding data/.bar.i
453 adding data/foo.i
453 adding data/foo.i
454 2 items added, 0 removed from fncache
454 2 items added, 0 removed from fncache
455
455
456 $ cat .hg/store/fncache | sort
456 $ cat .hg/store/fncache | sort
457 data/.bar.i
457 data/.bar.i
458 data/foo.i
458 data/foo.i
459
459
460 $ cd ..
460 $ cd ..
461
461
462 In repositories that have accumulated a large number of files over time, the
462 In repositories that have accumulated a large number of files over time, the
463 fncache file is going to be large. If we possibly can avoid loading it, so much the better.
463 fncache file is going to be large. If we possibly can avoid loading it, so much the better.
464 The cache should not loaded when committing changes to existing files, or when unbundling
464 The cache should not loaded when committing changes to existing files, or when unbundling
465 changesets that only contain changes to existing files:
465 changesets that only contain changes to existing files:
466
466
467 $ cat > fncacheloadwarn.py << EOF
467 $ cat > fncacheloadwarn.py << EOF
468 > from mercurial import extensions, localrepo
468 > from mercurial import extensions, localrepo
469 >
469 >
470 > def extsetup(ui):
470 > def extsetup(ui):
471 > def wrapstore(orig, requirements, *args):
471 > def wrapstore(orig, requirements, *args):
472 > store = orig(requirements, *args)
472 > store = orig(requirements, *args)
473 > if b'store' in requirements and b'fncache' in requirements:
473 > if b'store' in requirements and b'fncache' in requirements:
474 > instrumentfncachestore(store, ui)
474 > instrumentfncachestore(store, ui)
475 > return store
475 > return store
476 > extensions.wrapfunction(localrepo, 'makestore', wrapstore)
476 > extensions.wrapfunction(localrepo, 'makestore', wrapstore)
477 >
477 >
478 > def instrumentfncachestore(fncachestore, ui):
478 > def instrumentfncachestore(fncachestore, ui):
479 > class instrumentedfncache(type(fncachestore.fncache)):
479 > class instrumentedfncache(type(fncachestore.fncache)):
480 > def _load(self):
480 > def _load(self):
481 > ui.warn(b'fncache load triggered!\n')
481 > ui.warn(b'fncache load triggered!\n')
482 > super(instrumentedfncache, self)._load()
482 > super(instrumentedfncache, self)._load()
483 > fncachestore.fncache.__class__ = instrumentedfncache
483 > fncachestore.fncache.__class__ = instrumentedfncache
484 > EOF
484 > EOF
485
485
486 $ fncachextpath=`pwd`/fncacheloadwarn.py
486 $ fncachextpath=`pwd`/fncacheloadwarn.py
487 $ hg init nofncacheload
487 $ hg init nofncacheload
488 $ cd nofncacheload
488 $ cd nofncacheload
489 $ printf "[extensions]\nfncacheloadwarn=$fncachextpath\n" >> .hg/hgrc
489 $ printf "[extensions]\nfncacheloadwarn=$fncachextpath\n" >> .hg/hgrc
490
490
491 A new file should trigger a load, as we'd want to update the fncache set in that case:
491 A new file should trigger a load, as we'd want to update the fncache set in that case:
492
492
493 $ touch foo
493 $ touch foo
494 $ hg ci -qAm foo
494 $ hg ci -qAm foo
495 fncache load triggered!
495 fncache load triggered!
496
496
497 But modifying that file should not:
497 But modifying that file should not:
498
498
499 $ echo bar >> foo
499 $ echo bar >> foo
500 $ hg ci -qm foo
500 $ hg ci -qm foo
501
501
502 If a transaction has been aborted, the zero-size truncated index file will
502 If a transaction has been aborted, the zero-size truncated index file will
503 not prevent the fncache from being loaded; rather than actually abort
503 not prevent the fncache from being loaded; rather than actually abort
504 a transaction, we simulate the situation by creating a zero-size index file:
504 a transaction, we simulate the situation by creating a zero-size index file:
505
505
506 $ touch .hg/store/data/bar.i
506 $ touch .hg/store/data/bar.i
507 $ touch bar
507 $ touch bar
508 $ hg ci -qAm bar
508 $ hg ci -qAm bar
509 fncache load triggered!
509 fncache load triggered!
510
510
511 Unbundling should follow the same rules; existing files should not cause a load:
511 Unbundling should follow the same rules; existing files should not cause a load:
512
512
513 (loading during the clone is expected)
513 (loading during the clone is expected)
514 $ hg clone -q . tobundle
514 $ hg clone -q . tobundle
515 fncache load triggered!
515 fncache load triggered!
516 fncache load triggered!
516 fncache load triggered!
517
517
518 $ echo 'new line' > tobundle/bar
518 $ echo 'new line' > tobundle/bar
519 $ hg -R tobundle ci -qm bar
519 $ hg -R tobundle ci -qm bar
520 $ hg -R tobundle bundle -q barupdated.hg
520 $ hg -R tobundle bundle -q barupdated.hg
521 $ hg unbundle -q barupdated.hg
521 $ hg unbundle -q barupdated.hg
522
522
523 but adding new files should:
523 but adding new files should:
524
524
525 $ touch tobundle/newfile
525 $ touch tobundle/newfile
526 $ hg -R tobundle ci -qAm newfile
526 $ hg -R tobundle ci -qAm newfile
527 $ hg -R tobundle bundle -q newfile.hg
527 $ hg -R tobundle bundle -q newfile.hg
528 $ hg unbundle -q newfile.hg
528 $ hg unbundle -q newfile.hg
529 fncache load triggered!
529 fncache load triggered!
530
530
531 $ cd ..
531 $ cd ..
@@ -1,425 +1,425 b''
1 #require hardlink reporevlogstore
1 #require hardlink reporevlogstore
2
2
3 $ cat > nlinks.py <<EOF
3 $ cat > nlinks.py <<EOF
4 > import sys
4 > import sys
5 > from mercurial import pycompat, util
5 > from mercurial import pycompat, util
6 > for f in sorted(sys.stdin.readlines()):
6 > for f in sorted(sys.stdin.readlines()):
7 > f = f[:-1]
7 > f = f[:-1]
8 > print(util.nlinks(pycompat.fsencode(f)), f)
8 > print(util.nlinks(pycompat.fsencode(f)), f)
9 > EOF
9 > EOF
10
10
11 $ nlinksdir()
11 $ nlinksdir()
12 > {
12 > {
13 > find "$@" -type f | "$PYTHON" $TESTTMP/nlinks.py
13 > find "$@" -type f | "$PYTHON" $TESTTMP/nlinks.py
14 > }
14 > }
15
15
16 Some implementations of cp can't create hardlinks (replaces 'cp -al' on Linux):
16 Some implementations of cp can't create hardlinks (replaces 'cp -al' on Linux):
17
17
18 $ cat > linkcp.py <<EOF
18 $ cat > linkcp.py <<EOF
19 > import sys
19 > import sys
20 > from mercurial import pycompat, util
20 > from mercurial import pycompat, util
21 > util.copyfiles(pycompat.fsencode(sys.argv[1]),
21 > util.copyfiles(pycompat.fsencode(sys.argv[1]),
22 > pycompat.fsencode(sys.argv[2]), hardlink=True)
22 > pycompat.fsencode(sys.argv[2]), hardlink=True)
23 > EOF
23 > EOF
24
24
25 $ linkcp()
25 $ linkcp()
26 > {
26 > {
27 > "$PYTHON" $TESTTMP/linkcp.py $1 $2
27 > "$PYTHON" $TESTTMP/linkcp.py $1 $2
28 > }
28 > }
29
29
30 Prepare repo r1:
30 Prepare repo r1:
31
31
32 $ hg init r1
32 $ hg init r1
33 $ cd r1
33 $ cd r1
34
34
35 $ echo c1 > f1
35 $ echo c1 > f1
36 $ hg add f1
36 $ hg add f1
37 $ hg ci -m0
37 $ hg ci -m0
38
38
39 $ mkdir d1
39 $ mkdir d1
40 $ cd d1
40 $ cd d1
41 $ echo c2 > f2
41 $ echo c2 > f2
42 $ hg add f2
42 $ hg add f2
43 $ hg ci -m1
43 $ hg ci -m1
44 $ cd ../..
44 $ cd ../..
45
45
46 $ nlinksdir r1/.hg/store
46 $ nlinksdir r1/.hg/store
47 1 r1/.hg/store/00changelog.i
47 1 r1/.hg/store/00changelog.i
48 1 r1/.hg/store/00manifest.i
48 1 r1/.hg/store/00manifest.i
49 1 r1/.hg/store/data/d1/f2.i
49 1 r1/.hg/store/data/d1/f2.i
50 1 r1/.hg/store/data/f1.i
50 1 r1/.hg/store/data/f1.i
51 1 r1/.hg/store/fncache (repofncache !)
51 1 r1/.hg/store/fncache (repofncache !)
52 1 r1/.hg/store/phaseroots
52 1 r1/.hg/store/phaseroots
53 1 r1/.hg/store/requires
53 1 r1/.hg/store/requires
54 1 r1/.hg/store/undo
54 1 r1/.hg/store/undo
55 1 r1/.hg/store/undo.backup.fncache (repofncache !)
55 1 r1/.hg/store/undo.backup.fncache.bck (repofncache !)
56 1 r1/.hg/store/undo.backupfiles
56 1 r1/.hg/store/undo.backupfiles
57
57
58
58
59 Create hardlinked clone r2:
59 Create hardlinked clone r2:
60
60
61 $ hg clone -U --debug r1 r2 --config progress.debug=true
61 $ hg clone -U --debug r1 r2 --config progress.debug=true
62 linking: 1/7 files (14.29%)
62 linking: 1/7 files (14.29%)
63 linking: 2/7 files (28.57%)
63 linking: 2/7 files (28.57%)
64 linking: 3/7 files (42.86%)
64 linking: 3/7 files (42.86%)
65 linking: 4/7 files (57.14%)
65 linking: 4/7 files (57.14%)
66 linking: 5/7 files (71.43%)
66 linking: 5/7 files (71.43%)
67 linking: 6/7 files (85.71%)
67 linking: 6/7 files (85.71%)
68 linking: 7/7 files (100.00%)
68 linking: 7/7 files (100.00%)
69 linked 7 files
69 linked 7 files
70 updating the branch cache
70 updating the branch cache
71
71
72 Create non-hardlinked clone r3:
72 Create non-hardlinked clone r3:
73
73
74 $ hg clone --pull r1 r3
74 $ hg clone --pull r1 r3
75 requesting all changes
75 requesting all changes
76 adding changesets
76 adding changesets
77 adding manifests
77 adding manifests
78 adding file changes
78 adding file changes
79 added 2 changesets with 2 changes to 2 files
79 added 2 changesets with 2 changes to 2 files
80 new changesets 40d85e9847f2:7069c422939c
80 new changesets 40d85e9847f2:7069c422939c
81 updating to branch default
81 updating to branch default
82 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
82 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
83
83
84
84
85 Repos r1 and r2 should now contain hardlinked files:
85 Repos r1 and r2 should now contain hardlinked files:
86
86
87 $ nlinksdir r1/.hg/store
87 $ nlinksdir r1/.hg/store
88 2 r1/.hg/store/00changelog.i
88 2 r1/.hg/store/00changelog.i
89 2 r1/.hg/store/00manifest.i
89 2 r1/.hg/store/00manifest.i
90 2 r1/.hg/store/data/d1/f2.i
90 2 r1/.hg/store/data/d1/f2.i
91 2 r1/.hg/store/data/f1.i
91 2 r1/.hg/store/data/f1.i
92 1 r1/.hg/store/fncache (repofncache !)
92 1 r1/.hg/store/fncache (repofncache !)
93 1 r1/.hg/store/phaseroots
93 1 r1/.hg/store/phaseroots
94 1 r1/.hg/store/requires
94 1 r1/.hg/store/requires
95 1 r1/.hg/store/undo
95 1 r1/.hg/store/undo
96 1 r1/.hg/store/undo.backup.fncache (repofncache !)
96 1 r1/.hg/store/undo.backup.fncache.bck (repofncache !)
97 1 r1/.hg/store/undo.backupfiles
97 1 r1/.hg/store/undo.backupfiles
98
98
99 $ nlinksdir r2/.hg/store
99 $ nlinksdir r2/.hg/store
100 2 r2/.hg/store/00changelog.i
100 2 r2/.hg/store/00changelog.i
101 2 r2/.hg/store/00manifest.i
101 2 r2/.hg/store/00manifest.i
102 2 r2/.hg/store/data/d1/f2.i
102 2 r2/.hg/store/data/d1/f2.i
103 2 r2/.hg/store/data/f1.i
103 2 r2/.hg/store/data/f1.i
104 1 r2/.hg/store/fncache (repofncache !)
104 1 r2/.hg/store/fncache (repofncache !)
105 1 r2/.hg/store/requires
105 1 r2/.hg/store/requires
106
106
107 Repo r3 should not be hardlinked:
107 Repo r3 should not be hardlinked:
108
108
109 $ nlinksdir r3/.hg/store
109 $ nlinksdir r3/.hg/store
110 1 r3/.hg/store/00changelog.i
110 1 r3/.hg/store/00changelog.i
111 1 r3/.hg/store/00manifest.i
111 1 r3/.hg/store/00manifest.i
112 1 r3/.hg/store/data/d1/f2.i
112 1 r3/.hg/store/data/d1/f2.i
113 1 r3/.hg/store/data/f1.i
113 1 r3/.hg/store/data/f1.i
114 1 r3/.hg/store/fncache (repofncache !)
114 1 r3/.hg/store/fncache (repofncache !)
115 1 r3/.hg/store/phaseroots
115 1 r3/.hg/store/phaseroots
116 1 r3/.hg/store/requires
116 1 r3/.hg/store/requires
117 1 r3/.hg/store/undo
117 1 r3/.hg/store/undo
118 1 r3/.hg/store/undo.backupfiles
118 1 r3/.hg/store/undo.backupfiles
119
119
120
120
121 Create a non-inlined filelog in r3:
121 Create a non-inlined filelog in r3:
122
122
123 $ cd r3/d1
123 $ cd r3/d1
124 >>> f = open('data1', 'wb')
124 >>> f = open('data1', 'wb')
125 >>> for x in range(10000):
125 >>> for x in range(10000):
126 ... f.write(b"%d\n" % x) and None
126 ... f.write(b"%d\n" % x) and None
127 >>> f.close()
127 >>> f.close()
128 $ for j in 0 1 2 3 4 5 6 7 8 9; do
128 $ for j in 0 1 2 3 4 5 6 7 8 9; do
129 > cat data1 >> f2
129 > cat data1 >> f2
130 > hg commit -m$j
130 > hg commit -m$j
131 > done
131 > done
132 $ cd ../..
132 $ cd ../..
133
133
134 $ nlinksdir r3/.hg/store
134 $ nlinksdir r3/.hg/store
135 1 r3/.hg/store/00changelog.i
135 1 r3/.hg/store/00changelog.i
136 1 r3/.hg/store/00manifest.i
136 1 r3/.hg/store/00manifest.i
137 1 r3/.hg/store/data/d1/f2.d
137 1 r3/.hg/store/data/d1/f2.d
138 1 r3/.hg/store/data/d1/f2.i
138 1 r3/.hg/store/data/d1/f2.i
139 1 r3/.hg/store/data/f1.i
139 1 r3/.hg/store/data/f1.i
140 1 r3/.hg/store/fncache (repofncache !)
140 1 r3/.hg/store/fncache (repofncache !)
141 1 r3/.hg/store/phaseroots
141 1 r3/.hg/store/phaseroots
142 1 r3/.hg/store/requires
142 1 r3/.hg/store/requires
143 1 r3/.hg/store/undo
143 1 r3/.hg/store/undo
144 1 r3/.hg/store/undo.backupfiles
144 1 r3/.hg/store/undo.backupfiles
145
145
146 Push to repo r1 should break up most hardlinks in r2:
146 Push to repo r1 should break up most hardlinks in r2:
147
147
148 $ hg -R r2 verify -q
148 $ hg -R r2 verify -q
149
149
150 $ cd r3
150 $ cd r3
151 $ hg push
151 $ hg push
152 pushing to $TESTTMP/r1
152 pushing to $TESTTMP/r1
153 searching for changes
153 searching for changes
154 adding changesets
154 adding changesets
155 adding manifests
155 adding manifests
156 adding file changes
156 adding file changes
157 added 10 changesets with 10 changes to 1 files
157 added 10 changesets with 10 changes to 1 files
158
158
159 $ cd ..
159 $ cd ..
160
160
161 $ nlinksdir r2/.hg/store
161 $ nlinksdir r2/.hg/store
162 1 r2/.hg/store/00changelog.i
162 1 r2/.hg/store/00changelog.i
163 1 r2/.hg/store/00manifest.i
163 1 r2/.hg/store/00manifest.i
164 1 r2/.hg/store/data/d1/f2.i
164 1 r2/.hg/store/data/d1/f2.i
165 2 r2/.hg/store/data/f1.i
165 2 r2/.hg/store/data/f1.i
166 [12] r2/\.hg/store/fncache (re) (repofncache !)
166 [12] r2/\.hg/store/fncache (re) (repofncache !)
167 1 r2/.hg/store/requires
167 1 r2/.hg/store/requires
168
168
169 #if hardlink-whitelisted repofncache
169 #if hardlink-whitelisted repofncache
170 $ nlinksdir r2/.hg/store/fncache
170 $ nlinksdir r2/.hg/store/fncache
171 1 r2/.hg/store/fncache
171 1 r2/.hg/store/fncache
172 #endif
172 #endif
173
173
174 $ hg -R r2 verify -q
174 $ hg -R r2 verify -q
175
175
176 $ cd r1
176 $ cd r1
177 $ hg up
177 $ hg up
178 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
178 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
179
179
180 Committing a change to f1 in r1 must break up hardlink f1.i in r2:
180 Committing a change to f1 in r1 must break up hardlink f1.i in r2:
181
181
182 $ echo c1c1 >> f1
182 $ echo c1c1 >> f1
183 $ hg ci -m00
183 $ hg ci -m00
184 $ cd ..
184 $ cd ..
185
185
186 $ nlinksdir r2/.hg/store
186 $ nlinksdir r2/.hg/store
187 1 r2/.hg/store/00changelog.i
187 1 r2/.hg/store/00changelog.i
188 1 r2/.hg/store/00manifest.i
188 1 r2/.hg/store/00manifest.i
189 1 r2/.hg/store/data/d1/f2.i
189 1 r2/.hg/store/data/d1/f2.i
190 1 r2/.hg/store/data/f1.i
190 1 r2/.hg/store/data/f1.i
191 1 r2/.hg/store/fncache (repofncache !)
191 1 r2/.hg/store/fncache (repofncache !)
192 1 r2/.hg/store/requires
192 1 r2/.hg/store/requires
193
193
194 #if hardlink-whitelisted repofncache
194 #if hardlink-whitelisted repofncache
195 $ nlinksdir r2/.hg/store/fncache
195 $ nlinksdir r2/.hg/store/fncache
196 1 r2/.hg/store/fncache
196 1 r2/.hg/store/fncache
197 #endif
197 #endif
198
198
199 Create a file which exec permissions we will change
199 Create a file which exec permissions we will change
200 $ cd r3
200 $ cd r3
201 $ echo "echo hello world" > f3
201 $ echo "echo hello world" > f3
202 $ hg add f3
202 $ hg add f3
203 $ hg ci -mf3
203 $ hg ci -mf3
204 $ cd ..
204 $ cd ..
205
205
206 $ cd r3
206 $ cd r3
207 $ hg tip --template '{rev}:{node|short}\n'
207 $ hg tip --template '{rev}:{node|short}\n'
208 12:d3b77733a28a
208 12:d3b77733a28a
209 $ echo bla > f1
209 $ echo bla > f1
210 $ chmod +x f3
210 $ chmod +x f3
211 $ hg ci -m1
211 $ hg ci -m1
212 $ cd ..
212 $ cd ..
213
213
214 Create hardlinked copy r4 of r3 (on Linux, we would call 'cp -al'):
214 Create hardlinked copy r4 of r3 (on Linux, we would call 'cp -al'):
215
215
216 $ linkcp r3 r4
216 $ linkcp r3 r4
217
217
218 'checklink' is produced by hardlinking a symlink, which is undefined whether
218 'checklink' is produced by hardlinking a symlink, which is undefined whether
219 the symlink should be followed or not. It does behave differently on Linux and
219 the symlink should be followed or not. It does behave differently on Linux and
220 BSD. Just remove it so the test pass on both platforms.
220 BSD. Just remove it so the test pass on both platforms.
221
221
222 $ rm -f r4/.hg/wcache/checklink
222 $ rm -f r4/.hg/wcache/checklink
223
223
224 r4 has hardlinks in the working dir (not just inside .hg):
224 r4 has hardlinks in the working dir (not just inside .hg):
225
225
226 $ nlinksdir r4
226 $ nlinksdir r4
227 2 r4/.hg/00changelog.i
227 2 r4/.hg/00changelog.i
228 [24] r4/.hg/branch (re)
228 [24] r4/.hg/branch (re)
229 2 r4/.hg/cache/branch2-base
229 2 r4/.hg/cache/branch2-base
230 2 r4/.hg/cache/branch2-immutable
230 2 r4/.hg/cache/branch2-immutable
231 2 r4/.hg/cache/branch2-served
231 2 r4/.hg/cache/branch2-served
232 2 r4/.hg/cache/branch2-served.hidden
232 2 r4/.hg/cache/branch2-served.hidden
233 2 r4/.hg/cache/branch2-visible
233 2 r4/.hg/cache/branch2-visible
234 2 r4/.hg/cache/branch2-visible-hidden
234 2 r4/.hg/cache/branch2-visible-hidden
235 2 r4/.hg/cache/rbc-names-v1
235 2 r4/.hg/cache/rbc-names-v1
236 2 r4/.hg/cache/rbc-revs-v1
236 2 r4/.hg/cache/rbc-revs-v1
237 2 r4/.hg/cache/tags2
237 2 r4/.hg/cache/tags2
238 2 r4/.hg/cache/tags2-served
238 2 r4/.hg/cache/tags2-served
239 2 r4/.hg/dirstate
239 2 r4/.hg/dirstate
240 2 r4/.hg/fsmonitor.state (fsmonitor !)
240 2 r4/.hg/fsmonitor.state (fsmonitor !)
241 2 r4/.hg/hgrc
241 2 r4/.hg/hgrc
242 2 r4/.hg/last-message.txt
242 2 r4/.hg/last-message.txt
243 2 r4/.hg/requires
243 2 r4/.hg/requires
244 2 r4/.hg/store/00changelog.i
244 2 r4/.hg/store/00changelog.i
245 2 r4/.hg/store/00manifest.i
245 2 r4/.hg/store/00manifest.i
246 2 r4/.hg/store/data/d1/f2.d
246 2 r4/.hg/store/data/d1/f2.d
247 2 r4/.hg/store/data/d1/f2.i
247 2 r4/.hg/store/data/d1/f2.i
248 2 r4/.hg/store/data/f1.i
248 2 r4/.hg/store/data/f1.i
249 2 r4/.hg/store/data/f3.i
249 2 r4/.hg/store/data/f3.i
250 2 r4/.hg/store/fncache (repofncache !)
250 2 r4/.hg/store/fncache (repofncache !)
251 2 r4/.hg/store/phaseroots
251 2 r4/.hg/store/phaseroots
252 2 r4/.hg/store/requires
252 2 r4/.hg/store/requires
253 2 r4/.hg/store/undo
253 2 r4/.hg/store/undo
254 2 r4/.hg/store/undo.backupfiles
254 2 r4/.hg/store/undo.backupfiles
255 [24] r4/.hg/undo.backup.branch (re)
255 [24] r4/.hg/undo.backup.branch.bck (re)
256 2 r4/\.hg/undo\.backup\.dirstate (re)
256 2 r4/\.hg/undo\.backup\.dirstate.bck (re)
257 2 r4/.hg/undo.desc
257 2 r4/.hg/undo.desc
258 2 r4/.hg/wcache/checkisexec (execbit !)
258 2 r4/.hg/wcache/checkisexec (execbit !)
259 2 r4/.hg/wcache/checklink-target (symlink !)
259 2 r4/.hg/wcache/checklink-target (symlink !)
260 2 r4/.hg/wcache/checknoexec (execbit !)
260 2 r4/.hg/wcache/checknoexec (execbit !)
261 2 r4/.hg/wcache/manifestfulltextcache (reporevlogstore !)
261 2 r4/.hg/wcache/manifestfulltextcache (reporevlogstore !)
262 2 r4/d1/data1
262 2 r4/d1/data1
263 2 r4/d1/f2
263 2 r4/d1/f2
264 2 r4/f1
264 2 r4/f1
265 2 r4/f3
265 2 r4/f3
266
266
267 Update back to revision 12 in r4 should break hardlink of file f1 and f3:
267 Update back to revision 12 in r4 should break hardlink of file f1 and f3:
268 #if hardlink-whitelisted
268 #if hardlink-whitelisted
269 $ nlinksdir r4/.hg/undo.backup.dirstate r4/.hg/dirstate
269 $ nlinksdir r4/.hg/undo.backup.dirstate.bck r4/.hg/dirstate
270 2 r4/.hg/dirstate
270 2 r4/.hg/dirstate
271 2 r4/.hg/undo.backup.dirstate
271 2 r4/.hg/undo.backup.dirstate.bck
272 #endif
272 #endif
273
273
274
274
275 $ hg -R r4 up 12
275 $ hg -R r4 up 12
276 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (execbit !)
276 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (execbit !)
277 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-execbit !)
277 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-execbit !)
278
278
279 $ nlinksdir r4
279 $ nlinksdir r4
280 2 r4/.hg/00changelog.i
280 2 r4/.hg/00changelog.i
281 1 r4/.hg/branch
281 1 r4/.hg/branch
282 2 r4/.hg/cache/branch2-base
282 2 r4/.hg/cache/branch2-base
283 2 r4/.hg/cache/branch2-immutable
283 2 r4/.hg/cache/branch2-immutable
284 2 r4/.hg/cache/branch2-served
284 2 r4/.hg/cache/branch2-served
285 2 r4/.hg/cache/branch2-served.hidden
285 2 r4/.hg/cache/branch2-served.hidden
286 2 r4/.hg/cache/branch2-visible
286 2 r4/.hg/cache/branch2-visible
287 2 r4/.hg/cache/branch2-visible-hidden
287 2 r4/.hg/cache/branch2-visible-hidden
288 2 r4/.hg/cache/rbc-names-v1
288 2 r4/.hg/cache/rbc-names-v1
289 2 r4/.hg/cache/rbc-revs-v1
289 2 r4/.hg/cache/rbc-revs-v1
290 2 r4/.hg/cache/tags2
290 2 r4/.hg/cache/tags2
291 2 r4/.hg/cache/tags2-served
291 2 r4/.hg/cache/tags2-served
292 1 r4/.hg/dirstate
292 1 r4/.hg/dirstate
293 1 r4/.hg/fsmonitor.state (fsmonitor !)
293 1 r4/.hg/fsmonitor.state (fsmonitor !)
294 2 r4/.hg/hgrc
294 2 r4/.hg/hgrc
295 2 r4/.hg/last-message.txt
295 2 r4/.hg/last-message.txt
296 2 r4/.hg/requires
296 2 r4/.hg/requires
297 2 r4/.hg/store/00changelog.i
297 2 r4/.hg/store/00changelog.i
298 2 r4/.hg/store/00manifest.i
298 2 r4/.hg/store/00manifest.i
299 2 r4/.hg/store/data/d1/f2.d
299 2 r4/.hg/store/data/d1/f2.d
300 2 r4/.hg/store/data/d1/f2.i
300 2 r4/.hg/store/data/d1/f2.i
301 2 r4/.hg/store/data/f1.i
301 2 r4/.hg/store/data/f1.i
302 2 r4/.hg/store/data/f3.i
302 2 r4/.hg/store/data/f3.i
303 2 r4/.hg/store/fncache
303 2 r4/.hg/store/fncache
304 2 r4/.hg/store/phaseroots
304 2 r4/.hg/store/phaseroots
305 2 r4/.hg/store/requires
305 2 r4/.hg/store/requires
306 2 r4/.hg/store/undo
306 2 r4/.hg/store/undo
307 2 r4/.hg/store/undo.backupfiles
307 2 r4/.hg/store/undo.backupfiles
308 [23] r4/.hg/undo.backup.branch (re)
308 [23] r4/.hg/undo.backup.branch.bck (re)
309 2 r4/\.hg/undo\.backup\.dirstate (re)
309 2 r4/\.hg/undo\.backup\.dirstate.bck (re)
310 2 r4/.hg/undo.desc
310 2 r4/.hg/undo.desc
311 2 r4/.hg/wcache/checkisexec (execbit !)
311 2 r4/.hg/wcache/checkisexec (execbit !)
312 2 r4/.hg/wcache/checklink-target (symlink !)
312 2 r4/.hg/wcache/checklink-target (symlink !)
313 2 r4/.hg/wcache/checknoexec (execbit !)
313 2 r4/.hg/wcache/checknoexec (execbit !)
314 1 r4/.hg/wcache/manifestfulltextcache (reporevlogstore !)
314 1 r4/.hg/wcache/manifestfulltextcache (reporevlogstore !)
315 2 r4/d1/data1
315 2 r4/d1/data1
316 2 r4/d1/f2
316 2 r4/d1/f2
317 1 r4/f1
317 1 r4/f1
318 1 r4/f3 (execbit !)
318 1 r4/f3 (execbit !)
319 2 r4/f3 (no-execbit !)
319 2 r4/f3 (no-execbit !)
320
320
321 #if hardlink-whitelisted
321 #if hardlink-whitelisted
322 $ nlinksdir r4/.hg/undo.backup.dirstate r4/.hg/dirstate
322 $ nlinksdir r4/.hg/undo.backup.dirstate.bck r4/.hg/dirstate
323 1 r4/.hg/dirstate
323 1 r4/.hg/dirstate
324 2 r4/.hg/undo.backup.dirstate
324 2 r4/.hg/undo.backup.dirstate.bck
325 #endif
325 #endif
326
326
327 Test hardlinking outside hg:
327 Test hardlinking outside hg:
328
328
329 $ mkdir x
329 $ mkdir x
330 $ echo foo > x/a
330 $ echo foo > x/a
331
331
332 $ linkcp x y
332 $ linkcp x y
333 $ echo bar >> y/a
333 $ echo bar >> y/a
334
334
335 No diff if hardlink:
335 No diff if hardlink:
336
336
337 $ diff x/a y/a
337 $ diff x/a y/a
338
338
339 Test mq hardlinking:
339 Test mq hardlinking:
340
340
341 $ echo "[extensions]" >> $HGRCPATH
341 $ echo "[extensions]" >> $HGRCPATH
342 $ echo "mq=" >> $HGRCPATH
342 $ echo "mq=" >> $HGRCPATH
343
343
344 $ hg init a
344 $ hg init a
345 $ cd a
345 $ cd a
346
346
347 $ hg qimport -n foo - << EOF
347 $ hg qimport -n foo - << EOF
348 > # HG changeset patch
348 > # HG changeset patch
349 > # Date 1 0
349 > # Date 1 0
350 > diff -r 2588a8b53d66 a
350 > diff -r 2588a8b53d66 a
351 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
351 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
352 > +++ b/a Wed Jul 23 15:54:29 2008 +0200
352 > +++ b/a Wed Jul 23 15:54:29 2008 +0200
353 > @@ -0,0 +1,1 @@
353 > @@ -0,0 +1,1 @@
354 > +a
354 > +a
355 > EOF
355 > EOF
356 adding foo to series file
356 adding foo to series file
357
357
358 $ hg qpush
358 $ hg qpush
359 applying foo
359 applying foo
360 now at: foo
360 now at: foo
361
361
362 $ cd ..
362 $ cd ..
363 $ linkcp a b
363 $ linkcp a b
364 $ cd b
364 $ cd b
365
365
366 $ hg qimport -n bar - << EOF
366 $ hg qimport -n bar - << EOF
367 > # HG changeset patch
367 > # HG changeset patch
368 > # Date 2 0
368 > # Date 2 0
369 > diff -r 2588a8b53d66 a
369 > diff -r 2588a8b53d66 a
370 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
370 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
371 > +++ b/b Wed Jul 23 15:54:29 2008 +0200
371 > +++ b/b Wed Jul 23 15:54:29 2008 +0200
372 > @@ -0,0 +1,1 @@
372 > @@ -0,0 +1,1 @@
373 > +b
373 > +b
374 > EOF
374 > EOF
375 adding bar to series file
375 adding bar to series file
376
376
377 $ hg qpush
377 $ hg qpush
378 applying bar
378 applying bar
379 now at: bar
379 now at: bar
380
380
381 $ cat .hg/patches/status
381 $ cat .hg/patches/status
382 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
382 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
383 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c:bar
383 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c:bar
384
384
385 $ cat .hg/patches/series
385 $ cat .hg/patches/series
386 foo
386 foo
387 bar
387 bar
388
388
389 $ cat ../a/.hg/patches/status
389 $ cat ../a/.hg/patches/status
390 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
390 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
391
391
392 $ cat ../a/.hg/patches/series
392 $ cat ../a/.hg/patches/series
393 foo
393 foo
394
394
395 Test tags hardlinking:
395 Test tags hardlinking:
396
396
397 $ hg qdel -r qbase:qtip
397 $ hg qdel -r qbase:qtip
398 patch foo finalized without changeset message
398 patch foo finalized without changeset message
399 patch bar finalized without changeset message
399 patch bar finalized without changeset message
400
400
401 $ hg tag -l lfoo
401 $ hg tag -l lfoo
402 $ hg tag foo
402 $ hg tag foo
403
403
404 $ cd ..
404 $ cd ..
405 $ linkcp b c
405 $ linkcp b c
406 $ cd c
406 $ cd c
407
407
408 $ hg tag -l -r 0 lbar
408 $ hg tag -l -r 0 lbar
409 $ hg tag -r 0 bar
409 $ hg tag -r 0 bar
410
410
411 $ cat .hgtags
411 $ cat .hgtags
412 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
412 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
413 430ed4828a74fa4047bc816a25500f7472ab4bfe bar
413 430ed4828a74fa4047bc816a25500f7472ab4bfe bar
414
414
415 $ cat .hg/localtags
415 $ cat .hg/localtags
416 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
416 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
417 430ed4828a74fa4047bc816a25500f7472ab4bfe lbar
417 430ed4828a74fa4047bc816a25500f7472ab4bfe lbar
418
418
419 $ cat ../b/.hgtags
419 $ cat ../b/.hgtags
420 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
420 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
421
421
422 $ cat ../b/.hg/localtags
422 $ cat ../b/.hg/localtags
423 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
423 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
424
424
425 $ cd ..
425 $ cd ..
@@ -1,1463 +1,1463 b''
1 commit hooks can see env vars
1 commit hooks can see env vars
2 (and post-transaction one are run unlocked)
2 (and post-transaction one are run unlocked)
3
3
4
4
5 $ cat > $TESTTMP/txnabort.checkargs.py <<EOF
5 $ cat > $TESTTMP/txnabort.checkargs.py <<EOF
6 > from mercurial import pycompat
6 > from mercurial import pycompat
7 > def showargs(ui, repo, hooktype, **kwargs):
7 > def showargs(ui, repo, hooktype, **kwargs):
8 > kwargs = pycompat.byteskwargs(kwargs)
8 > kwargs = pycompat.byteskwargs(kwargs)
9 > ui.write(b'%s Python hook: %s\n' % (hooktype,
9 > ui.write(b'%s Python hook: %s\n' % (hooktype,
10 > b','.join(sorted(kwargs))))
10 > b','.join(sorted(kwargs))))
11 > EOF
11 > EOF
12
12
13 $ hg init a
13 $ hg init a
14 $ cd a
14 $ cd a
15 $ cat > .hg/hgrc <<EOF
15 $ cat > .hg/hgrc <<EOF
16 > [hooks]
16 > [hooks]
17 > commit = sh -c "HG_LOCAL= HG_TAG= printenv.py --line commit"
17 > commit = sh -c "HG_LOCAL= HG_TAG= printenv.py --line commit"
18 > commit.b = sh -c "HG_LOCAL= HG_TAG= printenv.py --line commit.b"
18 > commit.b = sh -c "HG_LOCAL= HG_TAG= printenv.py --line commit.b"
19 > precommit = sh -c "HG_LOCAL= HG_NODE= HG_TAG= printenv.py --line precommit"
19 > precommit = sh -c "HG_LOCAL= HG_NODE= HG_TAG= printenv.py --line precommit"
20 > pretxncommit = sh -c "HG_LOCAL= HG_TAG= printenv.py --line pretxncommit"
20 > pretxncommit = sh -c "HG_LOCAL= HG_TAG= printenv.py --line pretxncommit"
21 > pretxncommit.tip = hg -q tip
21 > pretxncommit.tip = hg -q tip
22 > pre-identify = sh -c "printenv.py --line pre-identify 1"
22 > pre-identify = sh -c "printenv.py --line pre-identify 1"
23 > pre-cat = sh -c "printenv.py --line pre-cat"
23 > pre-cat = sh -c "printenv.py --line pre-cat"
24 > post-cat = sh -c "printenv.py --line post-cat"
24 > post-cat = sh -c "printenv.py --line post-cat"
25 > pretxnopen = sh -c "HG_LOCAL= HG_TAG= printenv.py --line pretxnopen"
25 > pretxnopen = sh -c "HG_LOCAL= HG_TAG= printenv.py --line pretxnopen"
26 > pretxnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py --line pretxnclose"
26 > pretxnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py --line pretxnclose"
27 > txnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py --line txnclose"
27 > txnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py --line txnclose"
28 > txnabort.0 = python:$TESTTMP/txnabort.checkargs.py:showargs
28 > txnabort.0 = python:$TESTTMP/txnabort.checkargs.py:showargs
29 > txnabort.1 = sh -c "HG_LOCAL= HG_TAG= printenv.py --line txnabort"
29 > txnabort.1 = sh -c "HG_LOCAL= HG_TAG= printenv.py --line txnabort"
30 > txnclose.checklock = sh -c "hg debuglock > /dev/null"
30 > txnclose.checklock = sh -c "hg debuglock > /dev/null"
31 > EOF
31 > EOF
32 $ echo a > a
32 $ echo a > a
33 $ hg add a
33 $ hg add a
34 $ hg commit -m a
34 $ hg commit -m a
35 precommit hook: HG_HOOKNAME=precommit
35 precommit hook: HG_HOOKNAME=precommit
36 HG_HOOKTYPE=precommit
36 HG_HOOKTYPE=precommit
37 HG_PARENT1=0000000000000000000000000000000000000000
37 HG_PARENT1=0000000000000000000000000000000000000000
38
38
39 pretxnopen hook: HG_HOOKNAME=pretxnopen
39 pretxnopen hook: HG_HOOKNAME=pretxnopen
40 HG_HOOKTYPE=pretxnopen
40 HG_HOOKTYPE=pretxnopen
41 HG_TXNID=TXN:$ID$
41 HG_TXNID=TXN:$ID$
42 HG_TXNNAME=commit
42 HG_TXNNAME=commit
43
43
44 pretxncommit hook: HG_HOOKNAME=pretxncommit
44 pretxncommit hook: HG_HOOKNAME=pretxncommit
45 HG_HOOKTYPE=pretxncommit
45 HG_HOOKTYPE=pretxncommit
46 HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
46 HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
47 HG_PARENT1=0000000000000000000000000000000000000000
47 HG_PARENT1=0000000000000000000000000000000000000000
48 HG_PENDING=$TESTTMP/a
48 HG_PENDING=$TESTTMP/a
49
49
50 0:cb9a9f314b8b
50 0:cb9a9f314b8b
51 pretxnclose hook: HG_HOOKNAME=pretxnclose
51 pretxnclose hook: HG_HOOKNAME=pretxnclose
52 HG_HOOKTYPE=pretxnclose
52 HG_HOOKTYPE=pretxnclose
53 HG_PENDING=$TESTTMP/a
53 HG_PENDING=$TESTTMP/a
54 HG_PHASES_MOVED=1
54 HG_PHASES_MOVED=1
55 HG_TXNID=TXN:$ID$
55 HG_TXNID=TXN:$ID$
56 HG_TXNNAME=commit
56 HG_TXNNAME=commit
57
57
58 txnclose hook: HG_HOOKNAME=txnclose
58 txnclose hook: HG_HOOKNAME=txnclose
59 HG_HOOKTYPE=txnclose
59 HG_HOOKTYPE=txnclose
60 HG_PHASES_MOVED=1
60 HG_PHASES_MOVED=1
61 HG_TXNID=TXN:$ID$
61 HG_TXNID=TXN:$ID$
62 HG_TXNNAME=commit
62 HG_TXNNAME=commit
63
63
64 commit hook: HG_HOOKNAME=commit
64 commit hook: HG_HOOKNAME=commit
65 HG_HOOKTYPE=commit
65 HG_HOOKTYPE=commit
66 HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
66 HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
67 HG_PARENT1=0000000000000000000000000000000000000000
67 HG_PARENT1=0000000000000000000000000000000000000000
68
68
69 commit.b hook: HG_HOOKNAME=commit.b
69 commit.b hook: HG_HOOKNAME=commit.b
70 HG_HOOKTYPE=commit
70 HG_HOOKTYPE=commit
71 HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
71 HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
72 HG_PARENT1=0000000000000000000000000000000000000000
72 HG_PARENT1=0000000000000000000000000000000000000000
73
73
74
74
75 $ hg clone . ../b
75 $ hg clone . ../b
76 updating to branch default
76 updating to branch default
77 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
77 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 $ cd ../b
78 $ cd ../b
79
79
80 changegroup hooks can see env vars
80 changegroup hooks can see env vars
81
81
82 $ cat > .hg/hgrc <<EOF
82 $ cat > .hg/hgrc <<EOF
83 > [hooks]
83 > [hooks]
84 > prechangegroup = sh -c "printenv.py --line prechangegroup"
84 > prechangegroup = sh -c "printenv.py --line prechangegroup"
85 > changegroup = sh -c "printenv.py --line changegroup"
85 > changegroup = sh -c "printenv.py --line changegroup"
86 > incoming = sh -c "printenv.py --line incoming"
86 > incoming = sh -c "printenv.py --line incoming"
87 > EOF
87 > EOF
88
88
89 pretxncommit and commit hooks can see both parents of merge
89 pretxncommit and commit hooks can see both parents of merge
90
90
91 $ cd ../a
91 $ cd ../a
92 $ echo b >> a
92 $ echo b >> a
93 $ hg commit -m a1 -d "1 0"
93 $ hg commit -m a1 -d "1 0"
94 precommit hook: HG_HOOKNAME=precommit
94 precommit hook: HG_HOOKNAME=precommit
95 HG_HOOKTYPE=precommit
95 HG_HOOKTYPE=precommit
96 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
96 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
97
97
98 pretxnopen hook: HG_HOOKNAME=pretxnopen
98 pretxnopen hook: HG_HOOKNAME=pretxnopen
99 HG_HOOKTYPE=pretxnopen
99 HG_HOOKTYPE=pretxnopen
100 HG_TXNID=TXN:$ID$
100 HG_TXNID=TXN:$ID$
101 HG_TXNNAME=commit
101 HG_TXNNAME=commit
102
102
103 pretxncommit hook: HG_HOOKNAME=pretxncommit
103 pretxncommit hook: HG_HOOKNAME=pretxncommit
104 HG_HOOKTYPE=pretxncommit
104 HG_HOOKTYPE=pretxncommit
105 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
105 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
106 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
106 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
107 HG_PENDING=$TESTTMP/a
107 HG_PENDING=$TESTTMP/a
108
108
109 1:ab228980c14d
109 1:ab228980c14d
110 pretxnclose hook: HG_HOOKNAME=pretxnclose
110 pretxnclose hook: HG_HOOKNAME=pretxnclose
111 HG_HOOKTYPE=pretxnclose
111 HG_HOOKTYPE=pretxnclose
112 HG_PENDING=$TESTTMP/a
112 HG_PENDING=$TESTTMP/a
113 HG_TXNID=TXN:$ID$
113 HG_TXNID=TXN:$ID$
114 HG_TXNNAME=commit
114 HG_TXNNAME=commit
115
115
116 txnclose hook: HG_HOOKNAME=txnclose
116 txnclose hook: HG_HOOKNAME=txnclose
117 HG_HOOKTYPE=txnclose
117 HG_HOOKTYPE=txnclose
118 HG_TXNID=TXN:$ID$
118 HG_TXNID=TXN:$ID$
119 HG_TXNNAME=commit
119 HG_TXNNAME=commit
120
120
121 commit hook: HG_HOOKNAME=commit
121 commit hook: HG_HOOKNAME=commit
122 HG_HOOKTYPE=commit
122 HG_HOOKTYPE=commit
123 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
123 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
124 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
124 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
125
125
126 commit.b hook: HG_HOOKNAME=commit.b
126 commit.b hook: HG_HOOKNAME=commit.b
127 HG_HOOKTYPE=commit
127 HG_HOOKTYPE=commit
128 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
128 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
129 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
129 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
130
130
131 $ hg update -C 0
131 $ hg update -C 0
132 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
132 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
133 $ echo b > b
133 $ echo b > b
134 $ hg add b
134 $ hg add b
135 $ hg commit -m b -d '1 0'
135 $ hg commit -m b -d '1 0'
136 precommit hook: HG_HOOKNAME=precommit
136 precommit hook: HG_HOOKNAME=precommit
137 HG_HOOKTYPE=precommit
137 HG_HOOKTYPE=precommit
138 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
138 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
139
139
140 pretxnopen hook: HG_HOOKNAME=pretxnopen
140 pretxnopen hook: HG_HOOKNAME=pretxnopen
141 HG_HOOKTYPE=pretxnopen
141 HG_HOOKTYPE=pretxnopen
142 HG_TXNID=TXN:$ID$
142 HG_TXNID=TXN:$ID$
143 HG_TXNNAME=commit
143 HG_TXNNAME=commit
144
144
145 pretxncommit hook: HG_HOOKNAME=pretxncommit
145 pretxncommit hook: HG_HOOKNAME=pretxncommit
146 HG_HOOKTYPE=pretxncommit
146 HG_HOOKTYPE=pretxncommit
147 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
147 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
148 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
148 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
149 HG_PENDING=$TESTTMP/a
149 HG_PENDING=$TESTTMP/a
150
150
151 2:ee9deb46ab31
151 2:ee9deb46ab31
152 pretxnclose hook: HG_HOOKNAME=pretxnclose
152 pretxnclose hook: HG_HOOKNAME=pretxnclose
153 HG_HOOKTYPE=pretxnclose
153 HG_HOOKTYPE=pretxnclose
154 HG_PENDING=$TESTTMP/a
154 HG_PENDING=$TESTTMP/a
155 HG_TXNID=TXN:$ID$
155 HG_TXNID=TXN:$ID$
156 HG_TXNNAME=commit
156 HG_TXNNAME=commit
157
157
158 created new head
158 created new head
159 txnclose hook: HG_HOOKNAME=txnclose
159 txnclose hook: HG_HOOKNAME=txnclose
160 HG_HOOKTYPE=txnclose
160 HG_HOOKTYPE=txnclose
161 HG_TXNID=TXN:$ID$
161 HG_TXNID=TXN:$ID$
162 HG_TXNNAME=commit
162 HG_TXNNAME=commit
163
163
164 commit hook: HG_HOOKNAME=commit
164 commit hook: HG_HOOKNAME=commit
165 HG_HOOKTYPE=commit
165 HG_HOOKTYPE=commit
166 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
166 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
167 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
167 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
168
168
169 commit.b hook: HG_HOOKNAME=commit.b
169 commit.b hook: HG_HOOKNAME=commit.b
170 HG_HOOKTYPE=commit
170 HG_HOOKTYPE=commit
171 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
171 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
172 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
172 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
173
173
174 $ hg merge 1
174 $ hg merge 1
175 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
175 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
176 (branch merge, don't forget to commit)
176 (branch merge, don't forget to commit)
177 $ hg commit -m merge -d '2 0'
177 $ hg commit -m merge -d '2 0'
178 precommit hook: HG_HOOKNAME=precommit
178 precommit hook: HG_HOOKNAME=precommit
179 HG_HOOKTYPE=precommit
179 HG_HOOKTYPE=precommit
180 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
180 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
181 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
181 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
182
182
183 pretxnopen hook: HG_HOOKNAME=pretxnopen
183 pretxnopen hook: HG_HOOKNAME=pretxnopen
184 HG_HOOKTYPE=pretxnopen
184 HG_HOOKTYPE=pretxnopen
185 HG_TXNID=TXN:$ID$
185 HG_TXNID=TXN:$ID$
186 HG_TXNNAME=commit
186 HG_TXNNAME=commit
187
187
188 pretxncommit hook: HG_HOOKNAME=pretxncommit
188 pretxncommit hook: HG_HOOKNAME=pretxncommit
189 HG_HOOKTYPE=pretxncommit
189 HG_HOOKTYPE=pretxncommit
190 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
190 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
191 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
191 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
192 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
192 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
193 HG_PENDING=$TESTTMP/a
193 HG_PENDING=$TESTTMP/a
194
194
195 3:07f3376c1e65
195 3:07f3376c1e65
196 pretxnclose hook: HG_HOOKNAME=pretxnclose
196 pretxnclose hook: HG_HOOKNAME=pretxnclose
197 HG_HOOKTYPE=pretxnclose
197 HG_HOOKTYPE=pretxnclose
198 HG_PENDING=$TESTTMP/a
198 HG_PENDING=$TESTTMP/a
199 HG_TXNID=TXN:$ID$
199 HG_TXNID=TXN:$ID$
200 HG_TXNNAME=commit
200 HG_TXNNAME=commit
201
201
202 txnclose hook: HG_HOOKNAME=txnclose
202 txnclose hook: HG_HOOKNAME=txnclose
203 HG_HOOKTYPE=txnclose
203 HG_HOOKTYPE=txnclose
204 HG_TXNID=TXN:$ID$
204 HG_TXNID=TXN:$ID$
205 HG_TXNNAME=commit
205 HG_TXNNAME=commit
206
206
207 commit hook: HG_HOOKNAME=commit
207 commit hook: HG_HOOKNAME=commit
208 HG_HOOKTYPE=commit
208 HG_HOOKTYPE=commit
209 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
209 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
210 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
210 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
211 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
211 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
212
212
213 commit.b hook: HG_HOOKNAME=commit.b
213 commit.b hook: HG_HOOKNAME=commit.b
214 HG_HOOKTYPE=commit
214 HG_HOOKTYPE=commit
215 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
215 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
216 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
216 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
217 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
217 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
218
218
219
219
220 test generic hooks
220 test generic hooks
221
221
222 $ hg id
222 $ hg id
223 pre-identify hook: HG_ARGS=id
223 pre-identify hook: HG_ARGS=id
224 HG_HOOKNAME=pre-identify
224 HG_HOOKNAME=pre-identify
225 HG_HOOKTYPE=pre-identify
225 HG_HOOKTYPE=pre-identify
226 HG_OPTS={'bookmarks': None, 'branch': None, 'id': None, 'insecure': None, 'num': None, 'remotecmd': '', 'rev': '', 'ssh': '', 'tags': None, 'template': ''}
226 HG_OPTS={'bookmarks': None, 'branch': None, 'id': None, 'insecure': None, 'num': None, 'remotecmd': '', 'rev': '', 'ssh': '', 'tags': None, 'template': ''}
227 HG_PATS=[]
227 HG_PATS=[]
228
228
229 abort: pre-identify hook exited with status 1
229 abort: pre-identify hook exited with status 1
230 [40]
230 [40]
231 $ hg cat b
231 $ hg cat b
232 pre-cat hook: HG_ARGS=cat b
232 pre-cat hook: HG_ARGS=cat b
233 HG_HOOKNAME=pre-cat
233 HG_HOOKNAME=pre-cat
234 HG_HOOKTYPE=pre-cat
234 HG_HOOKTYPE=pre-cat
235 HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': '', 'template': ''}
235 HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': '', 'template': ''}
236 HG_PATS=['b']
236 HG_PATS=['b']
237
237
238 b
238 b
239 post-cat hook: HG_ARGS=cat b
239 post-cat hook: HG_ARGS=cat b
240 HG_HOOKNAME=post-cat
240 HG_HOOKNAME=post-cat
241 HG_HOOKTYPE=post-cat
241 HG_HOOKTYPE=post-cat
242 HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': '', 'template': ''}
242 HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': '', 'template': ''}
243 HG_PATS=['b']
243 HG_PATS=['b']
244 HG_RESULT=0
244 HG_RESULT=0
245
245
246
246
247 $ cd ../b
247 $ cd ../b
248 $ hg pull ../a
248 $ hg pull ../a
249 pulling from ../a
249 pulling from ../a
250 searching for changes
250 searching for changes
251 prechangegroup hook: HG_HOOKNAME=prechangegroup
251 prechangegroup hook: HG_HOOKNAME=prechangegroup
252 HG_HOOKTYPE=prechangegroup
252 HG_HOOKTYPE=prechangegroup
253 HG_SOURCE=pull
253 HG_SOURCE=pull
254 HG_TXNID=TXN:$ID$
254 HG_TXNID=TXN:$ID$
255 HG_TXNNAME=pull
255 HG_TXNNAME=pull
256 file:/*/$TESTTMP/a (glob)
256 file:/*/$TESTTMP/a (glob)
257 HG_URL=file:$TESTTMP/a
257 HG_URL=file:$TESTTMP/a
258
258
259 adding changesets
259 adding changesets
260 adding manifests
260 adding manifests
261 adding file changes
261 adding file changes
262 added 3 changesets with 2 changes to 2 files
262 added 3 changesets with 2 changes to 2 files
263 new changesets ab228980c14d:07f3376c1e65
263 new changesets ab228980c14d:07f3376c1e65
264 changegroup hook: HG_HOOKNAME=changegroup
264 changegroup hook: HG_HOOKNAME=changegroup
265 HG_HOOKTYPE=changegroup
265 HG_HOOKTYPE=changegroup
266 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
266 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
267 HG_NODE_LAST=07f3376c1e655977439df2a814e3cc14b27abac2
267 HG_NODE_LAST=07f3376c1e655977439df2a814e3cc14b27abac2
268 HG_SOURCE=pull
268 HG_SOURCE=pull
269 HG_TXNID=TXN:$ID$
269 HG_TXNID=TXN:$ID$
270 HG_TXNNAME=pull
270 HG_TXNNAME=pull
271 file:/*/$TESTTMP/a (glob)
271 file:/*/$TESTTMP/a (glob)
272 HG_URL=file:$TESTTMP/a
272 HG_URL=file:$TESTTMP/a
273
273
274 incoming hook: HG_HOOKNAME=incoming
274 incoming hook: HG_HOOKNAME=incoming
275 HG_HOOKTYPE=incoming
275 HG_HOOKTYPE=incoming
276 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
276 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
277 HG_SOURCE=pull
277 HG_SOURCE=pull
278 HG_TXNID=TXN:$ID$
278 HG_TXNID=TXN:$ID$
279 HG_TXNNAME=pull
279 HG_TXNNAME=pull
280 file:/*/$TESTTMP/a (glob)
280 file:/*/$TESTTMP/a (glob)
281 HG_URL=file:$TESTTMP/a
281 HG_URL=file:$TESTTMP/a
282
282
283 incoming hook: HG_HOOKNAME=incoming
283 incoming hook: HG_HOOKNAME=incoming
284 HG_HOOKTYPE=incoming
284 HG_HOOKTYPE=incoming
285 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
285 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
286 HG_SOURCE=pull
286 HG_SOURCE=pull
287 HG_TXNID=TXN:$ID$
287 HG_TXNID=TXN:$ID$
288 HG_TXNNAME=pull
288 HG_TXNNAME=pull
289 file:/*/$TESTTMP/a (glob)
289 file:/*/$TESTTMP/a (glob)
290 HG_URL=file:$TESTTMP/a
290 HG_URL=file:$TESTTMP/a
291
291
292 incoming hook: HG_HOOKNAME=incoming
292 incoming hook: HG_HOOKNAME=incoming
293 HG_HOOKTYPE=incoming
293 HG_HOOKTYPE=incoming
294 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
294 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
295 HG_SOURCE=pull
295 HG_SOURCE=pull
296 HG_TXNID=TXN:$ID$
296 HG_TXNID=TXN:$ID$
297 HG_TXNNAME=pull
297 HG_TXNNAME=pull
298 file:/*/$TESTTMP/a (glob)
298 file:/*/$TESTTMP/a (glob)
299 HG_URL=file:$TESTTMP/a
299 HG_URL=file:$TESTTMP/a
300
300
301 (run 'hg update' to get a working copy)
301 (run 'hg update' to get a working copy)
302
302
303 tag hooks can see env vars
303 tag hooks can see env vars
304
304
305 $ cd ../a
305 $ cd ../a
306 $ cat >> .hg/hgrc <<EOF
306 $ cat >> .hg/hgrc <<EOF
307 > pretag = sh -c "printenv.py --line pretag"
307 > pretag = sh -c "printenv.py --line pretag"
308 > tag = sh -c "HG_PARENT1= HG_PARENT2= printenv.py --line tag"
308 > tag = sh -c "HG_PARENT1= HG_PARENT2= printenv.py --line tag"
309 > EOF
309 > EOF
310 $ hg tag -d '3 0' a
310 $ hg tag -d '3 0' a
311 pretag hook: HG_HOOKNAME=pretag
311 pretag hook: HG_HOOKNAME=pretag
312 HG_HOOKTYPE=pretag
312 HG_HOOKTYPE=pretag
313 HG_LOCAL=0
313 HG_LOCAL=0
314 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
314 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
315 HG_TAG=a
315 HG_TAG=a
316
316
317 precommit hook: HG_HOOKNAME=precommit
317 precommit hook: HG_HOOKNAME=precommit
318 HG_HOOKTYPE=precommit
318 HG_HOOKTYPE=precommit
319 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
319 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
320
320
321 pretxnopen hook: HG_HOOKNAME=pretxnopen
321 pretxnopen hook: HG_HOOKNAME=pretxnopen
322 HG_HOOKTYPE=pretxnopen
322 HG_HOOKTYPE=pretxnopen
323 HG_TXNID=TXN:$ID$
323 HG_TXNID=TXN:$ID$
324 HG_TXNNAME=commit
324 HG_TXNNAME=commit
325
325
326 pretxncommit hook: HG_HOOKNAME=pretxncommit
326 pretxncommit hook: HG_HOOKNAME=pretxncommit
327 HG_HOOKTYPE=pretxncommit
327 HG_HOOKTYPE=pretxncommit
328 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
328 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
329 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
329 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
330 HG_PENDING=$TESTTMP/a
330 HG_PENDING=$TESTTMP/a
331
331
332 4:539e4b31b6dc
332 4:539e4b31b6dc
333 pretxnclose hook: HG_HOOKNAME=pretxnclose
333 pretxnclose hook: HG_HOOKNAME=pretxnclose
334 HG_HOOKTYPE=pretxnclose
334 HG_HOOKTYPE=pretxnclose
335 HG_PENDING=$TESTTMP/a
335 HG_PENDING=$TESTTMP/a
336 HG_TXNID=TXN:$ID$
336 HG_TXNID=TXN:$ID$
337 HG_TXNNAME=commit
337 HG_TXNNAME=commit
338
338
339 tag hook: HG_HOOKNAME=tag
339 tag hook: HG_HOOKNAME=tag
340 HG_HOOKTYPE=tag
340 HG_HOOKTYPE=tag
341 HG_LOCAL=0
341 HG_LOCAL=0
342 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
342 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
343 HG_TAG=a
343 HG_TAG=a
344
344
345 txnclose hook: HG_HOOKNAME=txnclose
345 txnclose hook: HG_HOOKNAME=txnclose
346 HG_HOOKTYPE=txnclose
346 HG_HOOKTYPE=txnclose
347 HG_TXNID=TXN:$ID$
347 HG_TXNID=TXN:$ID$
348 HG_TXNNAME=commit
348 HG_TXNNAME=commit
349
349
350 commit hook: HG_HOOKNAME=commit
350 commit hook: HG_HOOKNAME=commit
351 HG_HOOKTYPE=commit
351 HG_HOOKTYPE=commit
352 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
352 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
353 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
353 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
354
354
355 commit.b hook: HG_HOOKNAME=commit.b
355 commit.b hook: HG_HOOKNAME=commit.b
356 HG_HOOKTYPE=commit
356 HG_HOOKTYPE=commit
357 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
357 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
358 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
358 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
359
359
360 $ hg tag -l la
360 $ hg tag -l la
361 pretag hook: HG_HOOKNAME=pretag
361 pretag hook: HG_HOOKNAME=pretag
362 HG_HOOKTYPE=pretag
362 HG_HOOKTYPE=pretag
363 HG_LOCAL=1
363 HG_LOCAL=1
364 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
364 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
365 HG_TAG=la
365 HG_TAG=la
366
366
367 tag hook: HG_HOOKNAME=tag
367 tag hook: HG_HOOKNAME=tag
368 HG_HOOKTYPE=tag
368 HG_HOOKTYPE=tag
369 HG_LOCAL=1
369 HG_LOCAL=1
370 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
370 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
371 HG_TAG=la
371 HG_TAG=la
372
372
373
373
374 pretag hook can forbid tagging
374 pretag hook can forbid tagging
375
375
376 $ cat >> .hg/hgrc <<EOF
376 $ cat >> .hg/hgrc <<EOF
377 > pretag.forbid = sh -c "printenv.py --line pretag.forbid 1"
377 > pretag.forbid = sh -c "printenv.py --line pretag.forbid 1"
378 > EOF
378 > EOF
379 $ hg tag -d '4 0' fa
379 $ hg tag -d '4 0' fa
380 pretag hook: HG_HOOKNAME=pretag
380 pretag hook: HG_HOOKNAME=pretag
381 HG_HOOKTYPE=pretag
381 HG_HOOKTYPE=pretag
382 HG_LOCAL=0
382 HG_LOCAL=0
383 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
383 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
384 HG_TAG=fa
384 HG_TAG=fa
385
385
386 pretag.forbid hook: HG_HOOKNAME=pretag.forbid
386 pretag.forbid hook: HG_HOOKNAME=pretag.forbid
387 HG_HOOKTYPE=pretag
387 HG_HOOKTYPE=pretag
388 HG_LOCAL=0
388 HG_LOCAL=0
389 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
389 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
390 HG_TAG=fa
390 HG_TAG=fa
391
391
392 abort: pretag.forbid hook exited with status 1
392 abort: pretag.forbid hook exited with status 1
393 [40]
393 [40]
394 $ hg tag -l fla
394 $ hg tag -l fla
395 pretag hook: HG_HOOKNAME=pretag
395 pretag hook: HG_HOOKNAME=pretag
396 HG_HOOKTYPE=pretag
396 HG_HOOKTYPE=pretag
397 HG_LOCAL=1
397 HG_LOCAL=1
398 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
398 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
399 HG_TAG=fla
399 HG_TAG=fla
400
400
401 pretag.forbid hook: HG_HOOKNAME=pretag.forbid
401 pretag.forbid hook: HG_HOOKNAME=pretag.forbid
402 HG_HOOKTYPE=pretag
402 HG_HOOKTYPE=pretag
403 HG_LOCAL=1
403 HG_LOCAL=1
404 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
404 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
405 HG_TAG=fla
405 HG_TAG=fla
406
406
407 abort: pretag.forbid hook exited with status 1
407 abort: pretag.forbid hook exited with status 1
408 [40]
408 [40]
409
409
410 pretxncommit hook can see changeset, can roll back txn, changeset no
410 pretxncommit hook can see changeset, can roll back txn, changeset no
411 more there after
411 more there after
412
412
413 $ cat >> .hg/hgrc <<EOF
413 $ cat >> .hg/hgrc <<EOF
414 > pretxncommit.forbid0 = sh -c "hg tip -q"
414 > pretxncommit.forbid0 = sh -c "hg tip -q"
415 > pretxncommit.forbid1 = sh -c "printenv.py --line pretxncommit.forbid 1"
415 > pretxncommit.forbid1 = sh -c "printenv.py --line pretxncommit.forbid 1"
416 > EOF
416 > EOF
417 $ echo z > z
417 $ echo z > z
418 $ hg add z
418 $ hg add z
419 $ hg -q tip
419 $ hg -q tip
420 4:539e4b31b6dc
420 4:539e4b31b6dc
421 $ hg commit -m 'fail' -d '4 0'
421 $ hg commit -m 'fail' -d '4 0'
422 precommit hook: HG_HOOKNAME=precommit
422 precommit hook: HG_HOOKNAME=precommit
423 HG_HOOKTYPE=precommit
423 HG_HOOKTYPE=precommit
424 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
424 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
425
425
426 pretxnopen hook: HG_HOOKNAME=pretxnopen
426 pretxnopen hook: HG_HOOKNAME=pretxnopen
427 HG_HOOKTYPE=pretxnopen
427 HG_HOOKTYPE=pretxnopen
428 HG_TXNID=TXN:$ID$
428 HG_TXNID=TXN:$ID$
429 HG_TXNNAME=commit
429 HG_TXNNAME=commit
430
430
431 pretxncommit hook: HG_HOOKNAME=pretxncommit
431 pretxncommit hook: HG_HOOKNAME=pretxncommit
432 HG_HOOKTYPE=pretxncommit
432 HG_HOOKTYPE=pretxncommit
433 HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567
433 HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567
434 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
434 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
435 HG_PENDING=$TESTTMP/a
435 HG_PENDING=$TESTTMP/a
436
436
437 5:6f611f8018c1
437 5:6f611f8018c1
438 5:6f611f8018c1
438 5:6f611f8018c1
439 pretxncommit.forbid hook: HG_HOOKNAME=pretxncommit.forbid1
439 pretxncommit.forbid hook: HG_HOOKNAME=pretxncommit.forbid1
440 HG_HOOKTYPE=pretxncommit
440 HG_HOOKTYPE=pretxncommit
441 HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567
441 HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567
442 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
442 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
443 HG_PENDING=$TESTTMP/a
443 HG_PENDING=$TESTTMP/a
444
444
445 transaction abort!
445 transaction abort!
446 txnabort Python hook: changes,txnid,txnname
446 txnabort Python hook: changes,txnid,txnname
447 txnabort hook: HG_HOOKNAME=txnabort.1
447 txnabort hook: HG_HOOKNAME=txnabort.1
448 HG_HOOKTYPE=txnabort
448 HG_HOOKTYPE=txnabort
449 HG_TXNID=TXN:$ID$
449 HG_TXNID=TXN:$ID$
450 HG_TXNNAME=commit
450 HG_TXNNAME=commit
451
451
452 rollback completed
452 rollback completed
453 abort: pretxncommit.forbid1 hook exited with status 1
453 abort: pretxncommit.forbid1 hook exited with status 1
454 [40]
454 [40]
455 $ hg -q tip
455 $ hg -q tip
456 4:539e4b31b6dc
456 4:539e4b31b6dc
457
457
458 (Check that no 'changelog.i.a' file were left behind)
458 (Check that no 'changelog.i.a' file were left behind)
459
459
460 $ ls -1 .hg/store/
460 $ ls -1 .hg/store/
461 00changelog.i
461 00changelog.i
462 00manifest.i
462 00manifest.i
463 data
463 data
464 fncache (repofncache !)
464 fncache (repofncache !)
465 phaseroots
465 phaseroots
466 requires
466 requires
467 undo
467 undo
468 undo.backup.fncache (repofncache !)
468 undo.backup.fncache.bck (repofncache !)
469 undo.backupfiles
469 undo.backupfiles
470
470
471
471
472 precommit hook can prevent commit
472 precommit hook can prevent commit
473
473
474 $ cat >> .hg/hgrc <<EOF
474 $ cat >> .hg/hgrc <<EOF
475 > precommit.forbid = sh -c "printenv.py --line precommit.forbid 1"
475 > precommit.forbid = sh -c "printenv.py --line precommit.forbid 1"
476 > EOF
476 > EOF
477 $ hg commit -m 'fail' -d '4 0'
477 $ hg commit -m 'fail' -d '4 0'
478 precommit hook: HG_HOOKNAME=precommit
478 precommit hook: HG_HOOKNAME=precommit
479 HG_HOOKTYPE=precommit
479 HG_HOOKTYPE=precommit
480 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
480 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
481
481
482 precommit.forbid hook: HG_HOOKNAME=precommit.forbid
482 precommit.forbid hook: HG_HOOKNAME=precommit.forbid
483 HG_HOOKTYPE=precommit
483 HG_HOOKTYPE=precommit
484 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
484 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
485
485
486 abort: precommit.forbid hook exited with status 1
486 abort: precommit.forbid hook exited with status 1
487 [40]
487 [40]
488 $ hg -q tip
488 $ hg -q tip
489 4:539e4b31b6dc
489 4:539e4b31b6dc
490
490
491 preupdate hook can prevent update
491 preupdate hook can prevent update
492
492
493 $ cat >> .hg/hgrc <<EOF
493 $ cat >> .hg/hgrc <<EOF
494 > preupdate = sh -c "printenv.py --line preupdate"
494 > preupdate = sh -c "printenv.py --line preupdate"
495 > EOF
495 > EOF
496 $ hg update 1
496 $ hg update 1
497 preupdate hook: HG_HOOKNAME=preupdate
497 preupdate hook: HG_HOOKNAME=preupdate
498 HG_HOOKTYPE=preupdate
498 HG_HOOKTYPE=preupdate
499 HG_PARENT1=ab228980c14d
499 HG_PARENT1=ab228980c14d
500
500
501 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
501 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
502
502
503 update hook
503 update hook
504
504
505 $ cat >> .hg/hgrc <<EOF
505 $ cat >> .hg/hgrc <<EOF
506 > update = sh -c "printenv.py --line update"
506 > update = sh -c "printenv.py --line update"
507 > EOF
507 > EOF
508 $ hg update
508 $ hg update
509 preupdate hook: HG_HOOKNAME=preupdate
509 preupdate hook: HG_HOOKNAME=preupdate
510 HG_HOOKTYPE=preupdate
510 HG_HOOKTYPE=preupdate
511 HG_PARENT1=539e4b31b6dc
511 HG_PARENT1=539e4b31b6dc
512
512
513 update hook: HG_ERROR=0
513 update hook: HG_ERROR=0
514 HG_HOOKNAME=update
514 HG_HOOKNAME=update
515 HG_HOOKTYPE=update
515 HG_HOOKTYPE=update
516 HG_PARENT1=539e4b31b6dc
516 HG_PARENT1=539e4b31b6dc
517
517
518 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
518 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
519
519
520 pushkey hook
520 pushkey hook
521
521
522 $ cat >> .hg/hgrc <<EOF
522 $ cat >> .hg/hgrc <<EOF
523 > pushkey = sh -c "printenv.py --line pushkey"
523 > pushkey = sh -c "printenv.py --line pushkey"
524 > EOF
524 > EOF
525 $ cd ../b
525 $ cd ../b
526 $ hg bookmark -r null foo
526 $ hg bookmark -r null foo
527 $ hg push -B foo ../a
527 $ hg push -B foo ../a
528 pushing to ../a
528 pushing to ../a
529 searching for changes
529 searching for changes
530 no changes found
530 no changes found
531 pretxnopen hook: HG_HOOKNAME=pretxnopen
531 pretxnopen hook: HG_HOOKNAME=pretxnopen
532 HG_HOOKTYPE=pretxnopen
532 HG_HOOKTYPE=pretxnopen
533 HG_TXNID=TXN:$ID$
533 HG_TXNID=TXN:$ID$
534 HG_TXNNAME=push
534 HG_TXNNAME=push
535
535
536 pretxnclose hook: HG_BOOKMARK_MOVED=1
536 pretxnclose hook: HG_BOOKMARK_MOVED=1
537 HG_BUNDLE2=1
537 HG_BUNDLE2=1
538 HG_HOOKNAME=pretxnclose
538 HG_HOOKNAME=pretxnclose
539 HG_HOOKTYPE=pretxnclose
539 HG_HOOKTYPE=pretxnclose
540 HG_PENDING=$TESTTMP/a
540 HG_PENDING=$TESTTMP/a
541 HG_SOURCE=push
541 HG_SOURCE=push
542 HG_TXNID=TXN:$ID$
542 HG_TXNID=TXN:$ID$
543 HG_TXNNAME=push
543 HG_TXNNAME=push
544 HG_URL=file:$TESTTMP/a
544 HG_URL=file:$TESTTMP/a
545
545
546 pushkey hook: HG_BUNDLE2=1
546 pushkey hook: HG_BUNDLE2=1
547 HG_HOOKNAME=pushkey
547 HG_HOOKNAME=pushkey
548 HG_HOOKTYPE=pushkey
548 HG_HOOKTYPE=pushkey
549 HG_KEY=foo
549 HG_KEY=foo
550 HG_NAMESPACE=bookmarks
550 HG_NAMESPACE=bookmarks
551 HG_NEW=0000000000000000000000000000000000000000
551 HG_NEW=0000000000000000000000000000000000000000
552 HG_PUSHKEYCOMPAT=1
552 HG_PUSHKEYCOMPAT=1
553 HG_SOURCE=push
553 HG_SOURCE=push
554 HG_TXNID=TXN:$ID$
554 HG_TXNID=TXN:$ID$
555 HG_TXNNAME=push
555 HG_TXNNAME=push
556 HG_URL=file:$TESTTMP/a
556 HG_URL=file:$TESTTMP/a
557
557
558 txnclose hook: HG_BOOKMARK_MOVED=1
558 txnclose hook: HG_BOOKMARK_MOVED=1
559 HG_BUNDLE2=1
559 HG_BUNDLE2=1
560 HG_HOOKNAME=txnclose
560 HG_HOOKNAME=txnclose
561 HG_HOOKTYPE=txnclose
561 HG_HOOKTYPE=txnclose
562 HG_SOURCE=push
562 HG_SOURCE=push
563 HG_TXNID=TXN:$ID$
563 HG_TXNID=TXN:$ID$
564 HG_TXNNAME=push
564 HG_TXNNAME=push
565 HG_URL=file:$TESTTMP/a
565 HG_URL=file:$TESTTMP/a
566
566
567 exporting bookmark foo
567 exporting bookmark foo
568 [1]
568 [1]
569 $ cd ../a
569 $ cd ../a
570
570
571 listkeys hook
571 listkeys hook
572
572
573 $ cat >> .hg/hgrc <<EOF
573 $ cat >> .hg/hgrc <<EOF
574 > listkeys = sh -c "printenv.py --line listkeys"
574 > listkeys = sh -c "printenv.py --line listkeys"
575 > EOF
575 > EOF
576 $ hg bookmark -r null bar
576 $ hg bookmark -r null bar
577 pretxnopen hook: HG_HOOKNAME=pretxnopen
577 pretxnopen hook: HG_HOOKNAME=pretxnopen
578 HG_HOOKTYPE=pretxnopen
578 HG_HOOKTYPE=pretxnopen
579 HG_TXNID=TXN:$ID$
579 HG_TXNID=TXN:$ID$
580 HG_TXNNAME=bookmark
580 HG_TXNNAME=bookmark
581
581
582 pretxnclose hook: HG_BOOKMARK_MOVED=1
582 pretxnclose hook: HG_BOOKMARK_MOVED=1
583 HG_HOOKNAME=pretxnclose
583 HG_HOOKNAME=pretxnclose
584 HG_HOOKTYPE=pretxnclose
584 HG_HOOKTYPE=pretxnclose
585 HG_PENDING=$TESTTMP/a
585 HG_PENDING=$TESTTMP/a
586 HG_TXNID=TXN:$ID$
586 HG_TXNID=TXN:$ID$
587 HG_TXNNAME=bookmark
587 HG_TXNNAME=bookmark
588
588
589 txnclose hook: HG_BOOKMARK_MOVED=1
589 txnclose hook: HG_BOOKMARK_MOVED=1
590 HG_HOOKNAME=txnclose
590 HG_HOOKNAME=txnclose
591 HG_HOOKTYPE=txnclose
591 HG_HOOKTYPE=txnclose
592 HG_TXNID=TXN:$ID$
592 HG_TXNID=TXN:$ID$
593 HG_TXNNAME=bookmark
593 HG_TXNNAME=bookmark
594
594
595 $ cd ../b
595 $ cd ../b
596 $ hg pull -B bar ../a
596 $ hg pull -B bar ../a
597 pulling from ../a
597 pulling from ../a
598 listkeys hook: HG_HOOKNAME=listkeys
598 listkeys hook: HG_HOOKNAME=listkeys
599 HG_HOOKTYPE=listkeys
599 HG_HOOKTYPE=listkeys
600 HG_NAMESPACE=bookmarks
600 HG_NAMESPACE=bookmarks
601 HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
601 HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
602
602
603 no changes found
603 no changes found
604 adding remote bookmark bar
604 adding remote bookmark bar
605 $ cd ../a
605 $ cd ../a
606
606
607 test that prepushkey can prevent incoming keys
607 test that prepushkey can prevent incoming keys
608
608
609 $ cat >> .hg/hgrc <<EOF
609 $ cat >> .hg/hgrc <<EOF
610 > prepushkey = sh -c "printenv.py --line prepushkey.forbid 1"
610 > prepushkey = sh -c "printenv.py --line prepushkey.forbid 1"
611 > EOF
611 > EOF
612 $ cd ../b
612 $ cd ../b
613 $ hg bookmark -r null baz
613 $ hg bookmark -r null baz
614 $ hg push -B baz ../a
614 $ hg push -B baz ../a
615 pushing to ../a
615 pushing to ../a
616 searching for changes
616 searching for changes
617 listkeys hook: HG_HOOKNAME=listkeys
617 listkeys hook: HG_HOOKNAME=listkeys
618 HG_HOOKTYPE=listkeys
618 HG_HOOKTYPE=listkeys
619 HG_NAMESPACE=phases
619 HG_NAMESPACE=phases
620 HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
620 HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
621
621
622 listkeys hook: HG_HOOKNAME=listkeys
622 listkeys hook: HG_HOOKNAME=listkeys
623 HG_HOOKTYPE=listkeys
623 HG_HOOKTYPE=listkeys
624 HG_NAMESPACE=bookmarks
624 HG_NAMESPACE=bookmarks
625 HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
625 HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
626
626
627 no changes found
627 no changes found
628 pretxnopen hook: HG_HOOKNAME=pretxnopen
628 pretxnopen hook: HG_HOOKNAME=pretxnopen
629 HG_HOOKTYPE=pretxnopen
629 HG_HOOKTYPE=pretxnopen
630 HG_TXNID=TXN:$ID$
630 HG_TXNID=TXN:$ID$
631 HG_TXNNAME=push
631 HG_TXNNAME=push
632
632
633 prepushkey.forbid hook: HG_BUNDLE2=1
633 prepushkey.forbid hook: HG_BUNDLE2=1
634 HG_HOOKNAME=prepushkey
634 HG_HOOKNAME=prepushkey
635 HG_HOOKTYPE=prepushkey
635 HG_HOOKTYPE=prepushkey
636 HG_KEY=baz
636 HG_KEY=baz
637 HG_NAMESPACE=bookmarks
637 HG_NAMESPACE=bookmarks
638 HG_NEW=0000000000000000000000000000000000000000
638 HG_NEW=0000000000000000000000000000000000000000
639 HG_PUSHKEYCOMPAT=1
639 HG_PUSHKEYCOMPAT=1
640 HG_SOURCE=push
640 HG_SOURCE=push
641 HG_TXNID=TXN:$ID$
641 HG_TXNID=TXN:$ID$
642 HG_TXNNAME=push
642 HG_TXNNAME=push
643 HG_URL=file:$TESTTMP/a
643 HG_URL=file:$TESTTMP/a
644
644
645 txnabort Python hook: bundle2,changes,source,txnid,txnname,url
645 txnabort Python hook: bundle2,changes,source,txnid,txnname,url
646 txnabort hook: HG_BUNDLE2=1
646 txnabort hook: HG_BUNDLE2=1
647 HG_HOOKNAME=txnabort.1
647 HG_HOOKNAME=txnabort.1
648 HG_HOOKTYPE=txnabort
648 HG_HOOKTYPE=txnabort
649 HG_SOURCE=push
649 HG_SOURCE=push
650 HG_TXNID=TXN:$ID$
650 HG_TXNID=TXN:$ID$
651 HG_TXNNAME=push
651 HG_TXNNAME=push
652 HG_URL=file:$TESTTMP/a
652 HG_URL=file:$TESTTMP/a
653
653
654 abort: prepushkey hook exited with status 1
654 abort: prepushkey hook exited with status 1
655 [40]
655 [40]
656 $ cd ../a
656 $ cd ../a
657
657
658 test that prelistkeys can prevent listing keys
658 test that prelistkeys can prevent listing keys
659
659
660 $ cat >> .hg/hgrc <<EOF
660 $ cat >> .hg/hgrc <<EOF
661 > prelistkeys = sh -c "printenv.py --line prelistkeys.forbid 1"
661 > prelistkeys = sh -c "printenv.py --line prelistkeys.forbid 1"
662 > EOF
662 > EOF
663 $ hg bookmark -r null quux
663 $ hg bookmark -r null quux
664 pretxnopen hook: HG_HOOKNAME=pretxnopen
664 pretxnopen hook: HG_HOOKNAME=pretxnopen
665 HG_HOOKTYPE=pretxnopen
665 HG_HOOKTYPE=pretxnopen
666 HG_TXNID=TXN:$ID$
666 HG_TXNID=TXN:$ID$
667 HG_TXNNAME=bookmark
667 HG_TXNNAME=bookmark
668
668
669 pretxnclose hook: HG_BOOKMARK_MOVED=1
669 pretxnclose hook: HG_BOOKMARK_MOVED=1
670 HG_HOOKNAME=pretxnclose
670 HG_HOOKNAME=pretxnclose
671 HG_HOOKTYPE=pretxnclose
671 HG_HOOKTYPE=pretxnclose
672 HG_PENDING=$TESTTMP/a
672 HG_PENDING=$TESTTMP/a
673 HG_TXNID=TXN:$ID$
673 HG_TXNID=TXN:$ID$
674 HG_TXNNAME=bookmark
674 HG_TXNNAME=bookmark
675
675
676 txnclose hook: HG_BOOKMARK_MOVED=1
676 txnclose hook: HG_BOOKMARK_MOVED=1
677 HG_HOOKNAME=txnclose
677 HG_HOOKNAME=txnclose
678 HG_HOOKTYPE=txnclose
678 HG_HOOKTYPE=txnclose
679 HG_TXNID=TXN:$ID$
679 HG_TXNID=TXN:$ID$
680 HG_TXNNAME=bookmark
680 HG_TXNNAME=bookmark
681
681
682 $ cd ../b
682 $ cd ../b
683 $ hg pull -B quux ../a
683 $ hg pull -B quux ../a
684 pulling from ../a
684 pulling from ../a
685 prelistkeys.forbid hook: HG_HOOKNAME=prelistkeys
685 prelistkeys.forbid hook: HG_HOOKNAME=prelistkeys
686 HG_HOOKTYPE=prelistkeys
686 HG_HOOKTYPE=prelistkeys
687 HG_NAMESPACE=bookmarks
687 HG_NAMESPACE=bookmarks
688
688
689 abort: prelistkeys hook exited with status 1
689 abort: prelistkeys hook exited with status 1
690 [40]
690 [40]
691 $ cd ../a
691 $ cd ../a
692 $ rm .hg/hgrc
692 $ rm .hg/hgrc
693
693
694 prechangegroup hook can prevent incoming changes
694 prechangegroup hook can prevent incoming changes
695
695
696 $ cd ../b
696 $ cd ../b
697 $ hg -q tip
697 $ hg -q tip
698 3:07f3376c1e65
698 3:07f3376c1e65
699 $ cat > .hg/hgrc <<EOF
699 $ cat > .hg/hgrc <<EOF
700 > [hooks]
700 > [hooks]
701 > prechangegroup.forbid = sh -c "printenv.py --line prechangegroup.forbid 1"
701 > prechangegroup.forbid = sh -c "printenv.py --line prechangegroup.forbid 1"
702 > EOF
702 > EOF
703 $ hg pull ../a
703 $ hg pull ../a
704 pulling from ../a
704 pulling from ../a
705 searching for changes
705 searching for changes
706 prechangegroup.forbid hook: HG_HOOKNAME=prechangegroup.forbid
706 prechangegroup.forbid hook: HG_HOOKNAME=prechangegroup.forbid
707 HG_HOOKTYPE=prechangegroup
707 HG_HOOKTYPE=prechangegroup
708 HG_SOURCE=pull
708 HG_SOURCE=pull
709 HG_TXNID=TXN:$ID$
709 HG_TXNID=TXN:$ID$
710 HG_TXNNAME=pull
710 HG_TXNNAME=pull
711 file:/*/$TESTTMP/a (glob)
711 file:/*/$TESTTMP/a (glob)
712 HG_URL=file:$TESTTMP/a
712 HG_URL=file:$TESTTMP/a
713
713
714 abort: prechangegroup.forbid hook exited with status 1
714 abort: prechangegroup.forbid hook exited with status 1
715 [40]
715 [40]
716
716
717 pretxnchangegroup hook can see incoming changes, can roll back txn,
717 pretxnchangegroup hook can see incoming changes, can roll back txn,
718 incoming changes no longer there after
718 incoming changes no longer there after
719
719
720 $ cat > .hg/hgrc <<EOF
720 $ cat > .hg/hgrc <<EOF
721 > [hooks]
721 > [hooks]
722 > pretxnchangegroup.forbid0 = hg tip -q
722 > pretxnchangegroup.forbid0 = hg tip -q
723 > pretxnchangegroup.forbid1 = sh -c "printenv.py --line pretxnchangegroup.forbid 1"
723 > pretxnchangegroup.forbid1 = sh -c "printenv.py --line pretxnchangegroup.forbid 1"
724 > EOF
724 > EOF
725 $ hg pull ../a
725 $ hg pull ../a
726 pulling from ../a
726 pulling from ../a
727 searching for changes
727 searching for changes
728 adding changesets
728 adding changesets
729 adding manifests
729 adding manifests
730 adding file changes
730 adding file changes
731 4:539e4b31b6dc
731 4:539e4b31b6dc
732 pretxnchangegroup.forbid hook: HG_HOOKNAME=pretxnchangegroup.forbid1
732 pretxnchangegroup.forbid hook: HG_HOOKNAME=pretxnchangegroup.forbid1
733 HG_HOOKTYPE=pretxnchangegroup
733 HG_HOOKTYPE=pretxnchangegroup
734 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
734 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
735 HG_NODE_LAST=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
735 HG_NODE_LAST=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
736 HG_PENDING=$TESTTMP/b
736 HG_PENDING=$TESTTMP/b
737 HG_SOURCE=pull
737 HG_SOURCE=pull
738 HG_TXNID=TXN:$ID$
738 HG_TXNID=TXN:$ID$
739 HG_TXNNAME=pull
739 HG_TXNNAME=pull
740 file:/*/$TESTTMP/a (glob)
740 file:/*/$TESTTMP/a (glob)
741 HG_URL=file:$TESTTMP/a
741 HG_URL=file:$TESTTMP/a
742
742
743 transaction abort!
743 transaction abort!
744 rollback completed
744 rollback completed
745 abort: pretxnchangegroup.forbid1 hook exited with status 1
745 abort: pretxnchangegroup.forbid1 hook exited with status 1
746 [40]
746 [40]
747 $ hg -q tip
747 $ hg -q tip
748 3:07f3376c1e65
748 3:07f3376c1e65
749
749
750 outgoing hooks can see env vars
750 outgoing hooks can see env vars
751
751
752 $ rm .hg/hgrc
752 $ rm .hg/hgrc
753 $ cat > ../a/.hg/hgrc <<EOF
753 $ cat > ../a/.hg/hgrc <<EOF
754 > [hooks]
754 > [hooks]
755 > preoutgoing = sh -c "printenv.py --line preoutgoing"
755 > preoutgoing = sh -c "printenv.py --line preoutgoing"
756 > outgoing = sh -c "printenv.py --line outgoing"
756 > outgoing = sh -c "printenv.py --line outgoing"
757 > EOF
757 > EOF
758 $ hg pull ../a
758 $ hg pull ../a
759 pulling from ../a
759 pulling from ../a
760 searching for changes
760 searching for changes
761 preoutgoing hook: HG_HOOKNAME=preoutgoing
761 preoutgoing hook: HG_HOOKNAME=preoutgoing
762 HG_HOOKTYPE=preoutgoing
762 HG_HOOKTYPE=preoutgoing
763 HG_SOURCE=pull
763 HG_SOURCE=pull
764
764
765 outgoing hook: HG_HOOKNAME=outgoing
765 outgoing hook: HG_HOOKNAME=outgoing
766 HG_HOOKTYPE=outgoing
766 HG_HOOKTYPE=outgoing
767 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
767 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
768 HG_SOURCE=pull
768 HG_SOURCE=pull
769
769
770 adding changesets
770 adding changesets
771 adding manifests
771 adding manifests
772 adding file changes
772 adding file changes
773 adding remote bookmark quux
773 adding remote bookmark quux
774 added 1 changesets with 1 changes to 1 files
774 added 1 changesets with 1 changes to 1 files
775 new changesets 539e4b31b6dc
775 new changesets 539e4b31b6dc
776 (run 'hg update' to get a working copy)
776 (run 'hg update' to get a working copy)
777 $ hg rollback
777 $ hg rollback
778 repository tip rolled back to revision 3 (undo pull)
778 repository tip rolled back to revision 3 (undo pull)
779
779
780 preoutgoing hook can prevent outgoing changes
780 preoutgoing hook can prevent outgoing changes
781
781
782 $ cat >> ../a/.hg/hgrc <<EOF
782 $ cat >> ../a/.hg/hgrc <<EOF
783 > preoutgoing.forbid = sh -c "printenv.py --line preoutgoing.forbid 1"
783 > preoutgoing.forbid = sh -c "printenv.py --line preoutgoing.forbid 1"
784 > EOF
784 > EOF
785 $ hg pull ../a
785 $ hg pull ../a
786 pulling from ../a
786 pulling from ../a
787 searching for changes
787 searching for changes
788 preoutgoing hook: HG_HOOKNAME=preoutgoing
788 preoutgoing hook: HG_HOOKNAME=preoutgoing
789 HG_HOOKTYPE=preoutgoing
789 HG_HOOKTYPE=preoutgoing
790 HG_SOURCE=pull
790 HG_SOURCE=pull
791
791
792 preoutgoing.forbid hook: HG_HOOKNAME=preoutgoing.forbid
792 preoutgoing.forbid hook: HG_HOOKNAME=preoutgoing.forbid
793 HG_HOOKTYPE=preoutgoing
793 HG_HOOKTYPE=preoutgoing
794 HG_SOURCE=pull
794 HG_SOURCE=pull
795
795
796 abort: preoutgoing.forbid hook exited with status 1
796 abort: preoutgoing.forbid hook exited with status 1
797 [40]
797 [40]
798
798
799 outgoing hooks work for local clones
799 outgoing hooks work for local clones
800
800
801 $ cd ..
801 $ cd ..
802 $ cat > a/.hg/hgrc <<EOF
802 $ cat > a/.hg/hgrc <<EOF
803 > [hooks]
803 > [hooks]
804 > preoutgoing = sh -c "printenv.py --line preoutgoing"
804 > preoutgoing = sh -c "printenv.py --line preoutgoing"
805 > outgoing = sh -c "printenv.py --line outgoing"
805 > outgoing = sh -c "printenv.py --line outgoing"
806 > EOF
806 > EOF
807 $ hg clone a c
807 $ hg clone a c
808 preoutgoing hook: HG_HOOKNAME=preoutgoing
808 preoutgoing hook: HG_HOOKNAME=preoutgoing
809 HG_HOOKTYPE=preoutgoing
809 HG_HOOKTYPE=preoutgoing
810 HG_SOURCE=clone
810 HG_SOURCE=clone
811
811
812 outgoing hook: HG_HOOKNAME=outgoing
812 outgoing hook: HG_HOOKNAME=outgoing
813 HG_HOOKTYPE=outgoing
813 HG_HOOKTYPE=outgoing
814 HG_NODE=0000000000000000000000000000000000000000
814 HG_NODE=0000000000000000000000000000000000000000
815 HG_SOURCE=clone
815 HG_SOURCE=clone
816
816
817 updating to branch default
817 updating to branch default
818 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
818 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
819 $ rm -rf c
819 $ rm -rf c
820
820
821 preoutgoing hook can prevent outgoing changes for local clones
821 preoutgoing hook can prevent outgoing changes for local clones
822
822
823 $ cat >> a/.hg/hgrc <<EOF
823 $ cat >> a/.hg/hgrc <<EOF
824 > preoutgoing.forbid = sh -c "printenv.py --line preoutgoing.forbid 1"
824 > preoutgoing.forbid = sh -c "printenv.py --line preoutgoing.forbid 1"
825 > EOF
825 > EOF
826 $ hg clone a zzz
826 $ hg clone a zzz
827 preoutgoing hook: HG_HOOKNAME=preoutgoing
827 preoutgoing hook: HG_HOOKNAME=preoutgoing
828 HG_HOOKTYPE=preoutgoing
828 HG_HOOKTYPE=preoutgoing
829 HG_SOURCE=clone
829 HG_SOURCE=clone
830
830
831 preoutgoing.forbid hook: HG_HOOKNAME=preoutgoing.forbid
831 preoutgoing.forbid hook: HG_HOOKNAME=preoutgoing.forbid
832 HG_HOOKTYPE=preoutgoing
832 HG_HOOKTYPE=preoutgoing
833 HG_SOURCE=clone
833 HG_SOURCE=clone
834
834
835 abort: preoutgoing.forbid hook exited with status 1
835 abort: preoutgoing.forbid hook exited with status 1
836 [40]
836 [40]
837
837
838 $ cd "$TESTTMP/b"
838 $ cd "$TESTTMP/b"
839
839
840 $ cat > hooktests.py <<EOF
840 $ cat > hooktests.py <<EOF
841 > from mercurial import (
841 > from mercurial import (
842 > error,
842 > error,
843 > pycompat,
843 > pycompat,
844 > )
844 > )
845 >
845 >
846 > uncallable = 0
846 > uncallable = 0
847 >
847 >
848 > def printargs(ui, args):
848 > def printargs(ui, args):
849 > a = list(pycompat.byteskwargs(args).items())
849 > a = list(pycompat.byteskwargs(args).items())
850 > a.sort()
850 > a.sort()
851 > ui.write(b'hook args:\n')
851 > ui.write(b'hook args:\n')
852 > for k, v in a:
852 > for k, v in a:
853 > ui.write(b' %s %s\n' % (k, v))
853 > ui.write(b' %s %s\n' % (k, v))
854 >
854 >
855 > def passhook(ui, repo, **args):
855 > def passhook(ui, repo, **args):
856 > printargs(ui, args)
856 > printargs(ui, args)
857 >
857 >
858 > def failhook(ui, repo, **args):
858 > def failhook(ui, repo, **args):
859 > printargs(ui, args)
859 > printargs(ui, args)
860 > return True
860 > return True
861 >
861 >
862 > class LocalException(Exception):
862 > class LocalException(Exception):
863 > pass
863 > pass
864 >
864 >
865 > def raisehook(**args):
865 > def raisehook(**args):
866 > raise LocalException('exception from hook')
866 > raise LocalException('exception from hook')
867 >
867 >
868 > def aborthook(**args):
868 > def aborthook(**args):
869 > raise error.Abort(b'raise abort from hook')
869 > raise error.Abort(b'raise abort from hook')
870 >
870 >
871 > def brokenhook(**args):
871 > def brokenhook(**args):
872 > return 1 + {}
872 > return 1 + {}
873 >
873 >
874 > def verbosehook(ui, **args):
874 > def verbosehook(ui, **args):
875 > ui.note(b'verbose output from hook\n')
875 > ui.note(b'verbose output from hook\n')
876 >
876 >
877 > def printtags(ui, repo, **args):
877 > def printtags(ui, repo, **args):
878 > ui.write(b'[%s]\n' % b', '.join(sorted(repo.tags())))
878 > ui.write(b'[%s]\n' % b', '.join(sorted(repo.tags())))
879 >
879 >
880 > class container(object):
880 > class container(object):
881 > unreachable = 1
881 > unreachable = 1
882 > EOF
882 > EOF
883
883
884 $ cat > syntaxerror.py << NO_CHECK_EOF
884 $ cat > syntaxerror.py << NO_CHECK_EOF
885 > (foo
885 > (foo
886 > NO_CHECK_EOF
886 > NO_CHECK_EOF
887
887
888 test python hooks
888 test python hooks
889
889
890 #if windows
890 #if windows
891 $ PYTHONPATH="$TESTTMP/b;$PYTHONPATH"
891 $ PYTHONPATH="$TESTTMP/b;$PYTHONPATH"
892 #else
892 #else
893 $ PYTHONPATH="$TESTTMP/b:$PYTHONPATH"
893 $ PYTHONPATH="$TESTTMP/b:$PYTHONPATH"
894 #endif
894 #endif
895 $ export PYTHONPATH
895 $ export PYTHONPATH
896
896
897 $ echo '[hooks]' > ../a/.hg/hgrc
897 $ echo '[hooks]' > ../a/.hg/hgrc
898 $ echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
898 $ echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
899 $ hg pull ../a 2>&1 | grep 'raised an exception'
899 $ hg pull ../a 2>&1 | grep 'raised an exception'
900 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
900 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
901
901
902 $ echo '[hooks]' > ../a/.hg/hgrc
902 $ echo '[hooks]' > ../a/.hg/hgrc
903 $ echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
903 $ echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
904 $ hg pull ../a 2>&1 | grep 'raised an exception'
904 $ hg pull ../a 2>&1 | grep 'raised an exception'
905 error: preoutgoing.raise hook raised an exception: exception from hook
905 error: preoutgoing.raise hook raised an exception: exception from hook
906
906
907 $ echo '[hooks]' > ../a/.hg/hgrc
907 $ echo '[hooks]' > ../a/.hg/hgrc
908 $ echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
908 $ echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
909 $ hg pull ../a
909 $ hg pull ../a
910 pulling from ../a
910 pulling from ../a
911 searching for changes
911 searching for changes
912 error: preoutgoing.abort hook failed: raise abort from hook
912 error: preoutgoing.abort hook failed: raise abort from hook
913 abort: raise abort from hook
913 abort: raise abort from hook
914 [255]
914 [255]
915
915
916 $ echo '[hooks]' > ../a/.hg/hgrc
916 $ echo '[hooks]' > ../a/.hg/hgrc
917 $ echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
917 $ echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
918 $ hg pull ../a
918 $ hg pull ../a
919 pulling from ../a
919 pulling from ../a
920 searching for changes
920 searching for changes
921 hook args:
921 hook args:
922 hooktype preoutgoing
922 hooktype preoutgoing
923 source pull
923 source pull
924 abort: preoutgoing.fail hook failed
924 abort: preoutgoing.fail hook failed
925 [40]
925 [40]
926
926
927 $ echo '[hooks]' > ../a/.hg/hgrc
927 $ echo '[hooks]' > ../a/.hg/hgrc
928 $ echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
928 $ echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
929 $ hg pull ../a
929 $ hg pull ../a
930 pulling from ../a
930 pulling from ../a
931 searching for changes
931 searching for changes
932 abort: preoutgoing.uncallable hook is invalid: "hooktests.uncallable" is not callable
932 abort: preoutgoing.uncallable hook is invalid: "hooktests.uncallable" is not callable
933 [255]
933 [255]
934
934
935 $ echo '[hooks]' > ../a/.hg/hgrc
935 $ echo '[hooks]' > ../a/.hg/hgrc
936 $ echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
936 $ echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
937 $ hg pull ../a
937 $ hg pull ../a
938 pulling from ../a
938 pulling from ../a
939 searching for changes
939 searching for changes
940 abort: preoutgoing.nohook hook is invalid: "hooktests.nohook" is not defined
940 abort: preoutgoing.nohook hook is invalid: "hooktests.nohook" is not defined
941 [255]
941 [255]
942
942
943 $ echo '[hooks]' > ../a/.hg/hgrc
943 $ echo '[hooks]' > ../a/.hg/hgrc
944 $ echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
944 $ echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
945 $ hg pull ../a
945 $ hg pull ../a
946 pulling from ../a
946 pulling from ../a
947 searching for changes
947 searching for changes
948 abort: preoutgoing.nomodule hook is invalid: "nomodule" not in a module
948 abort: preoutgoing.nomodule hook is invalid: "nomodule" not in a module
949 [255]
949 [255]
950
950
951 $ echo '[hooks]' > ../a/.hg/hgrc
951 $ echo '[hooks]' > ../a/.hg/hgrc
952 $ echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
952 $ echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
953 $ hg pull ../a
953 $ hg pull ../a
954 pulling from ../a
954 pulling from ../a
955 searching for changes
955 searching for changes
956 abort: preoutgoing.badmodule hook is invalid: import of "nomodule" failed
956 abort: preoutgoing.badmodule hook is invalid: import of "nomodule" failed
957 (run with --traceback for stack trace)
957 (run with --traceback for stack trace)
958 [255]
958 [255]
959
959
960 $ echo '[hooks]' > ../a/.hg/hgrc
960 $ echo '[hooks]' > ../a/.hg/hgrc
961 $ echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
961 $ echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
962 $ hg pull ../a
962 $ hg pull ../a
963 pulling from ../a
963 pulling from ../a
964 searching for changes
964 searching for changes
965 abort: preoutgoing.unreachable hook is invalid: import of "hooktests.container" failed
965 abort: preoutgoing.unreachable hook is invalid: import of "hooktests.container" failed
966 (run with --traceback for stack trace)
966 (run with --traceback for stack trace)
967 [255]
967 [255]
968
968
969 $ echo '[hooks]' > ../a/.hg/hgrc
969 $ echo '[hooks]' > ../a/.hg/hgrc
970 $ echo 'preoutgoing.syntaxerror = python:syntaxerror.syntaxerror' >> ../a/.hg/hgrc
970 $ echo 'preoutgoing.syntaxerror = python:syntaxerror.syntaxerror' >> ../a/.hg/hgrc
971 $ hg pull ../a
971 $ hg pull ../a
972 pulling from ../a
972 pulling from ../a
973 searching for changes
973 searching for changes
974 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
974 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
975 (run with --traceback for stack trace)
975 (run with --traceback for stack trace)
976 [255]
976 [255]
977
977
978 $ hg pull ../a --traceback 2>&1 | egrep 'pulling|searching|^exception|Traceback|SyntaxError|ImportError|ModuleNotFoundError|HookLoadError|abort'
978 $ hg pull ../a --traceback 2>&1 | egrep 'pulling|searching|^exception|Traceback|SyntaxError|ImportError|ModuleNotFoundError|HookLoadError|abort'
979 pulling from ../a
979 pulling from ../a
980 searching for changes
980 searching for changes
981 exception from first failed import attempt:
981 exception from first failed import attempt:
982 Traceback (most recent call last):
982 Traceback (most recent call last):
983 SyntaxError: * (glob)
983 SyntaxError: * (glob)
984 exception from second failed import attempt:
984 exception from second failed import attempt:
985 Traceback (most recent call last):
985 Traceback (most recent call last):
986 SyntaxError: * (glob)
986 SyntaxError: * (glob)
987 Traceback (most recent call last):
987 Traceback (most recent call last):
988 ModuleNotFoundError: No module named 'hgext_syntaxerror'
988 ModuleNotFoundError: No module named 'hgext_syntaxerror'
989 Traceback (most recent call last):
989 Traceback (most recent call last):
990 SyntaxError: * (glob)
990 SyntaxError: * (glob)
991 Traceback (most recent call last):
991 Traceback (most recent call last):
992 ModuleNotFoundError: No module named 'hgext_syntaxerror'
992 ModuleNotFoundError: No module named 'hgext_syntaxerror'
993 Traceback (most recent call last):
993 Traceback (most recent call last):
994 raise error.HookLoadError( (py38 !)
994 raise error.HookLoadError( (py38 !)
995 mercurial.error.HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
995 mercurial.error.HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
996 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
996 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
997
997
998 $ echo '[hooks]' > ../a/.hg/hgrc
998 $ echo '[hooks]' > ../a/.hg/hgrc
999 $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
999 $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
1000 $ hg pull ../a
1000 $ hg pull ../a
1001 pulling from ../a
1001 pulling from ../a
1002 searching for changes
1002 searching for changes
1003 hook args:
1003 hook args:
1004 hooktype preoutgoing
1004 hooktype preoutgoing
1005 source pull
1005 source pull
1006 adding changesets
1006 adding changesets
1007 adding manifests
1007 adding manifests
1008 adding file changes
1008 adding file changes
1009 adding remote bookmark quux
1009 adding remote bookmark quux
1010 added 1 changesets with 1 changes to 1 files
1010 added 1 changesets with 1 changes to 1 files
1011 new changesets 539e4b31b6dc
1011 new changesets 539e4b31b6dc
1012 (run 'hg update' to get a working copy)
1012 (run 'hg update' to get a working copy)
1013
1013
1014 post- python hooks that fail to *run* don't cause an abort
1014 post- python hooks that fail to *run* don't cause an abort
1015 $ rm ../a/.hg/hgrc
1015 $ rm ../a/.hg/hgrc
1016 $ echo '[hooks]' > .hg/hgrc
1016 $ echo '[hooks]' > .hg/hgrc
1017 $ echo 'post-pull.broken = python:hooktests.brokenhook' >> .hg/hgrc
1017 $ echo 'post-pull.broken = python:hooktests.brokenhook' >> .hg/hgrc
1018 $ hg pull ../a
1018 $ hg pull ../a
1019 pulling from ../a
1019 pulling from ../a
1020 searching for changes
1020 searching for changes
1021 no changes found
1021 no changes found
1022 error: post-pull.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
1022 error: post-pull.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
1023 (run with --traceback for stack trace)
1023 (run with --traceback for stack trace)
1024
1024
1025 but post- python hooks that fail to *load* do
1025 but post- python hooks that fail to *load* do
1026 $ echo '[hooks]' > .hg/hgrc
1026 $ echo '[hooks]' > .hg/hgrc
1027 $ echo 'post-pull.nomodule = python:nomodule' >> .hg/hgrc
1027 $ echo 'post-pull.nomodule = python:nomodule' >> .hg/hgrc
1028 $ hg pull ../a
1028 $ hg pull ../a
1029 pulling from ../a
1029 pulling from ../a
1030 searching for changes
1030 searching for changes
1031 no changes found
1031 no changes found
1032 abort: post-pull.nomodule hook is invalid: "nomodule" not in a module
1032 abort: post-pull.nomodule hook is invalid: "nomodule" not in a module
1033 [255]
1033 [255]
1034
1034
1035 $ echo '[hooks]' > .hg/hgrc
1035 $ echo '[hooks]' > .hg/hgrc
1036 $ echo 'post-pull.badmodule = python:nomodule.nowhere' >> .hg/hgrc
1036 $ echo 'post-pull.badmodule = python:nomodule.nowhere' >> .hg/hgrc
1037 $ hg pull ../a
1037 $ hg pull ../a
1038 pulling from ../a
1038 pulling from ../a
1039 searching for changes
1039 searching for changes
1040 no changes found
1040 no changes found
1041 abort: post-pull.badmodule hook is invalid: import of "nomodule" failed
1041 abort: post-pull.badmodule hook is invalid: import of "nomodule" failed
1042 (run with --traceback for stack trace)
1042 (run with --traceback for stack trace)
1043 [255]
1043 [255]
1044
1044
1045 $ echo '[hooks]' > .hg/hgrc
1045 $ echo '[hooks]' > .hg/hgrc
1046 $ echo 'post-pull.nohook = python:hooktests.nohook' >> .hg/hgrc
1046 $ echo 'post-pull.nohook = python:hooktests.nohook' >> .hg/hgrc
1047 $ hg pull ../a
1047 $ hg pull ../a
1048 pulling from ../a
1048 pulling from ../a
1049 searching for changes
1049 searching for changes
1050 no changes found
1050 no changes found
1051 abort: post-pull.nohook hook is invalid: "hooktests.nohook" is not defined
1051 abort: post-pull.nohook hook is invalid: "hooktests.nohook" is not defined
1052 [255]
1052 [255]
1053
1053
1054 make sure --traceback works
1054 make sure --traceback works
1055
1055
1056 $ echo '[hooks]' > .hg/hgrc
1056 $ echo '[hooks]' > .hg/hgrc
1057 $ echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
1057 $ echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
1058
1058
1059 $ echo aa > a
1059 $ echo aa > a
1060 $ hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
1060 $ hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
1061 Traceback (most recent call last):
1061 Traceback (most recent call last):
1062
1062
1063 $ cd ..
1063 $ cd ..
1064 $ hg init c
1064 $ hg init c
1065 $ cd c
1065 $ cd c
1066
1066
1067 $ cat > hookext.py <<EOF
1067 $ cat > hookext.py <<EOF
1068 > def autohook(ui, **args):
1068 > def autohook(ui, **args):
1069 > ui.write(b'Automatically installed hook\n')
1069 > ui.write(b'Automatically installed hook\n')
1070 >
1070 >
1071 > def reposetup(ui, repo):
1071 > def reposetup(ui, repo):
1072 > repo.ui.setconfig(b"hooks", b"commit.auto", autohook)
1072 > repo.ui.setconfig(b"hooks", b"commit.auto", autohook)
1073 > EOF
1073 > EOF
1074 $ echo '[extensions]' >> .hg/hgrc
1074 $ echo '[extensions]' >> .hg/hgrc
1075 $ echo 'hookext = hookext.py' >> .hg/hgrc
1075 $ echo 'hookext = hookext.py' >> .hg/hgrc
1076
1076
1077 $ touch foo
1077 $ touch foo
1078 $ hg add foo
1078 $ hg add foo
1079 $ hg ci -d '0 0' -m 'add foo'
1079 $ hg ci -d '0 0' -m 'add foo'
1080 Automatically installed hook
1080 Automatically installed hook
1081 $ echo >> foo
1081 $ echo >> foo
1082 $ hg ci --debug -d '0 0' -m 'change foo'
1082 $ hg ci --debug -d '0 0' -m 'change foo'
1083 committing files:
1083 committing files:
1084 foo
1084 foo
1085 committing manifest
1085 committing manifest
1086 committing changelog
1086 committing changelog
1087 updating the branch cache
1087 updating the branch cache
1088 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
1088 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
1089 calling hook commit.auto: hgext_hookext.autohook
1089 calling hook commit.auto: hgext_hookext.autohook
1090 Automatically installed hook
1090 Automatically installed hook
1091
1091
1092 $ hg showconfig hooks
1092 $ hg showconfig hooks
1093 hooks.commit.auto=<function autohook at *> (glob)
1093 hooks.commit.auto=<function autohook at *> (glob)
1094
1094
1095 test python hook configured with python:[file]:[hook] syntax
1095 test python hook configured with python:[file]:[hook] syntax
1096
1096
1097 $ cd ..
1097 $ cd ..
1098 $ mkdir d
1098 $ mkdir d
1099 $ cd d
1099 $ cd d
1100 $ hg init repo
1100 $ hg init repo
1101 $ mkdir hooks
1101 $ mkdir hooks
1102
1102
1103 $ cd hooks
1103 $ cd hooks
1104 $ cat > testhooks.py <<EOF
1104 $ cat > testhooks.py <<EOF
1105 > def testhook(ui, **args):
1105 > def testhook(ui, **args):
1106 > ui.write(b'hook works\n')
1106 > ui.write(b'hook works\n')
1107 > EOF
1107 > EOF
1108 $ echo '[hooks]' > ../repo/.hg/hgrc
1108 $ echo '[hooks]' > ../repo/.hg/hgrc
1109 $ echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
1109 $ echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
1110
1110
1111 $ cd ../repo
1111 $ cd ../repo
1112 $ hg commit -d '0 0'
1112 $ hg commit -d '0 0'
1113 hook works
1113 hook works
1114 nothing changed
1114 nothing changed
1115 [1]
1115 [1]
1116
1116
1117 $ echo '[hooks]' > .hg/hgrc
1117 $ echo '[hooks]' > .hg/hgrc
1118 $ echo "update.ne = python:`pwd`/nonexistent.py:testhook" >> .hg/hgrc
1118 $ echo "update.ne = python:`pwd`/nonexistent.py:testhook" >> .hg/hgrc
1119 $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc
1119 $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc
1120
1120
1121 $ hg up null
1121 $ hg up null
1122 loading update.ne hook failed:
1122 loading update.ne hook failed:
1123 abort: $ENOENT$: '$TESTTMP/d/repo/nonexistent.py'
1123 abort: $ENOENT$: '$TESTTMP/d/repo/nonexistent.py'
1124 [255]
1124 [255]
1125
1125
1126 $ hg id
1126 $ hg id
1127 loading pre-identify.npmd hook failed:
1127 loading pre-identify.npmd hook failed:
1128 abort: No module named 'repo'
1128 abort: No module named 'repo'
1129 [255]
1129 [255]
1130
1130
1131 $ cd ../../b
1131 $ cd ../../b
1132
1132
1133 make sure --traceback works on hook import failure
1133 make sure --traceback works on hook import failure
1134
1134
1135 $ cat > importfail.py <<EOF
1135 $ cat > importfail.py <<EOF
1136 > import somebogusmodule
1136 > import somebogusmodule
1137 > # dereference something in the module to force demandimport to load it
1137 > # dereference something in the module to force demandimport to load it
1138 > somebogusmodule.whatever
1138 > somebogusmodule.whatever
1139 > EOF
1139 > EOF
1140
1140
1141 $ echo '[hooks]' > .hg/hgrc
1141 $ echo '[hooks]' > .hg/hgrc
1142 $ echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
1142 $ echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
1143
1143
1144 $ echo a >> a
1144 $ echo a >> a
1145 $ hg --traceback commit -ma 2>&1 | egrep '^exception|ImportError|ModuleNotFoundError|Traceback|HookLoadError|abort'
1145 $ hg --traceback commit -ma 2>&1 | egrep '^exception|ImportError|ModuleNotFoundError|Traceback|HookLoadError|abort'
1146 exception from first failed import attempt:
1146 exception from first failed import attempt:
1147 Traceback (most recent call last):
1147 Traceback (most recent call last):
1148 ModuleNotFoundError: No module named 'somebogusmodule'
1148 ModuleNotFoundError: No module named 'somebogusmodule'
1149 exception from second failed import attempt:
1149 exception from second failed import attempt:
1150 Traceback (most recent call last):
1150 Traceback (most recent call last):
1151 ModuleNotFoundError: No module named 'somebogusmodule'
1151 ModuleNotFoundError: No module named 'somebogusmodule'
1152 Traceback (most recent call last):
1152 Traceback (most recent call last):
1153 ModuleNotFoundError: No module named 'hgext_importfail'
1153 ModuleNotFoundError: No module named 'hgext_importfail'
1154 Traceback (most recent call last):
1154 Traceback (most recent call last):
1155 ModuleNotFoundError: No module named 'somebogusmodule'
1155 ModuleNotFoundError: No module named 'somebogusmodule'
1156 Traceback (most recent call last):
1156 Traceback (most recent call last):
1157 ModuleNotFoundError: No module named 'hgext_importfail'
1157 ModuleNotFoundError: No module named 'hgext_importfail'
1158 Traceback (most recent call last):
1158 Traceback (most recent call last):
1159 raise error.HookLoadError( (py38 !)
1159 raise error.HookLoadError( (py38 !)
1160 mercurial.error.HookLoadError: precommit.importfail hook is invalid: import of "importfail" failed
1160 mercurial.error.HookLoadError: precommit.importfail hook is invalid: import of "importfail" failed
1161 abort: precommit.importfail hook is invalid: import of "importfail" failed
1161 abort: precommit.importfail hook is invalid: import of "importfail" failed
1162
1162
1163 Issue1827: Hooks Update & Commit not completely post operation
1163 Issue1827: Hooks Update & Commit not completely post operation
1164
1164
1165 commit and update hooks should run after command completion. The largefiles
1165 commit and update hooks should run after command completion. The largefiles
1166 use demonstrates a recursive wlock, showing the hook doesn't run until the
1166 use demonstrates a recursive wlock, showing the hook doesn't run until the
1167 final release (and dirstate flush).
1167 final release (and dirstate flush).
1168
1168
1169 $ echo '[hooks]' > .hg/hgrc
1169 $ echo '[hooks]' > .hg/hgrc
1170 $ echo 'commit = hg id' >> .hg/hgrc
1170 $ echo 'commit = hg id' >> .hg/hgrc
1171 $ echo 'update = hg id' >> .hg/hgrc
1171 $ echo 'update = hg id' >> .hg/hgrc
1172 $ echo bb > a
1172 $ echo bb > a
1173 $ hg ci -ma
1173 $ hg ci -ma
1174 223eafe2750c tip
1174 223eafe2750c tip
1175 $ hg up 0 --config extensions.largefiles=
1175 $ hg up 0 --config extensions.largefiles=
1176 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
1176 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
1177 cb9a9f314b8b
1177 cb9a9f314b8b
1178 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1178 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1179
1179
1180 make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
1180 make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
1181 that is passed to pre/post hooks
1181 that is passed to pre/post hooks
1182
1182
1183 $ echo '[hooks]' > .hg/hgrc
1183 $ echo '[hooks]' > .hg/hgrc
1184 $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
1184 $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
1185 $ hg id
1185 $ hg id
1186 cb9a9f314b8b
1186 cb9a9f314b8b
1187 $ hg id --verbose
1187 $ hg id --verbose
1188 calling hook pre-identify: hooktests.verbosehook
1188 calling hook pre-identify: hooktests.verbosehook
1189 verbose output from hook
1189 verbose output from hook
1190 cb9a9f314b8b
1190 cb9a9f314b8b
1191
1191
1192 Ensure hooks can be prioritized
1192 Ensure hooks can be prioritized
1193
1193
1194 $ echo '[hooks]' > .hg/hgrc
1194 $ echo '[hooks]' > .hg/hgrc
1195 $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
1195 $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
1196 $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
1196 $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
1197 $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
1197 $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
1198 $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
1198 $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
1199 $ hg id --verbose
1199 $ hg id --verbose
1200 calling hook pre-identify.b: hooktests.verbosehook
1200 calling hook pre-identify.b: hooktests.verbosehook
1201 verbose output from hook
1201 verbose output from hook
1202 calling hook pre-identify.a: hooktests.verbosehook
1202 calling hook pre-identify.a: hooktests.verbosehook
1203 verbose output from hook
1203 verbose output from hook
1204 calling hook pre-identify.c: hooktests.verbosehook
1204 calling hook pre-identify.c: hooktests.verbosehook
1205 verbose output from hook
1205 verbose output from hook
1206 cb9a9f314b8b
1206 cb9a9f314b8b
1207
1207
1208 new tags must be visible in pretxncommit (issue3210)
1208 new tags must be visible in pretxncommit (issue3210)
1209
1209
1210 $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc
1210 $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc
1211 $ hg tag -f foo
1211 $ hg tag -f foo
1212 [a, foo, tip]
1212 [a, foo, tip]
1213
1213
1214 post-init hooks must not crash (issue4983)
1214 post-init hooks must not crash (issue4983)
1215 This also creates the `to` repo for the next test block.
1215 This also creates the `to` repo for the next test block.
1216
1216
1217 $ cd ..
1217 $ cd ..
1218 $ cat << EOF >> hgrc-with-post-init-hook
1218 $ cat << EOF >> hgrc-with-post-init-hook
1219 > [hooks]
1219 > [hooks]
1220 > post-init = sh -c "printenv.py --line post-init"
1220 > post-init = sh -c "printenv.py --line post-init"
1221 > EOF
1221 > EOF
1222 $ HGRCPATH=hgrc-with-post-init-hook hg init to
1222 $ HGRCPATH=hgrc-with-post-init-hook hg init to
1223 post-init hook: HG_ARGS=init to
1223 post-init hook: HG_ARGS=init to
1224 HG_HOOKNAME=post-init
1224 HG_HOOKNAME=post-init
1225 HG_HOOKTYPE=post-init
1225 HG_HOOKTYPE=post-init
1226 HG_OPTS={'insecure': None, 'remotecmd': '', 'ssh': ''}
1226 HG_OPTS={'insecure': None, 'remotecmd': '', 'ssh': ''}
1227 HG_PATS=['to']
1227 HG_PATS=['to']
1228 HG_RESULT=0
1228 HG_RESULT=0
1229
1229
1230
1230
1231 new commits must be visible in pretxnchangegroup (issue3428)
1231 new commits must be visible in pretxnchangegroup (issue3428)
1232
1232
1233 $ echo '[hooks]' >> to/.hg/hgrc
1233 $ echo '[hooks]' >> to/.hg/hgrc
1234 $ echo 'prechangegroup = hg --traceback tip' >> to/.hg/hgrc
1234 $ echo 'prechangegroup = hg --traceback tip' >> to/.hg/hgrc
1235 $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
1235 $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
1236 $ echo a >> to/a
1236 $ echo a >> to/a
1237 $ hg --cwd to ci -Ama
1237 $ hg --cwd to ci -Ama
1238 adding a
1238 adding a
1239 $ hg clone to from
1239 $ hg clone to from
1240 updating to branch default
1240 updating to branch default
1241 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1241 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1242 $ echo aa >> from/a
1242 $ echo aa >> from/a
1243 $ hg --cwd from ci -mb
1243 $ hg --cwd from ci -mb
1244 $ hg --cwd from push
1244 $ hg --cwd from push
1245 pushing to $TESTTMP/to
1245 pushing to $TESTTMP/to
1246 searching for changes
1246 searching for changes
1247 changeset: 0:cb9a9f314b8b
1247 changeset: 0:cb9a9f314b8b
1248 tag: tip
1248 tag: tip
1249 user: test
1249 user: test
1250 date: Thu Jan 01 00:00:00 1970 +0000
1250 date: Thu Jan 01 00:00:00 1970 +0000
1251 summary: a
1251 summary: a
1252
1252
1253 adding changesets
1253 adding changesets
1254 adding manifests
1254 adding manifests
1255 adding file changes
1255 adding file changes
1256 changeset: 1:9836a07b9b9d
1256 changeset: 1:9836a07b9b9d
1257 tag: tip
1257 tag: tip
1258 user: test
1258 user: test
1259 date: Thu Jan 01 00:00:00 1970 +0000
1259 date: Thu Jan 01 00:00:00 1970 +0000
1260 summary: b
1260 summary: b
1261
1261
1262 added 1 changesets with 1 changes to 1 files
1262 added 1 changesets with 1 changes to 1 files
1263
1263
1264 pretxnclose hook failure should abort the transaction
1264 pretxnclose hook failure should abort the transaction
1265
1265
1266 $ hg init txnfailure
1266 $ hg init txnfailure
1267 $ cd txnfailure
1267 $ cd txnfailure
1268 $ touch a && hg commit -Aqm a
1268 $ touch a && hg commit -Aqm a
1269 $ cat >> .hg/hgrc <<EOF
1269 $ cat >> .hg/hgrc <<EOF
1270 > [hooks]
1270 > [hooks]
1271 > pretxnclose.error = exit 1
1271 > pretxnclose.error = exit 1
1272 > EOF
1272 > EOF
1273 $ hg strip -r 0 --config extensions.strip=
1273 $ hg strip -r 0 --config extensions.strip=
1274 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1274 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1275 saved backup bundle to * (glob)
1275 saved backup bundle to * (glob)
1276 transaction abort!
1276 transaction abort!
1277 rollback completed
1277 rollback completed
1278 strip failed, backup bundle stored in * (glob)
1278 strip failed, backup bundle stored in * (glob)
1279 abort: pretxnclose.error hook exited with status 1
1279 abort: pretxnclose.error hook exited with status 1
1280 [40]
1280 [40]
1281 $ hg recover
1281 $ hg recover
1282 no interrupted transaction available
1282 no interrupted transaction available
1283 [1]
1283 [1]
1284 $ cd ..
1284 $ cd ..
1285
1285
1286 check whether HG_PENDING makes pending changes only in related
1286 check whether HG_PENDING makes pending changes only in related
1287 repositories visible to an external hook.
1287 repositories visible to an external hook.
1288
1288
1289 (emulate a transaction running concurrently by copied
1289 (emulate a transaction running concurrently by copied
1290 .hg/store/00changelog.i.a in subsequent test)
1290 .hg/store/00changelog.i.a in subsequent test)
1291
1291
1292 $ cat > $TESTTMP/savepending.sh <<EOF
1292 $ cat > $TESTTMP/savepending.sh <<EOF
1293 > cp .hg/store/00changelog.i.a .hg/store/00changelog.i.a.saved
1293 > cp .hg/store/00changelog.i.a .hg/store/00changelog.i.a.saved
1294 > exit 1 # to avoid adding new revision for subsequent tests
1294 > exit 1 # to avoid adding new revision for subsequent tests
1295 > EOF
1295 > EOF
1296 $ cd a
1296 $ cd a
1297 $ hg tip -q
1297 $ hg tip -q
1298 4:539e4b31b6dc
1298 4:539e4b31b6dc
1299 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" commit -m "invisible"
1299 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" commit -m "invisible"
1300 transaction abort!
1300 transaction abort!
1301 rollback completed
1301 rollback completed
1302 abort: pretxnclose hook exited with status 1
1302 abort: pretxnclose hook exited with status 1
1303 [40]
1303 [40]
1304 $ cp .hg/store/00changelog.i.a.saved .hg/store/00changelog.i.a
1304 $ cp .hg/store/00changelog.i.a.saved .hg/store/00changelog.i.a
1305
1305
1306 (check (in)visibility of new changeset while transaction running in
1306 (check (in)visibility of new changeset while transaction running in
1307 repo)
1307 repo)
1308
1308
1309 $ cat > $TESTTMP/checkpending.sh <<EOF
1309 $ cat > $TESTTMP/checkpending.sh <<EOF
1310 > echo '@a'
1310 > echo '@a'
1311 > hg -R "$TESTTMP/a" tip -q
1311 > hg -R "$TESTTMP/a" tip -q
1312 > echo '@a/nested'
1312 > echo '@a/nested'
1313 > hg -R "$TESTTMP/a/nested" tip -q
1313 > hg -R "$TESTTMP/a/nested" tip -q
1314 > exit 1 # to avoid adding new revision for subsequent tests
1314 > exit 1 # to avoid adding new revision for subsequent tests
1315 > EOF
1315 > EOF
1316 $ hg init nested
1316 $ hg init nested
1317 $ cd nested
1317 $ cd nested
1318 $ echo a > a
1318 $ echo a > a
1319 $ hg add a
1319 $ hg add a
1320 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" commit -m '#0'
1320 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" commit -m '#0'
1321 @a
1321 @a
1322 4:539e4b31b6dc
1322 4:539e4b31b6dc
1323 @a/nested
1323 @a/nested
1324 0:bf5e395ced2c
1324 0:bf5e395ced2c
1325 transaction abort!
1325 transaction abort!
1326 rollback completed
1326 rollback completed
1327 abort: pretxnclose hook exited with status 1
1327 abort: pretxnclose hook exited with status 1
1328 [40]
1328 [40]
1329
1329
1330 Hook from untrusted hgrc are reported as failure
1330 Hook from untrusted hgrc are reported as failure
1331 ================================================
1331 ================================================
1332
1332
1333 $ cat << EOF > $TESTTMP/untrusted.py
1333 $ cat << EOF > $TESTTMP/untrusted.py
1334 > from mercurial import scmutil, util
1334 > from mercurial import scmutil, util
1335 > def uisetup(ui):
1335 > def uisetup(ui):
1336 > class untrustedui(ui.__class__):
1336 > class untrustedui(ui.__class__):
1337 > def _trusted(self, fp, f):
1337 > def _trusted(self, fp, f):
1338 > if util.normpath(fp.name).endswith(b'untrusted/.hg/hgrc'):
1338 > if util.normpath(fp.name).endswith(b'untrusted/.hg/hgrc'):
1339 > return False
1339 > return False
1340 > return super(untrustedui, self)._trusted(fp, f)
1340 > return super(untrustedui, self)._trusted(fp, f)
1341 > ui.__class__ = untrustedui
1341 > ui.__class__ = untrustedui
1342 > EOF
1342 > EOF
1343 $ cat << EOF >> $HGRCPATH
1343 $ cat << EOF >> $HGRCPATH
1344 > [extensions]
1344 > [extensions]
1345 > untrusted=$TESTTMP/untrusted.py
1345 > untrusted=$TESTTMP/untrusted.py
1346 > EOF
1346 > EOF
1347 $ hg init untrusted
1347 $ hg init untrusted
1348 $ cd untrusted
1348 $ cd untrusted
1349
1349
1350 Non-blocking hook
1350 Non-blocking hook
1351 -----------------
1351 -----------------
1352
1352
1353 $ cat << EOF >> .hg/hgrc
1353 $ cat << EOF >> .hg/hgrc
1354 > [hooks]
1354 > [hooks]
1355 > txnclose.testing=echo txnclose hook called
1355 > txnclose.testing=echo txnclose hook called
1356 > EOF
1356 > EOF
1357 $ touch a && hg commit -Aqm a
1357 $ touch a && hg commit -Aqm a
1358 warning: untrusted hook txnclose.testing not executed
1358 warning: untrusted hook txnclose.testing not executed
1359 $ hg log
1359 $ hg log
1360 changeset: 0:3903775176ed
1360 changeset: 0:3903775176ed
1361 tag: tip
1361 tag: tip
1362 user: test
1362 user: test
1363 date: Thu Jan 01 00:00:00 1970 +0000
1363 date: Thu Jan 01 00:00:00 1970 +0000
1364 summary: a
1364 summary: a
1365
1365
1366
1366
1367 Non-blocking hook
1367 Non-blocking hook
1368 -----------------
1368 -----------------
1369
1369
1370 $ cat << EOF >> .hg/hgrc
1370 $ cat << EOF >> .hg/hgrc
1371 > [hooks]
1371 > [hooks]
1372 > pretxnclose.testing=echo pre-txnclose hook called
1372 > pretxnclose.testing=echo pre-txnclose hook called
1373 > EOF
1373 > EOF
1374 $ touch b && hg commit -Aqm a
1374 $ touch b && hg commit -Aqm a
1375 transaction abort!
1375 transaction abort!
1376 rollback completed
1376 rollback completed
1377 abort: untrusted hook pretxnclose.testing not executed
1377 abort: untrusted hook pretxnclose.testing not executed
1378 (see 'hg help config.trusted')
1378 (see 'hg help config.trusted')
1379 [40]
1379 [40]
1380 $ hg log
1380 $ hg log
1381 changeset: 0:3903775176ed
1381 changeset: 0:3903775176ed
1382 tag: tip
1382 tag: tip
1383 user: test
1383 user: test
1384 date: Thu Jan 01 00:00:00 1970 +0000
1384 date: Thu Jan 01 00:00:00 1970 +0000
1385 summary: a
1385 summary: a
1386
1386
1387
1387
1388 unsetup the test
1388 unsetup the test
1389 ----------------
1389 ----------------
1390
1390
1391 # touch the file to unconfuse chg with a diffrent mtime
1391 # touch the file to unconfuse chg with a diffrent mtime
1392 $ sleep 1
1392 $ sleep 1
1393 $ touch $TESTTMP/untrusted.py
1393 $ touch $TESTTMP/untrusted.py
1394 $ cat << EOF >> $HGRCPATH
1394 $ cat << EOF >> $HGRCPATH
1395 > [extensions]
1395 > [extensions]
1396 > untrusted=!
1396 > untrusted=!
1397 > EOF
1397 > EOF
1398
1398
1399 HGPLAIN setting in hooks
1399 HGPLAIN setting in hooks
1400 ========================
1400 ========================
1401
1401
1402 $ cat << EOF >> .hg/hgrc
1402 $ cat << EOF >> .hg/hgrc
1403 > [hooks]
1403 > [hooks]
1404 > pre-version.testing-default=sh -c "echo '### default ###' plain: \${HGPLAIN:-'<unset>'}"
1404 > pre-version.testing-default=sh -c "echo '### default ###' plain: \${HGPLAIN:-'<unset>'}"
1405 > pre-version.testing-yes=sh -c "echo '### yes #######' plain: \${HGPLAIN:-'<unset>'}"
1405 > pre-version.testing-yes=sh -c "echo '### yes #######' plain: \${HGPLAIN:-'<unset>'}"
1406 > pre-version.testing-yes:run-with-plain=yes
1406 > pre-version.testing-yes:run-with-plain=yes
1407 > pre-version.testing-no=sh -c "echo '### no ########' plain: \${HGPLAIN:-'<unset>'}"
1407 > pre-version.testing-no=sh -c "echo '### no ########' plain: \${HGPLAIN:-'<unset>'}"
1408 > pre-version.testing-no:run-with-plain=no
1408 > pre-version.testing-no:run-with-plain=no
1409 > pre-version.testing-auto=sh -c "echo '### auto ######' plain: \${HGPLAIN:-'<unset>'}"
1409 > pre-version.testing-auto=sh -c "echo '### auto ######' plain: \${HGPLAIN:-'<unset>'}"
1410 > pre-version.testing-auto:run-with-plain=auto
1410 > pre-version.testing-auto:run-with-plain=auto
1411 > EOF
1411 > EOF
1412
1412
1413 $ (unset HGPLAIN; hg version --quiet)
1413 $ (unset HGPLAIN; hg version --quiet)
1414 ### default ### plain: 1
1414 ### default ### plain: 1
1415 ### yes ####### plain: 1
1415 ### yes ####### plain: 1
1416 ### no ######## plain: <unset>
1416 ### no ######## plain: <unset>
1417 ### auto ###### plain: <unset>
1417 ### auto ###### plain: <unset>
1418 Mercurial Distributed SCM (*) (glob)
1418 Mercurial Distributed SCM (*) (glob)
1419
1419
1420 $ HGPLAIN=1 hg version --quiet
1420 $ HGPLAIN=1 hg version --quiet
1421 ### default ### plain: 1
1421 ### default ### plain: 1
1422 ### yes ####### plain: 1
1422 ### yes ####### plain: 1
1423 ### no ######## plain: <unset>
1423 ### no ######## plain: <unset>
1424 ### auto ###### plain: 1
1424 ### auto ###### plain: 1
1425 Mercurial Distributed SCM (*) (glob)
1425 Mercurial Distributed SCM (*) (glob)
1426
1426
1427 Test hook that change the underlying repo
1427 Test hook that change the underlying repo
1428 =========================================
1428 =========================================
1429
1429
1430 blackbox access the dirstate afterward and can see a changelog / dirstate
1430 blackbox access the dirstate afterward and can see a changelog / dirstate
1431 desync.
1431 desync.
1432
1432
1433
1433
1434 $ cd $TESTTMP
1434 $ cd $TESTTMP
1435 $ cat <<EOF >> $HGRCPATH
1435 $ cat <<EOF >> $HGRCPATH
1436 > [extensions]
1436 > [extensions]
1437 > blackbox=
1437 > blackbox=
1438 > [hooks]
1438 > [hooks]
1439 > post-merge = hg commit -m "auto merge"
1439 > post-merge = hg commit -m "auto merge"
1440 > EOF
1440 > EOF
1441
1441
1442 $ hg init t
1442 $ hg init t
1443 $ cd t
1443 $ cd t
1444 $ touch ".hgignore"
1444 $ touch ".hgignore"
1445 $ hg commit -Am "initial" -d'0 0'
1445 $ hg commit -Am "initial" -d'0 0'
1446 adding .hgignore
1446 adding .hgignore
1447
1447
1448 $ echo This is file a1 > a
1448 $ echo This is file a1 > a
1449 $ hg commit -Am "commit #1" -d'0 0'
1449 $ hg commit -Am "commit #1" -d'0 0'
1450 adding a
1450 adding a
1451
1451
1452 $ hg update 0
1452 $ hg update 0
1453 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1453 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1454 $ echo This is file b1 > b
1454 $ echo This is file b1 > b
1455 $ hg commit -Am "commit #2" -d'0 0'
1455 $ hg commit -Am "commit #2" -d'0 0'
1456 adding b
1456 adding b
1457 created new head
1457 created new head
1458
1458
1459 $ hg merge 1
1459 $ hg merge 1
1460 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1460 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1461 (branch merge, don't forget to commit)
1461 (branch merge, don't forget to commit)
1462
1462
1463 $ cd ..
1463 $ cd ..
@@ -1,180 +1,180 b''
1 #require unix-permissions
1 #require unix-permissions
2
2
3 test that new files created in .hg inherit the permissions from .hg/store
3 test that new files created in .hg inherit the permissions from .hg/store
4
4
5 $ mkdir dir
5 $ mkdir dir
6
6
7 just in case somebody has a strange $TMPDIR
7 just in case somebody has a strange $TMPDIR
8
8
9 $ chmod g-s dir
9 $ chmod g-s dir
10 $ cd dir
10 $ cd dir
11
11
12 $ cat >printmodes.py <<EOF
12 $ cat >printmodes.py <<EOF
13 > import os
13 > import os
14 > import sys
14 > import sys
15 >
15 >
16 > allnames = []
16 > allnames = []
17 > isdir = {}
17 > isdir = {}
18 > for root, dirs, files in os.walk(sys.argv[1]):
18 > for root, dirs, files in os.walk(sys.argv[1]):
19 > for d in dirs:
19 > for d in dirs:
20 > name = os.path.join(root, d)
20 > name = os.path.join(root, d)
21 > isdir[name] = 1
21 > isdir[name] = 1
22 > allnames.append(name)
22 > allnames.append(name)
23 > for f in files:
23 > for f in files:
24 > name = os.path.join(root, f)
24 > name = os.path.join(root, f)
25 > allnames.append(name)
25 > allnames.append(name)
26 > allnames.sort()
26 > allnames.sort()
27 > for name in allnames:
27 > for name in allnames:
28 > suffix = name in isdir and '/' or ''
28 > suffix = name in isdir and '/' or ''
29 > print('%05o %s%s' % (os.lstat(name).st_mode & 0o7777, name, suffix))
29 > print('%05o %s%s' % (os.lstat(name).st_mode & 0o7777, name, suffix))
30 > EOF
30 > EOF
31
31
32 $ cat >mode.py <<EOF
32 $ cat >mode.py <<EOF
33 > import os
33 > import os
34 > import sys
34 > import sys
35 > print('%05o' % os.lstat(sys.argv[1]).st_mode)
35 > print('%05o' % os.lstat(sys.argv[1]).st_mode)
36 > EOF
36 > EOF
37
37
38 $ umask 077
38 $ umask 077
39
39
40 $ hg init repo
40 $ hg init repo
41 $ cd repo
41 $ cd repo
42
42
43 $ chmod 0770 .hg/store .hg/cache .hg/wcache
43 $ chmod 0770 .hg/store .hg/cache .hg/wcache
44
44
45 before commit
45 before commit
46 store can be written by the group, other files cannot
46 store can be written by the group, other files cannot
47 store is setgid
47 store is setgid
48
48
49 $ "$PYTHON" ../printmodes.py .
49 $ "$PYTHON" ../printmodes.py .
50 00700 ./.hg/
50 00700 ./.hg/
51 00600 ./.hg/00changelog.i
51 00600 ./.hg/00changelog.i
52 00770 ./.hg/cache/
52 00770 ./.hg/cache/
53 00600 ./.hg/requires
53 00600 ./.hg/requires
54 00770 ./.hg/store/
54 00770 ./.hg/store/
55 00600 ./.hg/store/requires
55 00600 ./.hg/store/requires
56 00770 ./.hg/wcache/
56 00770 ./.hg/wcache/
57
57
58 $ mkdir dir
58 $ mkdir dir
59 $ touch foo dir/bar
59 $ touch foo dir/bar
60 $ hg ci -qAm 'add files'
60 $ hg ci -qAm 'add files'
61
61
62 after commit
62 after commit
63 working dir files can only be written by the owner
63 working dir files can only be written by the owner
64 files created in .hg can be written by the group
64 files created in .hg can be written by the group
65 (in particular, store/**, dirstate, branch cache file, undo files)
65 (in particular, store/**, dirstate, branch cache file, undo files)
66 new directories are setgid
66 new directories are setgid
67
67
68 $ "$PYTHON" ../printmodes.py .
68 $ "$PYTHON" ../printmodes.py .
69 00700 ./.hg/
69 00700 ./.hg/
70 00600 ./.hg/00changelog.i
70 00600 ./.hg/00changelog.i
71 00660 ./.hg/branch
71 00660 ./.hg/branch
72 00770 ./.hg/cache/
72 00770 ./.hg/cache/
73 00660 ./.hg/cache/branch2-served
73 00660 ./.hg/cache/branch2-served
74 00660 ./.hg/cache/rbc-names-v1
74 00660 ./.hg/cache/rbc-names-v1
75 00660 ./.hg/cache/rbc-revs-v1
75 00660 ./.hg/cache/rbc-revs-v1
76 00660 ./.hg/dirstate
76 00660 ./.hg/dirstate
77 00660 ./.hg/fsmonitor.state (fsmonitor !)
77 00660 ./.hg/fsmonitor.state (fsmonitor !)
78 00660 ./.hg/last-message.txt
78 00660 ./.hg/last-message.txt
79 00600 ./.hg/requires
79 00600 ./.hg/requires
80 00770 ./.hg/store/
80 00770 ./.hg/store/
81 00660 ./.hg/store/00changelog.i
81 00660 ./.hg/store/00changelog.i
82 00660 ./.hg/store/00manifest.i
82 00660 ./.hg/store/00manifest.i
83 00770 ./.hg/store/data/
83 00770 ./.hg/store/data/
84 00770 ./.hg/store/data/dir/
84 00770 ./.hg/store/data/dir/
85 00660 ./.hg/store/data/dir/bar.i (reporevlogstore !)
85 00660 ./.hg/store/data/dir/bar.i (reporevlogstore !)
86 00660 ./.hg/store/data/foo.i (reporevlogstore !)
86 00660 ./.hg/store/data/foo.i (reporevlogstore !)
87 00770 ./.hg/store/data/dir/bar/ (reposimplestore !)
87 00770 ./.hg/store/data/dir/bar/ (reposimplestore !)
88 00660 ./.hg/store/data/dir/bar/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
88 00660 ./.hg/store/data/dir/bar/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
89 00660 ./.hg/store/data/dir/bar/index (reposimplestore !)
89 00660 ./.hg/store/data/dir/bar/index (reposimplestore !)
90 00770 ./.hg/store/data/foo/ (reposimplestore !)
90 00770 ./.hg/store/data/foo/ (reposimplestore !)
91 00660 ./.hg/store/data/foo/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
91 00660 ./.hg/store/data/foo/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
92 00660 ./.hg/store/data/foo/index (reposimplestore !)
92 00660 ./.hg/store/data/foo/index (reposimplestore !)
93 00660 ./.hg/store/fncache (repofncache !)
93 00660 ./.hg/store/fncache (repofncache !)
94 00660 ./.hg/store/phaseroots
94 00660 ./.hg/store/phaseroots
95 00600 ./.hg/store/requires
95 00600 ./.hg/store/requires
96 00660 ./.hg/store/undo
96 00660 ./.hg/store/undo
97 00660 ./.hg/store/undo.backupfiles
97 00660 ./.hg/store/undo.backupfiles
98 00660 ./.hg/undo.backup.branch
98 00660 ./.hg/undo.backup.branch.bck
99 00660 ./.hg/undo.desc
99 00660 ./.hg/undo.desc
100 00770 ./.hg/wcache/
100 00770 ./.hg/wcache/
101 00711 ./.hg/wcache/checkisexec
101 00711 ./.hg/wcache/checkisexec
102 007.. ./.hg/wcache/checklink (re)
102 007.. ./.hg/wcache/checklink (re)
103 00600 ./.hg/wcache/checklink-target
103 00600 ./.hg/wcache/checklink-target
104 00660 ./.hg/wcache/manifestfulltextcache (reporevlogstore !)
104 00660 ./.hg/wcache/manifestfulltextcache (reporevlogstore !)
105 00700 ./dir/
105 00700 ./dir/
106 00600 ./dir/bar
106 00600 ./dir/bar
107 00600 ./foo
107 00600 ./foo
108
108
109 $ umask 007
109 $ umask 007
110 $ hg init ../push
110 $ hg init ../push
111
111
112 before push
112 before push
113 group can write everything
113 group can write everything
114
114
115 $ "$PYTHON" ../printmodes.py ../push
115 $ "$PYTHON" ../printmodes.py ../push
116 00770 ../push/.hg/
116 00770 ../push/.hg/
117 00660 ../push/.hg/00changelog.i
117 00660 ../push/.hg/00changelog.i
118 00770 ../push/.hg/cache/
118 00770 ../push/.hg/cache/
119 00660 ../push/.hg/requires
119 00660 ../push/.hg/requires
120 00770 ../push/.hg/store/
120 00770 ../push/.hg/store/
121 00660 ../push/.hg/store/requires
121 00660 ../push/.hg/store/requires
122 00770 ../push/.hg/wcache/
122 00770 ../push/.hg/wcache/
123
123
124 $ umask 077
124 $ umask 077
125 $ hg -q push ../push
125 $ hg -q push ../push
126
126
127 after push
127 after push
128 group can still write everything
128 group can still write everything
129
129
130 $ "$PYTHON" ../printmodes.py ../push
130 $ "$PYTHON" ../printmodes.py ../push
131 00770 ../push/.hg/
131 00770 ../push/.hg/
132 00660 ../push/.hg/00changelog.i
132 00660 ../push/.hg/00changelog.i
133 00660 ../push/.hg/branch
133 00660 ../push/.hg/branch
134 00770 ../push/.hg/cache/
134 00770 ../push/.hg/cache/
135 00660 ../push/.hg/cache/branch2-base
135 00660 ../push/.hg/cache/branch2-base
136 00660 ../push/.hg/cache/rbc-names-v1
136 00660 ../push/.hg/cache/rbc-names-v1
137 00660 ../push/.hg/cache/rbc-revs-v1
137 00660 ../push/.hg/cache/rbc-revs-v1
138 00660 ../push/.hg/requires
138 00660 ../push/.hg/requires
139 00770 ../push/.hg/store/
139 00770 ../push/.hg/store/
140 00660 ../push/.hg/store/00changelog.i
140 00660 ../push/.hg/store/00changelog.i
141 00660 ../push/.hg/store/00manifest.i
141 00660 ../push/.hg/store/00manifest.i
142 00770 ../push/.hg/store/data/
142 00770 ../push/.hg/store/data/
143 00770 ../push/.hg/store/data/dir/
143 00770 ../push/.hg/store/data/dir/
144 00660 ../push/.hg/store/data/dir/bar.i (reporevlogstore !)
144 00660 ../push/.hg/store/data/dir/bar.i (reporevlogstore !)
145 00660 ../push/.hg/store/data/foo.i (reporevlogstore !)
145 00660 ../push/.hg/store/data/foo.i (reporevlogstore !)
146 00770 ../push/.hg/store/data/dir/bar/ (reposimplestore !)
146 00770 ../push/.hg/store/data/dir/bar/ (reposimplestore !)
147 00660 ../push/.hg/store/data/dir/bar/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
147 00660 ../push/.hg/store/data/dir/bar/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
148 00660 ../push/.hg/store/data/dir/bar/index (reposimplestore !)
148 00660 ../push/.hg/store/data/dir/bar/index (reposimplestore !)
149 00770 ../push/.hg/store/data/foo/ (reposimplestore !)
149 00770 ../push/.hg/store/data/foo/ (reposimplestore !)
150 00660 ../push/.hg/store/data/foo/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
150 00660 ../push/.hg/store/data/foo/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
151 00660 ../push/.hg/store/data/foo/index (reposimplestore !)
151 00660 ../push/.hg/store/data/foo/index (reposimplestore !)
152 00660 ../push/.hg/store/fncache (repofncache !)
152 00660 ../push/.hg/store/fncache (repofncache !)
153 00660 ../push/.hg/store/requires
153 00660 ../push/.hg/store/requires
154 00660 ../push/.hg/store/undo
154 00660 ../push/.hg/store/undo
155 00660 ../push/.hg/store/undo.backupfiles
155 00660 ../push/.hg/store/undo.backupfiles
156 00660 ../push/.hg/undo.backup.branch
156 00660 ../push/.hg/undo.backup.branch.bck
157 00660 ../push/.hg/undo.desc
157 00660 ../push/.hg/undo.desc
158 00770 ../push/.hg/wcache/
158 00770 ../push/.hg/wcache/
159
159
160
160
161 Test that we don't lose the setgid bit when we call chmod.
161 Test that we don't lose the setgid bit when we call chmod.
162 Not all systems support setgid directories (e.g. HFS+), so
162 Not all systems support setgid directories (e.g. HFS+), so
163 just check that directories have the same mode.
163 just check that directories have the same mode.
164
164
165 $ cd ..
165 $ cd ..
166 $ hg init setgid
166 $ hg init setgid
167 $ cd setgid
167 $ cd setgid
168 $ chmod g+rwx .hg/store
168 $ chmod g+rwx .hg/store
169 $ chmod g+s .hg/store 2> /dev/null || true
169 $ chmod g+s .hg/store 2> /dev/null || true
170 $ mkdir dir
170 $ mkdir dir
171 $ touch dir/file
171 $ touch dir/file
172 $ hg ci -qAm 'add dir/file'
172 $ hg ci -qAm 'add dir/file'
173 $ storemode=`"$PYTHON" ../mode.py .hg/store`
173 $ storemode=`"$PYTHON" ../mode.py .hg/store`
174 $ dirmode=`"$PYTHON" ../mode.py .hg/store/data/dir`
174 $ dirmode=`"$PYTHON" ../mode.py .hg/store/data/dir`
175 $ if [ "$storemode" != "$dirmode" ]; then
175 $ if [ "$storemode" != "$dirmode" ]; then
176 > echo "$storemode != $dirmode"
176 > echo "$storemode != $dirmode"
177 > fi
177 > fi
178 $ cd ..
178 $ cd ..
179
179
180 $ cd .. # g-s dir
180 $ cd .. # g-s dir
@@ -1,263 +1,263 b''
1 Create user cache directory
1 Create user cache directory
2
2
3 $ USERCACHE=`pwd`/cache; export USERCACHE
3 $ USERCACHE=`pwd`/cache; export USERCACHE
4 $ cat <<EOF >> ${HGRCPATH}
4 $ cat <<EOF >> ${HGRCPATH}
5 > [extensions]
5 > [extensions]
6 > hgext.largefiles=
6 > hgext.largefiles=
7 > [largefiles]
7 > [largefiles]
8 > usercache=${USERCACHE}
8 > usercache=${USERCACHE}
9 > EOF
9 > EOF
10 $ mkdir -p ${USERCACHE}
10 $ mkdir -p ${USERCACHE}
11
11
12 Create source repo, and commit adding largefile.
12 Create source repo, and commit adding largefile.
13
13
14 $ hg init src
14 $ hg init src
15 $ cd src
15 $ cd src
16 $ echo large > large
16 $ echo large > large
17 $ hg add --large large
17 $ hg add --large large
18 $ hg commit -m 'add largefile'
18 $ hg commit -m 'add largefile'
19 $ hg rm large
19 $ hg rm large
20 $ hg commit -m 'branchhead without largefile' large
20 $ hg commit -m 'branchhead without largefile' large
21 $ hg up -qr 0
21 $ hg up -qr 0
22 $ rm large
22 $ rm large
23 $ echo "0000000000000000000000000000000000000000" > .hglf/large
23 $ echo "0000000000000000000000000000000000000000" > .hglf/large
24 $ hg commit -m 'commit missing file with corrupt standin' large
24 $ hg commit -m 'commit missing file with corrupt standin' large
25 abort: large: file not found!
25 abort: large: file not found!
26 [255]
26 [255]
27 $ hg up -Cqr 0
27 $ hg up -Cqr 0
28 $ cd ..
28 $ cd ..
29
29
30 Discard all cached largefiles in USERCACHE
30 Discard all cached largefiles in USERCACHE
31
31
32 $ rm -rf ${USERCACHE}
32 $ rm -rf ${USERCACHE}
33
33
34 Create mirror repo, and pull from source without largefile:
34 Create mirror repo, and pull from source without largefile:
35 "pull" is used instead of "clone" for suppression of (1) updating to
35 "pull" is used instead of "clone" for suppression of (1) updating to
36 tip (= caching largefile from source repo), and (2) recording source
36 tip (= caching largefile from source repo), and (2) recording source
37 repo as "default" path in .hg/hgrc.
37 repo as "default" path in .hg/hgrc.
38
38
39 $ hg init mirror
39 $ hg init mirror
40 $ cd mirror
40 $ cd mirror
41 $ hg pull ../src
41 $ hg pull ../src
42 pulling from ../src
42 pulling from ../src
43 requesting all changes
43 requesting all changes
44 adding changesets
44 adding changesets
45 adding manifests
45 adding manifests
46 adding file changes
46 adding file changes
47 added 2 changesets with 1 changes to 1 files
47 added 2 changesets with 1 changes to 1 files
48 new changesets eb85d9124f3f:26c18ce05e4e
48 new changesets eb85d9124f3f:26c18ce05e4e
49 (run 'hg update' to get a working copy)
49 (run 'hg update' to get a working copy)
50
50
51 Update working directory to "tip", which requires largefile("large"),
51 Update working directory to "tip", which requires largefile("large"),
52 but there is no cache file for it. So, hg must treat it as
52 but there is no cache file for it. So, hg must treat it as
53 "missing"(!) file.
53 "missing"(!) file.
54
54
55 $ hg update -r0
55 $ hg update -r0
56 getting changed largefiles
56 getting changed largefiles
57 large: largefile 7f7097b041ccf68cc5561e9600da4655d21c6d18 not available from file:/*/$TESTTMP/mirror (glob)
57 large: largefile 7f7097b041ccf68cc5561e9600da4655d21c6d18 not available from file:/*/$TESTTMP/mirror (glob)
58 0 largefiles updated, 0 removed
58 0 largefiles updated, 0 removed
59 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
60 $ hg status
60 $ hg status
61 ! large
61 ! large
62
62
63 Update working directory to null: this cleanup .hg/largefiles/dirstate
63 Update working directory to null: this cleanup .hg/largefiles/dirstate
64
64
65 $ hg update null
65 $ hg update null
66 getting changed largefiles
66 getting changed largefiles
67 0 largefiles updated, 0 removed
67 0 largefiles updated, 0 removed
68 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
68 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
69
69
70 Update working directory to tip, again.
70 Update working directory to tip, again.
71
71
72 $ hg update -r0
72 $ hg update -r0
73 getting changed largefiles
73 getting changed largefiles
74 large: largefile 7f7097b041ccf68cc5561e9600da4655d21c6d18 not available from file:/*/$TESTTMP/mirror (glob)
74 large: largefile 7f7097b041ccf68cc5561e9600da4655d21c6d18 not available from file:/*/$TESTTMP/mirror (glob)
75 0 largefiles updated, 0 removed
75 0 largefiles updated, 0 removed
76 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
76 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
77 $ hg status
77 $ hg status
78 ! large
78 ! large
79 $ cd ..
79 $ cd ..
80
80
81 Verify that largefiles from pulled branchheads are fetched, also to an empty repo
81 Verify that largefiles from pulled branchheads are fetched, also to an empty repo
82
82
83 $ hg init mirror2
83 $ hg init mirror2
84 $ hg -R mirror2 pull src -r0
84 $ hg -R mirror2 pull src -r0
85 pulling from src
85 pulling from src
86 adding changesets
86 adding changesets
87 adding manifests
87 adding manifests
88 adding file changes
88 adding file changes
89 added 1 changesets with 1 changes to 1 files
89 added 1 changesets with 1 changes to 1 files
90 new changesets eb85d9124f3f
90 new changesets eb85d9124f3f
91 (run 'hg update' to get a working copy)
91 (run 'hg update' to get a working copy)
92
92
93 #if unix-permissions
93 #if unix-permissions
94
94
95 Portable way to print file permissions:
95 Portable way to print file permissions:
96
96
97 $ cat > ls-l.py <<EOF
97 $ cat > ls-l.py <<EOF
98 > #!$PYTHON
98 > #!$PYTHON
99 > import os
99 > import os
100 > import sys
100 > import sys
101 > path = sys.argv[1]
101 > path = sys.argv[1]
102 > print('%03o' % (os.lstat(path).st_mode & 0o777))
102 > print('%03o' % (os.lstat(path).st_mode & 0o777))
103 > EOF
103 > EOF
104 $ chmod +x ls-l.py
104 $ chmod +x ls-l.py
105
105
106 Test that files in .hg/largefiles inherit mode from .hg/store, not
106 Test that files in .hg/largefiles inherit mode from .hg/store, not
107 from file in working copy:
107 from file in working copy:
108
108
109 $ cd src
109 $ cd src
110 $ chmod 750 .hg/store
110 $ chmod 750 .hg/store
111 $ chmod 660 large
111 $ chmod 660 large
112 $ echo change >> large
112 $ echo change >> large
113 $ hg commit -m change
113 $ hg commit -m change
114 created new head
114 created new head
115 $ ../ls-l.py .hg/largefiles/e151b474069de4ca6898f67ce2f2a7263adf8fea
115 $ ../ls-l.py .hg/largefiles/e151b474069de4ca6898f67ce2f2a7263adf8fea
116 640
116 640
117
117
118 Test permission of with files in .hg/largefiles created by update:
118 Test permission of with files in .hg/largefiles created by update:
119
119
120 $ cd ../mirror
120 $ cd ../mirror
121 $ rm -r "$USERCACHE" .hg/largefiles # avoid links
121 $ rm -r "$USERCACHE" .hg/largefiles # avoid links
122 $ chmod 750 .hg/store
122 $ chmod 750 .hg/store
123 $ hg pull ../src --update -q
123 $ hg pull ../src --update -q
124 $ ../ls-l.py .hg/largefiles/e151b474069de4ca6898f67ce2f2a7263adf8fea
124 $ ../ls-l.py .hg/largefiles/e151b474069de4ca6898f67ce2f2a7263adf8fea
125 640
125 640
126
126
127 Test permission of files created by push:
127 Test permission of files created by push:
128
128
129 $ hg serve -R ../src -d -p $HGPORT --pid-file hg.pid \
129 $ hg serve -R ../src -d -p $HGPORT --pid-file hg.pid \
130 > --config "web.allow_push=*" --config web.push_ssl=no
130 > --config "web.allow_push=*" --config web.push_ssl=no
131 $ cat hg.pid >> $DAEMON_PIDS
131 $ cat hg.pid >> $DAEMON_PIDS
132
132
133 $ echo change >> large
133 $ echo change >> large
134 $ hg commit -m change
134 $ hg commit -m change
135
135
136 $ rm -r "$USERCACHE"
136 $ rm -r "$USERCACHE"
137
137
138 $ hg push -q http://localhost:$HGPORT/
138 $ hg push -q http://localhost:$HGPORT/
139
139
140 $ ../ls-l.py ../src/.hg/largefiles/b734e14a0971e370408ab9bce8d56d8485e368a9
140 $ ../ls-l.py ../src/.hg/largefiles/b734e14a0971e370408ab9bce8d56d8485e368a9
141 640
141 640
142
142
143 $ cd ..
143 $ cd ..
144
144
145 #endif
145 #endif
146
146
147 Test issue 4053 (remove --after on a deleted, uncommitted file shouldn't say
147 Test issue 4053 (remove --after on a deleted, uncommitted file shouldn't say
148 it is missing, but a remove on a nonexistent unknown file still should. Same
148 it is missing, but a remove on a nonexistent unknown file still should. Same
149 for a forget.)
149 for a forget.)
150
150
151 $ cd src
151 $ cd src
152 $ touch x
152 $ touch x
153 $ hg add x
153 $ hg add x
154 $ mv x y
154 $ mv x y
155 $ hg remove -A x y ENOENT
155 $ hg remove -A x y ENOENT
156 ENOENT: * (glob)
156 ENOENT: * (glob)
157 not removing y: file is untracked
157 not removing y: file is untracked
158 [1]
158 [1]
159 $ hg add y
159 $ hg add y
160 $ mv y z
160 $ mv y z
161 $ hg forget y z ENOENT
161 $ hg forget y z ENOENT
162 ENOENT: * (glob)
162 ENOENT: * (glob)
163 not removing z: file is already untracked
163 not removing z: file is already untracked
164 [1]
164 [1]
165
165
166 Largefiles are accessible from the share's store
166 Largefiles are accessible from the share's store
167 $ cd ..
167 $ cd ..
168 $ hg share -q src share_dst --config extensions.share=
168 $ hg share -q src share_dst --config extensions.share=
169 $ hg -R share_dst update -r0
169 $ hg -R share_dst update -r0
170 getting changed largefiles
170 getting changed largefiles
171 1 largefiles updated, 0 removed
171 1 largefiles updated, 0 removed
172 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
172 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
173
173
174 $ echo modified > share_dst/large
174 $ echo modified > share_dst/large
175 $ hg -R share_dst ci -m modified
175 $ hg -R share_dst ci -m modified
176 created new head
176 created new head
177
177
178 Only dirstate is in the local store for the share, and the largefile is in the
178 Only dirstate is in the local store for the share, and the largefile is in the
179 share source's local store. Avoid the extra largefiles added in the unix
179 share source's local store. Avoid the extra largefiles added in the unix
180 conditional above.
180 conditional above.
181 $ hash=`hg -R share_dst cat share_dst/.hglf/large`
181 $ hash=`hg -R share_dst cat share_dst/.hglf/large`
182 $ echo $hash
182 $ echo $hash
183 e2fb5f2139d086ded2cb600d5a91a196e76bf020
183 e2fb5f2139d086ded2cb600d5a91a196e76bf020
184
184
185 $ find share_dst/.hg/largefiles/* | sort
185 $ find share_dst/.hg/largefiles/* | sort
186 share_dst/.hg/largefiles/dirstate
186 share_dst/.hg/largefiles/dirstate
187 share_dst/.hg/largefiles/undo.backup.dirstate
187 share_dst/.hg/largefiles/undo.backup.dirstate.bck
188
188
189 $ find src/.hg/largefiles/* | egrep "(dirstate|$hash)" | sort
189 $ find src/.hg/largefiles/* | egrep "(dirstate|$hash)" | sort
190 src/.hg/largefiles/dirstate
190 src/.hg/largefiles/dirstate
191 src/.hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020
191 src/.hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020
192
192
193 Verify that backwards compatibility is maintained for old storage layout
193 Verify that backwards compatibility is maintained for old storage layout
194 $ mv src/.hg/largefiles/$hash share_dst/.hg/largefiles
194 $ mv src/.hg/largefiles/$hash share_dst/.hg/largefiles
195 $ hg verify --quiet --lfa -R share_dst --config largefiles.usercache=
195 $ hg verify --quiet --lfa -R share_dst --config largefiles.usercache=
196
196
197 Inject corruption into the largefiles store and see how update handles that:
197 Inject corruption into the largefiles store and see how update handles that:
198
198
199 $ cd src
199 $ cd src
200 $ hg up -qC tip
200 $ hg up -qC tip
201 $ cat large
201 $ cat large
202 modified
202 modified
203 $ rm large
203 $ rm large
204 $ cat .hglf/large
204 $ cat .hglf/large
205 e2fb5f2139d086ded2cb600d5a91a196e76bf020
205 e2fb5f2139d086ded2cb600d5a91a196e76bf020
206 $ mv .hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020 ..
206 $ mv .hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020 ..
207 $ echo corruption > .hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020
207 $ echo corruption > .hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020
208 $ hg up -C
208 $ hg up -C
209 getting changed largefiles
209 getting changed largefiles
210 large: data corruption in $TESTTMP/src/.hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020 with hash 6a7bb2556144babe3899b25e5428123735bb1e27
210 large: data corruption in $TESTTMP/src/.hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020 with hash 6a7bb2556144babe3899b25e5428123735bb1e27
211 0 largefiles updated, 0 removed
211 0 largefiles updated, 0 removed
212 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
212 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
213 updated to "cd24c147f45c: modified"
213 updated to "cd24c147f45c: modified"
214 [12] other heads for branch "default" (re)
214 [12] other heads for branch "default" (re)
215 $ hg st
215 $ hg st
216 ! large
216 ! large
217 ? z
217 ? z
218 $ rm .hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020
218 $ rm .hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020
219
219
220 #if serve
220 #if serve
221
221
222 Test coverage of error handling from putlfile:
222 Test coverage of error handling from putlfile:
223
223
224 $ mkdir $TESTTMP/mirrorcache
224 $ mkdir $TESTTMP/mirrorcache
225 $ hg serve -R ../mirror -d -p $HGPORT1 --pid-file hg.pid --config largefiles.usercache=$TESTTMP/mirrorcache
225 $ hg serve -R ../mirror -d -p $HGPORT1 --pid-file hg.pid --config largefiles.usercache=$TESTTMP/mirrorcache
226 $ cat hg.pid >> $DAEMON_PIDS
226 $ cat hg.pid >> $DAEMON_PIDS
227
227
228 $ hg push http://localhost:$HGPORT1 -f --config files.usercache=nocache
228 $ hg push http://localhost:$HGPORT1 -f --config files.usercache=nocache
229 pushing to http://localhost:$HGPORT1/
229 pushing to http://localhost:$HGPORT1/
230 searching for changes
230 searching for changes
231 abort: remotestore: could not open file $TESTTMP/src/.hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020: HTTP Error 403: ssl required
231 abort: remotestore: could not open file $TESTTMP/src/.hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020: HTTP Error 403: ssl required
232 [255]
232 [255]
233
233
234 $ rm .hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020
234 $ rm .hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020
235
235
236 Test coverage of 'missing from store':
236 Test coverage of 'missing from store':
237
237
238 $ hg serve -R ../mirror -d -p $HGPORT2 --pid-file hg.pid --config largefiles.usercache=$TESTTMP/mirrorcache --config "web.allow_push=*" --config web.push_ssl=no
238 $ hg serve -R ../mirror -d -p $HGPORT2 --pid-file hg.pid --config largefiles.usercache=$TESTTMP/mirrorcache --config "web.allow_push=*" --config web.push_ssl=no
239 $ cat hg.pid >> $DAEMON_PIDS
239 $ cat hg.pid >> $DAEMON_PIDS
240
240
241 $ hg push http://localhost:$HGPORT2 -f --config largefiles.usercache=nocache
241 $ hg push http://localhost:$HGPORT2 -f --config largefiles.usercache=nocache
242 pushing to http://localhost:$HGPORT2/
242 pushing to http://localhost:$HGPORT2/
243 searching for changes
243 searching for changes
244 abort: largefile e2fb5f2139d086ded2cb600d5a91a196e76bf020 missing from store (needs to be uploaded)
244 abort: largefile e2fb5f2139d086ded2cb600d5a91a196e76bf020 missing from store (needs to be uploaded)
245 [255]
245 [255]
246
246
247 Verify that --lfrev controls which revisions are checked for largefiles to push
247 Verify that --lfrev controls which revisions are checked for largefiles to push
248
248
249 $ hg push http://localhost:$HGPORT2 -f --config largefiles.usercache=nocache --lfrev tip
249 $ hg push http://localhost:$HGPORT2 -f --config largefiles.usercache=nocache --lfrev tip
250 pushing to http://localhost:$HGPORT2/
250 pushing to http://localhost:$HGPORT2/
251 searching for changes
251 searching for changes
252 abort: largefile e2fb5f2139d086ded2cb600d5a91a196e76bf020 missing from store (needs to be uploaded)
252 abort: largefile e2fb5f2139d086ded2cb600d5a91a196e76bf020 missing from store (needs to be uploaded)
253 [255]
253 [255]
254
254
255 $ hg push http://localhost:$HGPORT2 -f --config largefiles.usercache=nocache --lfrev null
255 $ hg push http://localhost:$HGPORT2 -f --config largefiles.usercache=nocache --lfrev null
256 pushing to http://localhost:$HGPORT2/
256 pushing to http://localhost:$HGPORT2/
257 searching for changes
257 searching for changes
258 remote: adding changesets
258 remote: adding changesets
259 remote: adding manifests
259 remote: adding manifests
260 remote: adding file changes
260 remote: adding file changes
261 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
261 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
262
262
263 #endif
263 #endif
@@ -1,1260 +1,1258 b''
1 ===================================
1 ===================================
2 Test the persistent on-disk nodemap
2 Test the persistent on-disk nodemap
3 ===================================
3 ===================================
4
4
5
5
6 $ cat << EOF >> $HGRCPATH
6 $ cat << EOF >> $HGRCPATH
7 > [format]
7 > [format]
8 > use-share-safe=yes
8 > use-share-safe=yes
9 > [extensions]
9 > [extensions]
10 > share=
10 > share=
11 > EOF
11 > EOF
12
12
13 #if no-rust
13 #if no-rust
14
14
15 $ cat << EOF >> $HGRCPATH
15 $ cat << EOF >> $HGRCPATH
16 > [format]
16 > [format]
17 > use-persistent-nodemap=yes
17 > use-persistent-nodemap=yes
18 > [devel]
18 > [devel]
19 > persistent-nodemap=yes
19 > persistent-nodemap=yes
20 > EOF
20 > EOF
21
21
22 #endif
22 #endif
23
23
24 $ hg init test-repo --config storage.revlog.persistent-nodemap.slow-path=allow
24 $ hg init test-repo --config storage.revlog.persistent-nodemap.slow-path=allow
25 $ cd test-repo
25 $ cd test-repo
26
26
27 Check handling of the default slow-path value
27 Check handling of the default slow-path value
28
28
29 #if no-pure no-rust
29 #if no-pure no-rust
30
30
31 $ hg id
31 $ hg id
32 abort: accessing `persistent-nodemap` repository without associated fast implementation.
32 abort: accessing `persistent-nodemap` repository without associated fast implementation.
33 (check `hg help config.format.use-persistent-nodemap` for details)
33 (check `hg help config.format.use-persistent-nodemap` for details)
34 [255]
34 [255]
35
35
36 Unlock further check (we are here to test the feature)
36 Unlock further check (we are here to test the feature)
37
37
38 $ cat << EOF >> $HGRCPATH
38 $ cat << EOF >> $HGRCPATH
39 > [storage]
39 > [storage]
40 > # to avoid spamming the test
40 > # to avoid spamming the test
41 > revlog.persistent-nodemap.slow-path=allow
41 > revlog.persistent-nodemap.slow-path=allow
42 > EOF
42 > EOF
43
43
44 #endif
44 #endif
45
45
46 #if rust
46 #if rust
47
47
48 Regression test for a previous bug in Rust/C FFI for the `Revlog_CAPI` capsule:
48 Regression test for a previous bug in Rust/C FFI for the `Revlog_CAPI` capsule:
49 in places where `mercurial/cext/revlog.c` function signatures use `Py_ssize_t`
49 in places where `mercurial/cext/revlog.c` function signatures use `Py_ssize_t`
50 (64 bits on Linux x86_64), corresponding declarations in `rust/hg-cpython/src/cindex.rs`
50 (64 bits on Linux x86_64), corresponding declarations in `rust/hg-cpython/src/cindex.rs`
51 incorrectly used `libc::c_int` (32 bits).
51 incorrectly used `libc::c_int` (32 bits).
52 As a result, -1 passed from Rust for the null revision became 4294967295 in C.
52 As a result, -1 passed from Rust for the null revision became 4294967295 in C.
53
53
54 $ hg log -r 00000000
54 $ hg log -r 00000000
55 changeset: -1:000000000000
55 changeset: -1:000000000000
56 tag: tip
56 tag: tip
57 user:
57 user:
58 date: Thu Jan 01 00:00:00 1970 +0000
58 date: Thu Jan 01 00:00:00 1970 +0000
59
59
60
60
61 #endif
61 #endif
62
62
63
63
64 $ hg debugformat
64 $ hg debugformat
65 format-variant repo
65 format-variant repo
66 fncache: yes
66 fncache: yes
67 dirstate-v2: no
67 dirstate-v2: no
68 tracked-hint: no
68 tracked-hint: no
69 dotencode: yes
69 dotencode: yes
70 generaldelta: yes
70 generaldelta: yes
71 share-safe: yes
71 share-safe: yes
72 sparserevlog: yes
72 sparserevlog: yes
73 persistent-nodemap: yes
73 persistent-nodemap: yes
74 copies-sdc: no
74 copies-sdc: no
75 revlog-v2: no
75 revlog-v2: no
76 changelog-v2: no
76 changelog-v2: no
77 plain-cl-delta: yes
77 plain-cl-delta: yes
78 compression: zlib (no-zstd !)
78 compression: zlib (no-zstd !)
79 compression: zstd (zstd !)
79 compression: zstd (zstd !)
80 compression-level: default
80 compression-level: default
81 $ hg debugbuilddag .+5000 --new-file
81 $ hg debugbuilddag .+5000 --new-file
82
82
83 $ hg debugnodemap --metadata
83 $ hg debugnodemap --metadata
84 uid: ???????? (glob)
84 uid: ???????? (glob)
85 tip-rev: 5000
85 tip-rev: 5000
86 tip-node: 6b02b8c7b96654c25e86ba69eda198d7e6ad8b3c
86 tip-node: 6b02b8c7b96654c25e86ba69eda198d7e6ad8b3c
87 data-length: 121088
87 data-length: 121088
88 data-unused: 0
88 data-unused: 0
89 data-unused: 0.000%
89 data-unused: 0.000%
90 $ f --size .hg/store/00changelog.n
90 $ f --size .hg/store/00changelog.n
91 .hg/store/00changelog.n: size=62
91 .hg/store/00changelog.n: size=62
92
92
93 Simple lookup works
93 Simple lookup works
94
94
95 $ ANYNODE=`hg log --template '{node|short}\n' --rev tip`
95 $ ANYNODE=`hg log --template '{node|short}\n' --rev tip`
96 $ hg log -r "$ANYNODE" --template '{rev}\n'
96 $ hg log -r "$ANYNODE" --template '{rev}\n'
97 5000
97 5000
98
98
99
99
100 #if rust
100 #if rust
101
101
102 $ f --sha256 .hg/store/00changelog-*.nd
102 $ f --sha256 .hg/store/00changelog-*.nd
103 .hg/store/00changelog-????????.nd: sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd (glob)
103 .hg/store/00changelog-????????.nd: sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd (glob)
104
104
105 $ f --sha256 .hg/store/00manifest-*.nd
105 $ f --sha256 .hg/store/00manifest-*.nd
106 .hg/store/00manifest-????????.nd: sha256=97117b1c064ea2f86664a124589e47db0e254e8d34739b5c5cc5bf31c9da2b51 (glob)
106 .hg/store/00manifest-????????.nd: sha256=97117b1c064ea2f86664a124589e47db0e254e8d34739b5c5cc5bf31c9da2b51 (glob)
107 $ hg debugnodemap --dump-new | f --sha256 --size
107 $ hg debugnodemap --dump-new | f --sha256 --size
108 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
108 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
109 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
109 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
110 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
110 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
111 0000: 00 00 00 91 00 00 00 20 00 00 00 bb 00 00 00 e7 |....... ........|
111 0000: 00 00 00 91 00 00 00 20 00 00 00 bb 00 00 00 e7 |....... ........|
112 0010: 00 00 00 66 00 00 00 a1 00 00 01 13 00 00 01 22 |...f..........."|
112 0010: 00 00 00 66 00 00 00 a1 00 00 01 13 00 00 01 22 |...f..........."|
113 0020: 00 00 00 23 00 00 00 fc 00 00 00 ba 00 00 00 5e |...#...........^|
113 0020: 00 00 00 23 00 00 00 fc 00 00 00 ba 00 00 00 5e |...#...........^|
114 0030: 00 00 00 df 00 00 01 4e 00 00 01 65 00 00 00 ab |.......N...e....|
114 0030: 00 00 00 df 00 00 01 4e 00 00 01 65 00 00 00 ab |.......N...e....|
115 0040: 00 00 00 a9 00 00 00 95 00 00 00 73 00 00 00 38 |...........s...8|
115 0040: 00 00 00 a9 00 00 00 95 00 00 00 73 00 00 00 38 |...........s...8|
116 0050: 00 00 00 cc 00 00 00 92 00 00 00 90 00 00 00 69 |...............i|
116 0050: 00 00 00 cc 00 00 00 92 00 00 00 90 00 00 00 69 |...............i|
117 0060: 00 00 00 ec 00 00 00 8d 00 00 01 4f 00 00 00 12 |...........O....|
117 0060: 00 00 00 ec 00 00 00 8d 00 00 01 4f 00 00 00 12 |...........O....|
118 0070: 00 00 02 0c 00 00 00 77 00 00 00 9c 00 00 00 8f |.......w........|
118 0070: 00 00 02 0c 00 00 00 77 00 00 00 9c 00 00 00 8f |.......w........|
119 0080: 00 00 00 d5 00 00 00 6b 00 00 00 48 00 00 00 b3 |.......k...H....|
119 0080: 00 00 00 d5 00 00 00 6b 00 00 00 48 00 00 00 b3 |.......k...H....|
120 0090: 00 00 00 e5 00 00 00 b5 00 00 00 8e 00 00 00 ad |................|
120 0090: 00 00 00 e5 00 00 00 b5 00 00 00 8e 00 00 00 ad |................|
121 00a0: 00 00 00 7b 00 00 00 7c 00 00 00 0b 00 00 00 2b |...{...|.......+|
121 00a0: 00 00 00 7b 00 00 00 7c 00 00 00 0b 00 00 00 2b |...{...|.......+|
122 00b0: 00 00 00 c6 00 00 00 1e 00 00 01 08 00 00 00 11 |................|
122 00b0: 00 00 00 c6 00 00 00 1e 00 00 01 08 00 00 00 11 |................|
123 00c0: 00 00 01 30 00 00 00 26 00 00 01 9c 00 00 00 35 |...0...&.......5|
123 00c0: 00 00 01 30 00 00 00 26 00 00 01 9c 00 00 00 35 |...0...&.......5|
124 00d0: 00 00 00 b8 00 00 01 31 00 00 00 2c 00 00 00 55 |.......1...,...U|
124 00d0: 00 00 00 b8 00 00 01 31 00 00 00 2c 00 00 00 55 |.......1...,...U|
125 00e0: 00 00 00 8a 00 00 00 9a 00 00 00 0c 00 00 01 1e |................|
125 00e0: 00 00 00 8a 00 00 00 9a 00 00 00 0c 00 00 01 1e |................|
126 00f0: 00 00 00 a4 00 00 00 83 00 00 00 c9 00 00 00 8c |................|
126 00f0: 00 00 00 a4 00 00 00 83 00 00 00 c9 00 00 00 8c |................|
127
127
128
128
129 #else
129 #else
130
130
131 $ f --sha256 .hg/store/00changelog-*.nd
131 $ f --sha256 .hg/store/00changelog-*.nd
132 .hg/store/00changelog-????????.nd: sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79 (glob)
132 .hg/store/00changelog-????????.nd: sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79 (glob)
133 $ hg debugnodemap --dump-new | f --sha256 --size
133 $ hg debugnodemap --dump-new | f --sha256 --size
134 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
134 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
135 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
135 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
136 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
136 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
137 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
137 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
138 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
138 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
139 0020: ff ff ff ff ff ff f5 06 ff ff ff ff ff ff f3 e7 |................|
139 0020: ff ff ff ff ff ff f5 06 ff ff ff ff ff ff f3 e7 |................|
140 0030: ff ff ef ca ff ff ff ff ff ff ff ff ff ff ff ff |................|
140 0030: ff ff ef ca ff ff ff ff ff ff ff ff ff ff ff ff |................|
141 0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
141 0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
142 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ed 08 |................|
142 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ed 08 |................|
143 0060: ff ff ed 66 ff ff ff ff ff ff ff ff ff ff ff ff |...f............|
143 0060: ff ff ed 66 ff ff ff ff ff ff ff ff ff ff ff ff |...f............|
144 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
144 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
145 0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
145 0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
146 0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f6 ed |................|
146 0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f6 ed |................|
147 00a0: ff ff ff ff ff ff fe 61 ff ff ff ff ff ff ff ff |.......a........|
147 00a0: ff ff ff ff ff ff fe 61 ff ff ff ff ff ff ff ff |.......a........|
148 00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
148 00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
149 00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
149 00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
150 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
150 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
151 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f1 02 |................|
151 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f1 02 |................|
152 00f0: ff ff ff ff ff ff ed 1b ff ff ff ff ff ff ff ff |................|
152 00f0: ff ff ff ff ff ff ed 1b ff ff ff ff ff ff ff ff |................|
153
153
154 #endif
154 #endif
155
155
156 $ hg debugnodemap --check
156 $ hg debugnodemap --check
157 revision in index: 5001
157 revision in index: 5001
158 revision in nodemap: 5001
158 revision in nodemap: 5001
159
159
160 add a new commit
160 add a new commit
161
161
162 $ hg up
162 $ hg up
163 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
163 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
164 $ echo foo > foo
164 $ echo foo > foo
165 $ hg add foo
165 $ hg add foo
166
166
167
167
168 Check slow-path config value handling
168 Check slow-path config value handling
169 -------------------------------------
169 -------------------------------------
170
170
171 #if no-pure no-rust
171 #if no-pure no-rust
172
172
173 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
173 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
174 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
174 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
175 falling back to default value: abort
175 falling back to default value: abort
176 abort: accessing `persistent-nodemap` repository without associated fast implementation.
176 abort: accessing `persistent-nodemap` repository without associated fast implementation.
177 (check `hg help config.format.use-persistent-nodemap` for details)
177 (check `hg help config.format.use-persistent-nodemap` for details)
178 [255]
178 [255]
179
179
180 $ hg log -r . --config "storage.revlog.persistent-nodemap.slow-path=warn"
180 $ hg log -r . --config "storage.revlog.persistent-nodemap.slow-path=warn"
181 warning: accessing `persistent-nodemap` repository without associated fast implementation.
181 warning: accessing `persistent-nodemap` repository without associated fast implementation.
182 (check `hg help config.format.use-persistent-nodemap` for details)
182 (check `hg help config.format.use-persistent-nodemap` for details)
183 changeset: 5000:6b02b8c7b966
183 changeset: 5000:6b02b8c7b966
184 tag: tip
184 tag: tip
185 user: debugbuilddag
185 user: debugbuilddag
186 date: Thu Jan 01 01:23:20 1970 +0000
186 date: Thu Jan 01 01:23:20 1970 +0000
187 summary: r5000
187 summary: r5000
188
188
189 $ hg ci -m 'foo' --config "storage.revlog.persistent-nodemap.slow-path=abort"
189 $ hg ci -m 'foo' --config "storage.revlog.persistent-nodemap.slow-path=abort"
190 abort: accessing `persistent-nodemap` repository without associated fast implementation.
190 abort: accessing `persistent-nodemap` repository without associated fast implementation.
191 (check `hg help config.format.use-persistent-nodemap` for details)
191 (check `hg help config.format.use-persistent-nodemap` for details)
192 [255]
192 [255]
193
193
194 #else
194 #else
195
195
196 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
196 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
197 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
197 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
198 falling back to default value: abort
198 falling back to default value: abort
199 6b02b8c7b966+ tip
199 6b02b8c7b966+ tip
200
200
201 #endif
201 #endif
202
202
203 $ hg ci -m 'foo'
203 $ hg ci -m 'foo'
204
204
205 #if no-pure no-rust
205 #if no-pure no-rust
206 $ hg debugnodemap --metadata
206 $ hg debugnodemap --metadata
207 uid: ???????? (glob)
207 uid: ???????? (glob)
208 tip-rev: 5001
208 tip-rev: 5001
209 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
209 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
210 data-length: 121088
210 data-length: 121088
211 data-unused: 0
211 data-unused: 0
212 data-unused: 0.000%
212 data-unused: 0.000%
213 #else
213 #else
214 $ hg debugnodemap --metadata
214 $ hg debugnodemap --metadata
215 uid: ???????? (glob)
215 uid: ???????? (glob)
216 tip-rev: 5001
216 tip-rev: 5001
217 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
217 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
218 data-length: 121344
218 data-length: 121344
219 data-unused: 256
219 data-unused: 256
220 data-unused: 0.211%
220 data-unused: 0.211%
221 #endif
221 #endif
222
222
223 $ f --size .hg/store/00changelog.n
223 $ f --size .hg/store/00changelog.n
224 .hg/store/00changelog.n: size=62
224 .hg/store/00changelog.n: size=62
225
225
226 (The pure code use the debug code that perform incremental update, the C code reencode from scratch)
226 (The pure code use the debug code that perform incremental update, the C code reencode from scratch)
227
227
228 #if pure
228 #if pure
229 $ f --sha256 .hg/store/00changelog-*.nd --size
229 $ f --sha256 .hg/store/00changelog-*.nd --size
230 .hg/store/00changelog-????????.nd: size=121344, sha256=cce54c5da5bde3ad72a4938673ed4064c86231b9c64376b082b163fdb20f8f66 (glob)
230 .hg/store/00changelog-????????.nd: size=121344, sha256=cce54c5da5bde3ad72a4938673ed4064c86231b9c64376b082b163fdb20f8f66 (glob)
231 #endif
231 #endif
232
232
233 #if rust
233 #if rust
234 $ f --sha256 .hg/store/00changelog-*.nd --size
234 $ f --sha256 .hg/store/00changelog-*.nd --size
235 .hg/store/00changelog-????????.nd: size=121344, sha256=952b042fcf614ceb37b542b1b723e04f18f83efe99bee4e0f5ccd232ef470e58 (glob)
235 .hg/store/00changelog-????????.nd: size=121344, sha256=952b042fcf614ceb37b542b1b723e04f18f83efe99bee4e0f5ccd232ef470e58 (glob)
236 #endif
236 #endif
237
237
238 #if no-pure no-rust
238 #if no-pure no-rust
239 $ f --sha256 .hg/store/00changelog-*.nd --size
239 $ f --sha256 .hg/store/00changelog-*.nd --size
240 .hg/store/00changelog-????????.nd: size=121088, sha256=df7c06a035b96cb28c7287d349d603baef43240be7736fe34eea419a49702e17 (glob)
240 .hg/store/00changelog-????????.nd: size=121088, sha256=df7c06a035b96cb28c7287d349d603baef43240be7736fe34eea419a49702e17 (glob)
241 #endif
241 #endif
242
242
243 $ hg debugnodemap --check
243 $ hg debugnodemap --check
244 revision in index: 5002
244 revision in index: 5002
245 revision in nodemap: 5002
245 revision in nodemap: 5002
246
246
247 Test code path without mmap
247 Test code path without mmap
248 ---------------------------
248 ---------------------------
249
249
250 $ echo bar > bar
250 $ echo bar > bar
251 $ hg add bar
251 $ hg add bar
252 $ hg ci -m 'bar' --config storage.revlog.persistent-nodemap.mmap=no
252 $ hg ci -m 'bar' --config storage.revlog.persistent-nodemap.mmap=no
253
253
254 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=yes
254 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=yes
255 revision in index: 5003
255 revision in index: 5003
256 revision in nodemap: 5003
256 revision in nodemap: 5003
257 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=no
257 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=no
258 revision in index: 5003
258 revision in index: 5003
259 revision in nodemap: 5003
259 revision in nodemap: 5003
260
260
261
261
262 #if pure
262 #if pure
263 $ hg debugnodemap --metadata
263 $ hg debugnodemap --metadata
264 uid: ???????? (glob)
264 uid: ???????? (glob)
265 tip-rev: 5002
265 tip-rev: 5002
266 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
266 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
267 data-length: 121600
267 data-length: 121600
268 data-unused: 512
268 data-unused: 512
269 data-unused: 0.421%
269 data-unused: 0.421%
270 $ f --sha256 .hg/store/00changelog-*.nd --size
270 $ f --sha256 .hg/store/00changelog-*.nd --size
271 .hg/store/00changelog-????????.nd: size=121600, sha256=def52503d049ccb823974af313a98a935319ba61f40f3aa06a8be4d35c215054 (glob)
271 .hg/store/00changelog-????????.nd: size=121600, sha256=def52503d049ccb823974af313a98a935319ba61f40f3aa06a8be4d35c215054 (glob)
272 #endif
272 #endif
273 #if rust
273 #if rust
274 $ hg debugnodemap --metadata
274 $ hg debugnodemap --metadata
275 uid: ???????? (glob)
275 uid: ???????? (glob)
276 tip-rev: 5002
276 tip-rev: 5002
277 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
277 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
278 data-length: 121600
278 data-length: 121600
279 data-unused: 512
279 data-unused: 512
280 data-unused: 0.421%
280 data-unused: 0.421%
281 $ f --sha256 .hg/store/00changelog-*.nd --size
281 $ f --sha256 .hg/store/00changelog-*.nd --size
282 .hg/store/00changelog-????????.nd: size=121600, sha256=dacf5b5f1d4585fee7527d0e67cad5b1ba0930e6a0928f650f779aefb04ce3fb (glob)
282 .hg/store/00changelog-????????.nd: size=121600, sha256=dacf5b5f1d4585fee7527d0e67cad5b1ba0930e6a0928f650f779aefb04ce3fb (glob)
283 #endif
283 #endif
284 #if no-pure no-rust
284 #if no-pure no-rust
285 $ hg debugnodemap --metadata
285 $ hg debugnodemap --metadata
286 uid: ???????? (glob)
286 uid: ???????? (glob)
287 tip-rev: 5002
287 tip-rev: 5002
288 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
288 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
289 data-length: 121088
289 data-length: 121088
290 data-unused: 0
290 data-unused: 0
291 data-unused: 0.000%
291 data-unused: 0.000%
292 $ f --sha256 .hg/store/00changelog-*.nd --size
292 $ f --sha256 .hg/store/00changelog-*.nd --size
293 .hg/store/00changelog-????????.nd: size=121088, sha256=59fcede3e3cc587755916ceed29e3c33748cd1aa7d2f91828ac83e7979d935e8 (glob)
293 .hg/store/00changelog-????????.nd: size=121088, sha256=59fcede3e3cc587755916ceed29e3c33748cd1aa7d2f91828ac83e7979d935e8 (glob)
294 #endif
294 #endif
295
295
296 Test force warming the cache
296 Test force warming the cache
297
297
298 $ rm .hg/store/00changelog.n
298 $ rm .hg/store/00changelog.n
299 $ hg debugnodemap --metadata
299 $ hg debugnodemap --metadata
300 $ hg debugupdatecache
300 $ hg debugupdatecache
301 #if pure
301 #if pure
302 $ hg debugnodemap --metadata
302 $ hg debugnodemap --metadata
303 uid: ???????? (glob)
303 uid: ???????? (glob)
304 tip-rev: 5002
304 tip-rev: 5002
305 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
305 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
306 data-length: 121088
306 data-length: 121088
307 data-unused: 0
307 data-unused: 0
308 data-unused: 0.000%
308 data-unused: 0.000%
309 #else
309 #else
310 $ hg debugnodemap --metadata
310 $ hg debugnodemap --metadata
311 uid: ???????? (glob)
311 uid: ???????? (glob)
312 tip-rev: 5002
312 tip-rev: 5002
313 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
313 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
314 data-length: 121088
314 data-length: 121088
315 data-unused: 0
315 data-unused: 0
316 data-unused: 0.000%
316 data-unused: 0.000%
317 #endif
317 #endif
318
318
319 Check out of sync nodemap
319 Check out of sync nodemap
320 =========================
320 =========================
321
321
322 First copy old data on the side.
322 First copy old data on the side.
323
323
324 $ mkdir ../tmp-copies
324 $ mkdir ../tmp-copies
325 $ cp .hg/store/00changelog-????????.nd .hg/store/00changelog.n ../tmp-copies
325 $ cp .hg/store/00changelog-????????.nd .hg/store/00changelog.n ../tmp-copies
326
326
327 Nodemap lagging behind
327 Nodemap lagging behind
328 ----------------------
328 ----------------------
329
329
330 make a new commit
330 make a new commit
331
331
332 $ echo bar2 > bar
332 $ echo bar2 > bar
333 $ hg ci -m 'bar2'
333 $ hg ci -m 'bar2'
334 $ NODE=`hg log -r tip -T '{node}\n'`
334 $ NODE=`hg log -r tip -T '{node}\n'`
335 $ hg log -r "$NODE" -T '{rev}\n'
335 $ hg log -r "$NODE" -T '{rev}\n'
336 5003
336 5003
337
337
338 If the nodemap is lagging behind, it can catch up fine
338 If the nodemap is lagging behind, it can catch up fine
339
339
340 $ hg debugnodemap --metadata
340 $ hg debugnodemap --metadata
341 uid: ???????? (glob)
341 uid: ???????? (glob)
342 tip-rev: 5003
342 tip-rev: 5003
343 tip-node: c9329770f979ade2d16912267c38ba5f82fd37b3
343 tip-node: c9329770f979ade2d16912267c38ba5f82fd37b3
344 data-length: 121344 (pure !)
344 data-length: 121344 (pure !)
345 data-length: 121344 (rust !)
345 data-length: 121344 (rust !)
346 data-length: 121152 (no-rust no-pure !)
346 data-length: 121152 (no-rust no-pure !)
347 data-unused: 192 (pure !)
347 data-unused: 192 (pure !)
348 data-unused: 192 (rust !)
348 data-unused: 192 (rust !)
349 data-unused: 0 (no-rust no-pure !)
349 data-unused: 0 (no-rust no-pure !)
350 data-unused: 0.158% (pure !)
350 data-unused: 0.158% (pure !)
351 data-unused: 0.158% (rust !)
351 data-unused: 0.158% (rust !)
352 data-unused: 0.000% (no-rust no-pure !)
352 data-unused: 0.000% (no-rust no-pure !)
353 $ cp -f ../tmp-copies/* .hg/store/
353 $ cp -f ../tmp-copies/* .hg/store/
354 $ hg debugnodemap --metadata
354 $ hg debugnodemap --metadata
355 uid: ???????? (glob)
355 uid: ???????? (glob)
356 tip-rev: 5002
356 tip-rev: 5002
357 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
357 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
358 data-length: 121088
358 data-length: 121088
359 data-unused: 0
359 data-unused: 0
360 data-unused: 0.000%
360 data-unused: 0.000%
361 $ hg log -r "$NODE" -T '{rev}\n'
361 $ hg log -r "$NODE" -T '{rev}\n'
362 5003
362 5003
363
363
364 changelog altered
364 changelog altered
365 -----------------
365 -----------------
366
366
367 If the nodemap is not gated behind a requirements, an unaware client can alter
367 If the nodemap is not gated behind a requirements, an unaware client can alter
368 the repository so the revlog used to generate the nodemap is not longer
368 the repository so the revlog used to generate the nodemap is not longer
369 compatible with the persistent nodemap. We need to detect that.
369 compatible with the persistent nodemap. We need to detect that.
370
370
371 $ hg up "$NODE~5"
371 $ hg up "$NODE~5"
372 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
372 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
373 $ echo bar > babar
373 $ echo bar > babar
374 $ hg add babar
374 $ hg add babar
375 $ hg ci -m 'babar'
375 $ hg ci -m 'babar'
376 created new head
376 created new head
377 $ OTHERNODE=`hg log -r tip -T '{node}\n'`
377 $ OTHERNODE=`hg log -r tip -T '{node}\n'`
378 $ hg log -r "$OTHERNODE" -T '{rev}\n'
378 $ hg log -r "$OTHERNODE" -T '{rev}\n'
379 5004
379 5004
380
380
381 $ hg --config extensions.strip= strip --rev "$NODE~1" --no-backup
381 $ hg --config extensions.strip= strip --rev "$NODE~1" --no-backup
382
382
383 the nodemap should detect the changelog have been tampered with and recover.
383 the nodemap should detect the changelog have been tampered with and recover.
384
384
385 $ hg debugnodemap --metadata
385 $ hg debugnodemap --metadata
386 uid: ???????? (glob)
386 uid: ???????? (glob)
387 tip-rev: 5002
387 tip-rev: 5002
388 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
388 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
389 data-length: 121536 (pure !)
389 data-length: 121536 (pure !)
390 data-length: 121088 (rust !)
390 data-length: 121088 (rust !)
391 data-length: 121088 (no-pure no-rust !)
391 data-length: 121088 (no-pure no-rust !)
392 data-unused: 448 (pure !)
392 data-unused: 448 (pure !)
393 data-unused: 0 (rust !)
393 data-unused: 0 (rust !)
394 data-unused: 0 (no-pure no-rust !)
394 data-unused: 0 (no-pure no-rust !)
395 data-unused: 0.000% (rust !)
395 data-unused: 0.000% (rust !)
396 data-unused: 0.369% (pure !)
396 data-unused: 0.369% (pure !)
397 data-unused: 0.000% (no-pure no-rust !)
397 data-unused: 0.000% (no-pure no-rust !)
398
398
399 $ cp -f ../tmp-copies/* .hg/store/
399 $ cp -f ../tmp-copies/* .hg/store/
400 $ hg debugnodemap --metadata
400 $ hg debugnodemap --metadata
401 uid: ???????? (glob)
401 uid: ???????? (glob)
402 tip-rev: 5002
402 tip-rev: 5002
403 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
403 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
404 data-length: 121088
404 data-length: 121088
405 data-unused: 0
405 data-unused: 0
406 data-unused: 0.000%
406 data-unused: 0.000%
407 $ hg log -r "$OTHERNODE" -T '{rev}\n'
407 $ hg log -r "$OTHERNODE" -T '{rev}\n'
408 5002
408 5002
409
409
410 missing data file
410 missing data file
411 -----------------
411 -----------------
412
412
413 $ UUID=`hg debugnodemap --metadata| grep 'uid:' | \
413 $ UUID=`hg debugnodemap --metadata| grep 'uid:' | \
414 > sed 's/uid: //'`
414 > sed 's/uid: //'`
415 $ FILE=.hg/store/00changelog-"${UUID}".nd
415 $ FILE=.hg/store/00changelog-"${UUID}".nd
416 $ mv $FILE ../tmp-data-file
416 $ mv $FILE ../tmp-data-file
417 $ cp .hg/store/00changelog.n ../tmp-docket
417 $ cp .hg/store/00changelog.n ../tmp-docket
418
418
419 mercurial don't crash
419 mercurial don't crash
420
420
421 $ hg log -r .
421 $ hg log -r .
422 changeset: 5002:b355ef8adce0
422 changeset: 5002:b355ef8adce0
423 tag: tip
423 tag: tip
424 parent: 4998:d918ad6d18d3
424 parent: 4998:d918ad6d18d3
425 user: test
425 user: test
426 date: Thu Jan 01 00:00:00 1970 +0000
426 date: Thu Jan 01 00:00:00 1970 +0000
427 summary: babar
427 summary: babar
428
428
429 $ hg debugnodemap --metadata
429 $ hg debugnodemap --metadata
430
430
431 $ hg debugupdatecache
431 $ hg debugupdatecache
432 $ hg debugnodemap --metadata
432 $ hg debugnodemap --metadata
433 uid: * (glob)
433 uid: * (glob)
434 tip-rev: 5002
434 tip-rev: 5002
435 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
435 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
436 data-length: 121088
436 data-length: 121088
437 data-unused: 0
437 data-unused: 0
438 data-unused: 0.000%
438 data-unused: 0.000%
439 $ mv ../tmp-data-file $FILE
439 $ mv ../tmp-data-file $FILE
440 $ mv ../tmp-docket .hg/store/00changelog.n
440 $ mv ../tmp-docket .hg/store/00changelog.n
441
441
442 Check transaction related property
442 Check transaction related property
443 ==================================
443 ==================================
444
444
445 An up to date nodemap should be available to shell hooks,
445 An up to date nodemap should be available to shell hooks,
446
446
447 $ echo dsljfl > a
447 $ echo dsljfl > a
448 $ hg add a
448 $ hg add a
449 $ hg ci -m a
449 $ hg ci -m a
450 $ hg debugnodemap --metadata
450 $ hg debugnodemap --metadata
451 uid: ???????? (glob)
451 uid: ???????? (glob)
452 tip-rev: 5003
452 tip-rev: 5003
453 tip-node: a52c5079765b5865d97b993b303a18740113bbb2
453 tip-node: a52c5079765b5865d97b993b303a18740113bbb2
454 data-length: 121088
454 data-length: 121088
455 data-unused: 0
455 data-unused: 0
456 data-unused: 0.000%
456 data-unused: 0.000%
457 $ echo babar2 > babar
457 $ echo babar2 > babar
458 $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap --metadata"
458 $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap --metadata"
459 uid: ???????? (glob)
459 uid: ???????? (glob)
460 tip-rev: 5004
460 tip-rev: 5004
461 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
461 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
462 data-length: 121280 (pure !)
462 data-length: 121280 (pure !)
463 data-length: 121280 (rust !)
463 data-length: 121280 (rust !)
464 data-length: 121088 (no-pure no-rust !)
464 data-length: 121088 (no-pure no-rust !)
465 data-unused: 192 (pure !)
465 data-unused: 192 (pure !)
466 data-unused: 192 (rust !)
466 data-unused: 192 (rust !)
467 data-unused: 0 (no-pure no-rust !)
467 data-unused: 0 (no-pure no-rust !)
468 data-unused: 0.158% (pure !)
468 data-unused: 0.158% (pure !)
469 data-unused: 0.158% (rust !)
469 data-unused: 0.158% (rust !)
470 data-unused: 0.000% (no-pure no-rust !)
470 data-unused: 0.000% (no-pure no-rust !)
471 $ hg debugnodemap --metadata
471 $ hg debugnodemap --metadata
472 uid: ???????? (glob)
472 uid: ???????? (glob)
473 tip-rev: 5004
473 tip-rev: 5004
474 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
474 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
475 data-length: 121280 (pure !)
475 data-length: 121280 (pure !)
476 data-length: 121280 (rust !)
476 data-length: 121280 (rust !)
477 data-length: 121088 (no-pure no-rust !)
477 data-length: 121088 (no-pure no-rust !)
478 data-unused: 192 (pure !)
478 data-unused: 192 (pure !)
479 data-unused: 192 (rust !)
479 data-unused: 192 (rust !)
480 data-unused: 0 (no-pure no-rust !)
480 data-unused: 0 (no-pure no-rust !)
481 data-unused: 0.158% (pure !)
481 data-unused: 0.158% (pure !)
482 data-unused: 0.158% (rust !)
482 data-unused: 0.158% (rust !)
483 data-unused: 0.000% (no-pure no-rust !)
483 data-unused: 0.000% (no-pure no-rust !)
484
484
485 Another process does not see the pending nodemap content during run.
485 Another process does not see the pending nodemap content during run.
486
486
487 $ echo qpoasp > a
487 $ echo qpoasp > a
488 $ hg ci -m a2 \
488 $ hg ci -m a2 \
489 > --config "hooks.pretxnclose=sh \"$RUNTESTDIR/testlib/wait-on-file\" 20 sync-repo-read sync-txn-pending" \
489 > --config "hooks.pretxnclose=sh \"$RUNTESTDIR/testlib/wait-on-file\" 20 sync-repo-read sync-txn-pending" \
490 > --config "hooks.txnclose=touch sync-txn-close" > output.txt 2>&1 &
490 > --config "hooks.txnclose=touch sync-txn-close" > output.txt 2>&1 &
491
491
492 (read the repository while the commit transaction is pending)
492 (read the repository while the commit transaction is pending)
493
493
494 $ sh "$RUNTESTDIR/testlib/wait-on-file" 20 sync-txn-pending && \
494 $ sh "$RUNTESTDIR/testlib/wait-on-file" 20 sync-txn-pending && \
495 > hg debugnodemap --metadata && \
495 > hg debugnodemap --metadata && \
496 > sh "$RUNTESTDIR/testlib/wait-on-file" 20 sync-txn-close sync-repo-read
496 > sh "$RUNTESTDIR/testlib/wait-on-file" 20 sync-txn-close sync-repo-read
497 uid: ???????? (glob)
497 uid: ???????? (glob)
498 tip-rev: 5004
498 tip-rev: 5004
499 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
499 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
500 data-length: 121280 (pure !)
500 data-length: 121280 (pure !)
501 data-length: 121280 (rust !)
501 data-length: 121280 (rust !)
502 data-length: 121088 (no-pure no-rust !)
502 data-length: 121088 (no-pure no-rust !)
503 data-unused: 192 (pure !)
503 data-unused: 192 (pure !)
504 data-unused: 192 (rust !)
504 data-unused: 192 (rust !)
505 data-unused: 0 (no-pure no-rust !)
505 data-unused: 0 (no-pure no-rust !)
506 data-unused: 0.158% (pure !)
506 data-unused: 0.158% (pure !)
507 data-unused: 0.158% (rust !)
507 data-unused: 0.158% (rust !)
508 data-unused: 0.000% (no-pure no-rust !)
508 data-unused: 0.000% (no-pure no-rust !)
509 $ hg debugnodemap --metadata
509 $ hg debugnodemap --metadata
510 uid: ???????? (glob)
510 uid: ???????? (glob)
511 tip-rev: 5005
511 tip-rev: 5005
512 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
512 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
513 data-length: 121536 (pure !)
513 data-length: 121536 (pure !)
514 data-length: 121536 (rust !)
514 data-length: 121536 (rust !)
515 data-length: 121088 (no-pure no-rust !)
515 data-length: 121088 (no-pure no-rust !)
516 data-unused: 448 (pure !)
516 data-unused: 448 (pure !)
517 data-unused: 448 (rust !)
517 data-unused: 448 (rust !)
518 data-unused: 0 (no-pure no-rust !)
518 data-unused: 0 (no-pure no-rust !)
519 data-unused: 0.369% (pure !)
519 data-unused: 0.369% (pure !)
520 data-unused: 0.369% (rust !)
520 data-unused: 0.369% (rust !)
521 data-unused: 0.000% (no-pure no-rust !)
521 data-unused: 0.000% (no-pure no-rust !)
522
522
523 $ cat output.txt
523 $ cat output.txt
524
524
525 Check that a failing transaction will properly revert the data
525 Check that a failing transaction will properly revert the data
526
526
527 $ echo plakfe > a
527 $ echo plakfe > a
528 $ f --size --sha256 .hg/store/00changelog-*.nd
528 $ f --size --sha256 .hg/store/00changelog-*.nd
529 .hg/store/00changelog-????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
529 .hg/store/00changelog-????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
530 .hg/store/00changelog-????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
530 .hg/store/00changelog-????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
531 .hg/store/00changelog-????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
531 .hg/store/00changelog-????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
532 $ hg ci -m a3 --config "extensions.abort=$RUNTESTDIR/testlib/crash_transaction_late.py"
532 $ hg ci -m a3 --config "extensions.abort=$RUNTESTDIR/testlib/crash_transaction_late.py"
533 transaction abort!
533 transaction abort!
534 rollback completed
534 rollback completed
535 abort: This is a late abort
535 abort: This is a late abort
536 [255]
536 [255]
537 $ hg debugnodemap --metadata
537 $ hg debugnodemap --metadata
538 uid: ???????? (glob)
538 uid: ???????? (glob)
539 tip-rev: 5005
539 tip-rev: 5005
540 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
540 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
541 data-length: 121536 (pure !)
541 data-length: 121536 (pure !)
542 data-length: 121536 (rust !)
542 data-length: 121536 (rust !)
543 data-length: 121088 (no-pure no-rust !)
543 data-length: 121088 (no-pure no-rust !)
544 data-unused: 448 (pure !)
544 data-unused: 448 (pure !)
545 data-unused: 448 (rust !)
545 data-unused: 448 (rust !)
546 data-unused: 0 (no-pure no-rust !)
546 data-unused: 0 (no-pure no-rust !)
547 data-unused: 0.369% (pure !)
547 data-unused: 0.369% (pure !)
548 data-unused: 0.369% (rust !)
548 data-unused: 0.369% (rust !)
549 data-unused: 0.000% (no-pure no-rust !)
549 data-unused: 0.000% (no-pure no-rust !)
550 $ f --size --sha256 .hg/store/00changelog-*.nd
550 $ f --size --sha256 .hg/store/00changelog-*.nd
551 .hg/store/00changelog-????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
551 .hg/store/00changelog-????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
552 .hg/store/00changelog-????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
552 .hg/store/00changelog-????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
553 .hg/store/00changelog-????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
553 .hg/store/00changelog-????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
554
554
555 Check that removing content does not confuse the nodemap
555 Check that removing content does not confuse the nodemap
556 --------------------------------------------------------
556 --------------------------------------------------------
557
557
558 removing data with rollback
558 removing data with rollback
559
559
560 $ echo aso > a
560 $ echo aso > a
561 $ hg ci -m a4
561 $ hg ci -m a4
562 $ hg rollback
562 $ hg rollback
563 repository tip rolled back to revision 5005 (undo commit)
563 repository tip rolled back to revision 5005 (undo commit)
564 working directory now based on revision 5005
564 working directory now based on revision 5005
565 $ hg id -r .
565 $ hg id -r .
566 90d5d3ba2fc4 tip
566 90d5d3ba2fc4 tip
567
567
568 removing data with strip
568 removing data with strip
569
569
570 $ echo aso > a
570 $ echo aso > a
571 $ hg ci -m a4
571 $ hg ci -m a4
572 $ hg --config extensions.strip= strip -r . --no-backup
572 $ hg --config extensions.strip= strip -r . --no-backup
573 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
573 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
574 $ hg id -r . --traceback
574 $ hg id -r . --traceback
575 90d5d3ba2fc4 tip
575 90d5d3ba2fc4 tip
576
576
577 (be a good citizen and regenerate the nodemap)
577 (be a good citizen and regenerate the nodemap)
578 $ hg debugupdatecaches
578 $ hg debugupdatecaches
579 $ hg debugnodemap --metadata
579 $ hg debugnodemap --metadata
580 uid: * (glob)
580 uid: * (glob)
581 tip-rev: 5005
581 tip-rev: 5005
582 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
582 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
583 data-length: 121088
583 data-length: 121088
584 data-unused: 0
584 data-unused: 0
585 data-unused: 0.000%
585 data-unused: 0.000%
586
586
587 Check race condition when multiple process write new data to the repository
587 Check race condition when multiple process write new data to the repository
588 ---------------------------------------------------------------------------
588 ---------------------------------------------------------------------------
589
589
590 In this test, we check that two writers touching the repositories will not
590 In this test, we check that two writers touching the repositories will not
591 overwrite each other data. This test is prompted by the existent of issue6554.
591 overwrite each other data. This test is prompted by the existent of issue6554.
592 Where a writer ended up using and outdated docket to update the repository. See
592 Where a writer ended up using and outdated docket to update the repository. See
593 the dedicated extension for details on the race windows and read/write schedule
593 the dedicated extension for details on the race windows and read/write schedule
594 necessary to end up in this situation: testlib/persistent-nodemap-race-ext.py
594 necessary to end up in this situation: testlib/persistent-nodemap-race-ext.py
595
595
596 The issue was initially observed on a server with a high push trafic, but it
596 The issue was initially observed on a server with a high push trafic, but it
597 can be reproduced using a share and two commiting process which seems simpler.
597 can be reproduced using a share and two commiting process which seems simpler.
598
598
599 The test is Rust only as the other implementation does not use the same
599 The test is Rust only as the other implementation does not use the same
600 read/write patterns.
600 read/write patterns.
601
601
602 $ cd ..
602 $ cd ..
603
603
604 #if rust
604 #if rust
605
605
606 $ cp -R test-repo race-repo
606 $ cp -R test-repo race-repo
607 $ hg share race-repo ./other-wc --config format.use-share-safe=yes
607 $ hg share race-repo ./other-wc --config format.use-share-safe=yes
608 updating working directory
608 updating working directory
609 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
609 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
610 $ hg debugformat -R ./race-repo | egrep 'share-safe|persistent-nodemap'
610 $ hg debugformat -R ./race-repo | egrep 'share-safe|persistent-nodemap'
611 share-safe: yes
611 share-safe: yes
612 persistent-nodemap: yes
612 persistent-nodemap: yes
613 $ hg debugformat -R ./other-wc/ | egrep 'share-safe|persistent-nodemap'
613 $ hg debugformat -R ./other-wc/ | egrep 'share-safe|persistent-nodemap'
614 share-safe: yes
614 share-safe: yes
615 persistent-nodemap: yes
615 persistent-nodemap: yes
616 $ hg -R ./other-wc update 'min(head())'
616 $ hg -R ./other-wc update 'min(head())'
617 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
617 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
618 $ hg -R ./race-repo debugnodemap --metadata
618 $ hg -R ./race-repo debugnodemap --metadata
619 uid: 43c37dde
619 uid: 43c37dde
620 tip-rev: 5005
620 tip-rev: 5005
621 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
621 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
622 data-length: 121088
622 data-length: 121088
623 data-unused: 0
623 data-unused: 0
624 data-unused: 0.000%
624 data-unused: 0.000%
625 $ hg -R ./race-repo log -G -r 'head()'
625 $ hg -R ./race-repo log -G -r 'head()'
626 @ changeset: 5005:90d5d3ba2fc4
626 @ changeset: 5005:90d5d3ba2fc4
627 | tag: tip
627 | tag: tip
628 ~ user: test
628 ~ user: test
629 date: Thu Jan 01 00:00:00 1970 +0000
629 date: Thu Jan 01 00:00:00 1970 +0000
630 summary: a2
630 summary: a2
631
631
632 o changeset: 5001:16395c3cf7e2
632 o changeset: 5001:16395c3cf7e2
633 | user: test
633 | user: test
634 ~ date: Thu Jan 01 00:00:00 1970 +0000
634 ~ date: Thu Jan 01 00:00:00 1970 +0000
635 summary: foo
635 summary: foo
636
636
637 $ hg -R ./other-wc log -G -r 'head()'
637 $ hg -R ./other-wc log -G -r 'head()'
638 o changeset: 5005:90d5d3ba2fc4
638 o changeset: 5005:90d5d3ba2fc4
639 | tag: tip
639 | tag: tip
640 ~ user: test
640 ~ user: test
641 date: Thu Jan 01 00:00:00 1970 +0000
641 date: Thu Jan 01 00:00:00 1970 +0000
642 summary: a2
642 summary: a2
643
643
644 @ changeset: 5001:16395c3cf7e2
644 @ changeset: 5001:16395c3cf7e2
645 | user: test
645 | user: test
646 ~ date: Thu Jan 01 00:00:00 1970 +0000
646 ~ date: Thu Jan 01 00:00:00 1970 +0000
647 summary: foo
647 summary: foo
648
648
649 $ echo left-side-race > race-repo/left-side-race
649 $ echo left-side-race > race-repo/left-side-race
650 $ hg -R ./race-repo/ add race-repo/left-side-race
650 $ hg -R ./race-repo/ add race-repo/left-side-race
651
651
652 $ echo right-side-race > ./other-wc/right-side-race
652 $ echo right-side-race > ./other-wc/right-side-race
653 $ hg -R ./other-wc/ add ./other-wc/right-side-race
653 $ hg -R ./other-wc/ add ./other-wc/right-side-race
654
654
655 $ mkdir sync-files
655 $ mkdir sync-files
656 $ mkdir outputs
656 $ mkdir outputs
657 $ (
657 $ (
658 > hg -R ./race-repo/ commit -m left-side-commit \
658 > hg -R ./race-repo/ commit -m left-side-commit \
659 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
659 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
660 > --config 'devel.nodemap-race.role=left';
660 > --config 'devel.nodemap-race.role=left';
661 > touch sync-files/left-done
661 > touch sync-files/left-done
662 > ) > outputs/left.txt 2>&1 &
662 > ) > outputs/left.txt 2>&1 &
663 $ (
663 $ (
664 > hg -R ./other-wc/ commit -m right-side-commit \
664 > hg -R ./other-wc/ commit -m right-side-commit \
665 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
665 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
666 > --config 'devel.nodemap-race.role=right';
666 > --config 'devel.nodemap-race.role=right';
667 > touch sync-files/right-done
667 > touch sync-files/right-done
668 > ) > outputs/right.txt 2>&1 &
668 > ) > outputs/right.txt 2>&1 &
669 $ (
669 $ (
670 > hg -R ./race-repo/ check-nodemap-race \
670 > hg -R ./race-repo/ check-nodemap-race \
671 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
671 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
672 > --config 'devel.nodemap-race.role=reader';
672 > --config 'devel.nodemap-race.role=reader';
673 > touch sync-files/reader-done
673 > touch sync-files/reader-done
674 > ) > outputs/reader.txt 2>&1 &
674 > ) > outputs/reader.txt 2>&1 &
675 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/left-done
675 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/left-done
676 $ cat outputs/left.txt
676 $ cat outputs/left.txt
677 docket-details:
677 docket-details:
678 uid: 43c37dde
678 uid: 43c37dde
679 actual-tip: 5005
679 actual-tip: 5005
680 tip-rev: 5005
680 tip-rev: 5005
681 data-length: 121088
681 data-length: 121088
682 nodemap-race: left side locked and ready to commit
682 nodemap-race: left side locked and ready to commit
683 docket-details:
683 docket-details:
684 uid: 43c37dde
684 uid: 43c37dde
685 actual-tip: 5005
685 actual-tip: 5005
686 tip-rev: 5005
686 tip-rev: 5005
687 data-length: 121088
687 data-length: 121088
688 finalized changelog write
688 finalized changelog write
689 persisting changelog nodemap
689 persisting changelog nodemap
690 new data start at 121088
690 new data start at 121088
691 persisted changelog nodemap
691 persisted changelog nodemap
692 docket-details:
692 docket-details:
693 uid: 43c37dde
693 uid: 43c37dde
694 actual-tip: 5006
694 actual-tip: 5006
695 tip-rev: 5006
695 tip-rev: 5006
696 data-length: 121280
696 data-length: 121280
697 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/right-done
697 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/right-done
698 $ cat outputs/right.txt
698 $ cat outputs/right.txt
699 nodemap-race: right side start of the locking sequence
699 nodemap-race: right side start of the locking sequence
700 nodemap-race: right side reading changelog
700 nodemap-race: right side reading changelog
701 nodemap-race: right side reading of changelog is done
701 nodemap-race: right side reading of changelog is done
702 docket-details:
702 docket-details:
703 uid: 43c37dde
703 uid: 43c37dde
704 actual-tip: 5006
704 actual-tip: 5006
705 tip-rev: 5005
705 tip-rev: 5005
706 data-length: 121088
706 data-length: 121088
707 nodemap-race: right side ready to wait for the lock
707 nodemap-race: right side ready to wait for the lock
708 nodemap-race: right side locked and ready to commit
708 nodemap-race: right side locked and ready to commit
709 docket-details:
709 docket-details:
710 uid: 43c37dde
710 uid: 43c37dde
711 actual-tip: 5006
711 actual-tip: 5006
712 tip-rev: 5006
712 tip-rev: 5006
713 data-length: 121280
713 data-length: 121280
714 right ready to write, waiting for reader
714 right ready to write, waiting for reader
715 right proceeding with writing its changelog index and nodemap
715 right proceeding with writing its changelog index and nodemap
716 finalized changelog write
716 finalized changelog write
717 persisting changelog nodemap
717 persisting changelog nodemap
718 new data start at 121280
718 new data start at 121280
719 persisted changelog nodemap
719 persisted changelog nodemap
720 docket-details:
720 docket-details:
721 uid: 43c37dde
721 uid: 43c37dde
722 actual-tip: 5007
722 actual-tip: 5007
723 tip-rev: 5007
723 tip-rev: 5007
724 data-length: 121536
724 data-length: 121536
725 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/reader-done
725 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/reader-done
726 $ cat outputs/reader.txt
726 $ cat outputs/reader.txt
727 reader: reading changelog
727 reader: reading changelog
728 reader ready to read the changelog, waiting for right
728 reader ready to read the changelog, waiting for right
729 reader: nodemap docket read
729 reader: nodemap docket read
730 record-data-length: 121280
730 record-data-length: 121280
731 actual-data-length: 121280
731 actual-data-length: 121280
732 file-actual-length: 121536
732 file-actual-length: 121536
733 reader: changelog read
733 reader: changelog read
734 docket-details:
734 docket-details:
735 uid: 43c37dde
735 uid: 43c37dde
736 actual-tip: 5006
736 actual-tip: 5006
737 tip-rev: 5006
737 tip-rev: 5006
738 data-length: 121280
738 data-length: 121280
739 tip-rev: 5006
739 tip-rev: 5006
740 tip-node: 492901161367
740 tip-node: 492901161367
741 node-rev: 5006
741 node-rev: 5006
742
742
743 $ hg -R ./race-repo log -G -r 'head()'
743 $ hg -R ./race-repo log -G -r 'head()'
744 o changeset: 5007:ac4a2abde241
744 o changeset: 5007:ac4a2abde241
745 | tag: tip
745 | tag: tip
746 ~ parent: 5001:16395c3cf7e2
746 ~ parent: 5001:16395c3cf7e2
747 user: test
747 user: test
748 date: Thu Jan 01 00:00:00 1970 +0000
748 date: Thu Jan 01 00:00:00 1970 +0000
749 summary: right-side-commit
749 summary: right-side-commit
750
750
751 @ changeset: 5006:492901161367
751 @ changeset: 5006:492901161367
752 | user: test
752 | user: test
753 ~ date: Thu Jan 01 00:00:00 1970 +0000
753 ~ date: Thu Jan 01 00:00:00 1970 +0000
754 summary: left-side-commit
754 summary: left-side-commit
755
755
756 $ hg -R ./other-wc log -G -r 'head()'
756 $ hg -R ./other-wc log -G -r 'head()'
757 @ changeset: 5007:ac4a2abde241
757 @ changeset: 5007:ac4a2abde241
758 | tag: tip
758 | tag: tip
759 ~ parent: 5001:16395c3cf7e2
759 ~ parent: 5001:16395c3cf7e2
760 user: test
760 user: test
761 date: Thu Jan 01 00:00:00 1970 +0000
761 date: Thu Jan 01 00:00:00 1970 +0000
762 summary: right-side-commit
762 summary: right-side-commit
763
763
764 o changeset: 5006:492901161367
764 o changeset: 5006:492901161367
765 | user: test
765 | user: test
766 ~ date: Thu Jan 01 00:00:00 1970 +0000
766 ~ date: Thu Jan 01 00:00:00 1970 +0000
767 summary: left-side-commit
767 summary: left-side-commit
768
768
769 #endif
769 #endif
770
770
771 Test upgrade / downgrade
771 Test upgrade / downgrade
772 ========================
772 ========================
773
773
774 $ cd ./test-repo/
774 $ cd ./test-repo/
775
775
776 downgrading
776 downgrading
777
777
778 $ cat << EOF >> .hg/hgrc
778 $ cat << EOF >> .hg/hgrc
779 > [format]
779 > [format]
780 > use-persistent-nodemap=no
780 > use-persistent-nodemap=no
781 > EOF
781 > EOF
782 $ hg debugformat -v
782 $ hg debugformat -v
783 format-variant repo config default
783 format-variant repo config default
784 fncache: yes yes yes
784 fncache: yes yes yes
785 dirstate-v2: no no no
785 dirstate-v2: no no no
786 tracked-hint: no no no
786 tracked-hint: no no no
787 dotencode: yes yes yes
787 dotencode: yes yes yes
788 generaldelta: yes yes yes
788 generaldelta: yes yes yes
789 share-safe: yes yes yes
789 share-safe: yes yes yes
790 sparserevlog: yes yes yes
790 sparserevlog: yes yes yes
791 persistent-nodemap: yes no no
791 persistent-nodemap: yes no no
792 copies-sdc: no no no
792 copies-sdc: no no no
793 revlog-v2: no no no
793 revlog-v2: no no no
794 changelog-v2: no no no
794 changelog-v2: no no no
795 plain-cl-delta: yes yes yes
795 plain-cl-delta: yes yes yes
796 compression: zlib zlib zlib (no-zstd !)
796 compression: zlib zlib zlib (no-zstd !)
797 compression: zstd zstd zstd (zstd !)
797 compression: zstd zstd zstd (zstd !)
798 compression-level: default default default
798 compression-level: default default default
799 $ hg debugupgraderepo --run --no-backup --quiet
799 $ hg debugupgraderepo --run --no-backup --quiet
800 upgrade will perform the following actions:
800 upgrade will perform the following actions:
801
801
802 requirements
802 requirements
803 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
803 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
804 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
804 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
805 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
805 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
806 removed: persistent-nodemap
806 removed: persistent-nodemap
807
807
808 processed revlogs:
808 processed revlogs:
809 - all-filelogs
809 - all-filelogs
810 - changelog
810 - changelog
811 - manifest
811 - manifest
812
812
813 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
813 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
814 [1]
814 [1]
815 $ hg debugnodemap --metadata
815 $ hg debugnodemap --metadata
816
816
817
817
818 upgrading
818 upgrading
819
819
820 $ cat << EOF >> .hg/hgrc
820 $ cat << EOF >> .hg/hgrc
821 > [format]
821 > [format]
822 > use-persistent-nodemap=yes
822 > use-persistent-nodemap=yes
823 > EOF
823 > EOF
824 $ hg debugformat -v
824 $ hg debugformat -v
825 format-variant repo config default
825 format-variant repo config default
826 fncache: yes yes yes
826 fncache: yes yes yes
827 dirstate-v2: no no no
827 dirstate-v2: no no no
828 tracked-hint: no no no
828 tracked-hint: no no no
829 dotencode: yes yes yes
829 dotencode: yes yes yes
830 generaldelta: yes yes yes
830 generaldelta: yes yes yes
831 share-safe: yes yes yes
831 share-safe: yes yes yes
832 sparserevlog: yes yes yes
832 sparserevlog: yes yes yes
833 persistent-nodemap: no yes no
833 persistent-nodemap: no yes no
834 copies-sdc: no no no
834 copies-sdc: no no no
835 revlog-v2: no no no
835 revlog-v2: no no no
836 changelog-v2: no no no
836 changelog-v2: no no no
837 plain-cl-delta: yes yes yes
837 plain-cl-delta: yes yes yes
838 compression: zlib zlib zlib (no-zstd !)
838 compression: zlib zlib zlib (no-zstd !)
839 compression: zstd zstd zstd (zstd !)
839 compression: zstd zstd zstd (zstd !)
840 compression-level: default default default
840 compression-level: default default default
841 $ hg debugupgraderepo --run --no-backup --quiet
841 $ hg debugupgraderepo --run --no-backup --quiet
842 upgrade will perform the following actions:
842 upgrade will perform the following actions:
843
843
844 requirements
844 requirements
845 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
845 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
846 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
846 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
847 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
847 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
848 added: persistent-nodemap
848 added: persistent-nodemap
849
849
850 processed revlogs:
850 processed revlogs:
851 - all-filelogs
851 - all-filelogs
852 - changelog
852 - changelog
853 - manifest
853 - manifest
854
854
855 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
855 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
856 00changelog-*.nd (glob)
856 00changelog-*.nd (glob)
857 00changelog.n
857 00changelog.n
858 00manifest-*.nd (glob)
858 00manifest-*.nd (glob)
859 00manifest.n
859 00manifest.n
860
860
861 $ hg debugnodemap --metadata
861 $ hg debugnodemap --metadata
862 uid: * (glob)
862 uid: * (glob)
863 tip-rev: 5005
863 tip-rev: 5005
864 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
864 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
865 data-length: 121088
865 data-length: 121088
866 data-unused: 0
866 data-unused: 0
867 data-unused: 0.000%
867 data-unused: 0.000%
868
868
869 Running unrelated upgrade
869 Running unrelated upgrade
870
870
871 $ hg debugupgraderepo --run --no-backup --quiet --optimize re-delta-all
871 $ hg debugupgraderepo --run --no-backup --quiet --optimize re-delta-all
872 upgrade will perform the following actions:
872 upgrade will perform the following actions:
873
873
874 requirements
874 requirements
875 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
875 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
876 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
876 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
877 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
877 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
878
878
879 optimisations: re-delta-all
879 optimisations: re-delta-all
880
880
881 processed revlogs:
881 processed revlogs:
882 - all-filelogs
882 - all-filelogs
883 - changelog
883 - changelog
884 - manifest
884 - manifest
885
885
886 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
886 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
887 00changelog-*.nd (glob)
887 00changelog-*.nd (glob)
888 00changelog.n
888 00changelog.n
889 00manifest-*.nd (glob)
889 00manifest-*.nd (glob)
890 00manifest.n
890 00manifest.n
891
891
892 $ hg debugnodemap --metadata
892 $ hg debugnodemap --metadata
893 uid: * (glob)
893 uid: * (glob)
894 tip-rev: 5005
894 tip-rev: 5005
895 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
895 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
896 data-length: 121088
896 data-length: 121088
897 data-unused: 0
897 data-unused: 0
898 data-unused: 0.000%
898 data-unused: 0.000%
899
899
900 Persistent nodemap and local/streaming clone
900 Persistent nodemap and local/streaming clone
901 ============================================
901 ============================================
902
902
903 $ cd ..
903 $ cd ..
904
904
905 standard clone
905 standard clone
906 --------------
906 --------------
907
907
908 The persistent nodemap should exist after a streaming clone
908 The persistent nodemap should exist after a streaming clone
909
909
910 $ hg clone --pull --quiet -U test-repo standard-clone
910 $ hg clone --pull --quiet -U test-repo standard-clone
911 $ ls -1 standard-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
911 $ ls -1 standard-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
912 00changelog-*.nd (glob)
912 00changelog-*.nd (glob)
913 00changelog.n
913 00changelog.n
914 00manifest-*.nd (glob)
914 00manifest-*.nd (glob)
915 00manifest.n
915 00manifest.n
916 $ hg -R standard-clone debugnodemap --metadata
916 $ hg -R standard-clone debugnodemap --metadata
917 uid: * (glob)
917 uid: * (glob)
918 tip-rev: 5005
918 tip-rev: 5005
919 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
919 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
920 data-length: 121088
920 data-length: 121088
921 data-unused: 0
921 data-unused: 0
922 data-unused: 0.000%
922 data-unused: 0.000%
923
923
924
924
925 local clone
925 local clone
926 ------------
926 ------------
927
927
928 The persistent nodemap should exist after a streaming clone
928 The persistent nodemap should exist after a streaming clone
929
929
930 $ hg clone -U test-repo local-clone
930 $ hg clone -U test-repo local-clone
931 $ ls -1 local-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
931 $ ls -1 local-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
932 00changelog-*.nd (glob)
932 00changelog-*.nd (glob)
933 00changelog.n
933 00changelog.n
934 00manifest-*.nd (glob)
934 00manifest-*.nd (glob)
935 00manifest.n
935 00manifest.n
936 $ hg -R local-clone debugnodemap --metadata
936 $ hg -R local-clone debugnodemap --metadata
937 uid: * (glob)
937 uid: * (glob)
938 tip-rev: 5005
938 tip-rev: 5005
939 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
939 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
940 data-length: 121088
940 data-length: 121088
941 data-unused: 0
941 data-unused: 0
942 data-unused: 0.000%
942 data-unused: 0.000%
943
943
944 Test various corruption case
944 Test various corruption case
945 ============================
945 ============================
946
946
947 Missing datafile
947 Missing datafile
948 ----------------
948 ----------------
949
949
950 Test behavior with a missing datafile
950 Test behavior with a missing datafile
951
951
952 $ hg clone --quiet --pull test-repo corruption-test-repo
952 $ hg clone --quiet --pull test-repo corruption-test-repo
953 $ ls -1 corruption-test-repo/.hg/store/00changelog*
953 $ ls -1 corruption-test-repo/.hg/store/00changelog*
954 corruption-test-repo/.hg/store/00changelog-*.nd (glob)
954 corruption-test-repo/.hg/store/00changelog-*.nd (glob)
955 corruption-test-repo/.hg/store/00changelog.d
955 corruption-test-repo/.hg/store/00changelog.d
956 corruption-test-repo/.hg/store/00changelog.i
956 corruption-test-repo/.hg/store/00changelog.i
957 corruption-test-repo/.hg/store/00changelog.n
957 corruption-test-repo/.hg/store/00changelog.n
958 $ rm corruption-test-repo/.hg/store/00changelog*.nd
958 $ rm corruption-test-repo/.hg/store/00changelog*.nd
959 $ hg log -R corruption-test-repo -r .
959 $ hg log -R corruption-test-repo -r .
960 changeset: 5005:90d5d3ba2fc4
960 changeset: 5005:90d5d3ba2fc4
961 tag: tip
961 tag: tip
962 user: test
962 user: test
963 date: Thu Jan 01 00:00:00 1970 +0000
963 date: Thu Jan 01 00:00:00 1970 +0000
964 summary: a2
964 summary: a2
965
965
966 $ ls -1 corruption-test-repo/.hg/store/00changelog*
966 $ ls -1 corruption-test-repo/.hg/store/00changelog*
967 corruption-test-repo/.hg/store/00changelog.d
967 corruption-test-repo/.hg/store/00changelog.d
968 corruption-test-repo/.hg/store/00changelog.i
968 corruption-test-repo/.hg/store/00changelog.i
969 corruption-test-repo/.hg/store/00changelog.n
969 corruption-test-repo/.hg/store/00changelog.n
970
970
971 Truncated data file
971 Truncated data file
972 -------------------
972 -------------------
973
973
974 Test behavior with a too short datafile
974 Test behavior with a too short datafile
975
975
976 rebuild the missing data
976 rebuild the missing data
977 $ hg -R corruption-test-repo debugupdatecache
977 $ hg -R corruption-test-repo debugupdatecache
978 $ ls -1 corruption-test-repo/.hg/store/00changelog*
978 $ ls -1 corruption-test-repo/.hg/store/00changelog*
979 corruption-test-repo/.hg/store/00changelog-*.nd (glob)
979 corruption-test-repo/.hg/store/00changelog-*.nd (glob)
980 corruption-test-repo/.hg/store/00changelog.d
980 corruption-test-repo/.hg/store/00changelog.d
981 corruption-test-repo/.hg/store/00changelog.i
981 corruption-test-repo/.hg/store/00changelog.i
982 corruption-test-repo/.hg/store/00changelog.n
982 corruption-test-repo/.hg/store/00changelog.n
983
983
984 truncate the file
984 truncate the file
985
985
986 $ datafilepath=`ls corruption-test-repo/.hg/store/00changelog*.nd`
986 $ datafilepath=`ls corruption-test-repo/.hg/store/00changelog*.nd`
987 $ f -s $datafilepath
987 $ f -s $datafilepath
988 corruption-test-repo/.hg/store/00changelog-*.nd: size=121088 (glob)
988 corruption-test-repo/.hg/store/00changelog-*.nd: size=121088 (glob)
989 $ dd if=$datafilepath bs=1000 count=10 of=$datafilepath-tmp
989 $ dd if=$datafilepath bs=1000 count=10 of=$datafilepath-tmp
990 10+0 records in
990 10+0 records in
991 10+0 records out
991 10+0 records out
992 * bytes * (glob)
992 * bytes * (glob)
993 $ mv $datafilepath-tmp $datafilepath
993 $ mv $datafilepath-tmp $datafilepath
994 $ f -s $datafilepath
994 $ f -s $datafilepath
995 corruption-test-repo/.hg/store/00changelog-*.nd: size=10000 (glob)
995 corruption-test-repo/.hg/store/00changelog-*.nd: size=10000 (glob)
996
996
997 Check that Mercurial reaction to this event
997 Check that Mercurial reaction to this event
998
998
999 $ hg -R corruption-test-repo log -r . --traceback
999 $ hg -R corruption-test-repo log -r . --traceback
1000 changeset: 5005:90d5d3ba2fc4
1000 changeset: 5005:90d5d3ba2fc4
1001 tag: tip
1001 tag: tip
1002 user: test
1002 user: test
1003 date: Thu Jan 01 00:00:00 1970 +0000
1003 date: Thu Jan 01 00:00:00 1970 +0000
1004 summary: a2
1004 summary: a2
1005
1005
1006
1006
1007
1007
1008 stream clone
1008 stream clone
1009 ============
1009 ============
1010
1010
1011 The persistent nodemap should exist after a streaming clone
1011 The persistent nodemap should exist after a streaming clone
1012
1012
1013 Simple case
1013 Simple case
1014 -----------
1014 -----------
1015
1015
1016 No race condition
1016 No race condition
1017
1017
1018 $ hg clone -U --stream ssh://user@dummy/test-repo stream-clone --debug | egrep '00(changelog|manifest)'
1018 $ hg clone -U --stream ssh://user@dummy/test-repo stream-clone --debug | egrep '00(changelog|manifest)'
1019 adding [s] 00manifest.n (62 bytes)
1019 adding [s] 00manifest.n (62 bytes)
1020 adding [s] 00manifest-*.nd (118 KB) (glob)
1020 adding [s] 00manifest-*.nd (118 KB) (glob)
1021 adding [s] 00changelog.n (62 bytes)
1021 adding [s] 00changelog.n (62 bytes)
1022 adding [s] 00changelog-*.nd (118 KB) (glob)
1022 adding [s] 00changelog-*.nd (118 KB) (glob)
1023 adding [s] 00manifest.d (452 KB) (no-zstd !)
1023 adding [s] 00manifest.d (452 KB) (no-zstd !)
1024 adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
1024 adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
1025 adding [s] 00manifest.d (492 KB) (zstd bigendian !)
1025 adding [s] 00manifest.d (492 KB) (zstd bigendian !)
1026 adding [s] 00changelog.d (360 KB) (no-zstd !)
1026 adding [s] 00changelog.d (360 KB) (no-zstd !)
1027 adding [s] 00changelog.d (368 KB) (zstd !)
1027 adding [s] 00changelog.d (368 KB) (zstd !)
1028 adding [s] 00manifest.i (313 KB)
1028 adding [s] 00manifest.i (313 KB)
1029 adding [s] 00changelog.i (313 KB)
1029 adding [s] 00changelog.i (313 KB)
1030 $ ls -1 stream-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
1030 $ ls -1 stream-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
1031 00changelog-*.nd (glob)
1031 00changelog-*.nd (glob)
1032 00changelog.n
1032 00changelog.n
1033 00manifest-*.nd (glob)
1033 00manifest-*.nd (glob)
1034 00manifest.n
1034 00manifest.n
1035 $ hg -R stream-clone debugnodemap --metadata
1035 $ hg -R stream-clone debugnodemap --metadata
1036 uid: * (glob)
1036 uid: * (glob)
1037 tip-rev: 5005
1037 tip-rev: 5005
1038 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1038 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1039 data-length: 121088
1039 data-length: 121088
1040 data-unused: 0
1040 data-unused: 0
1041 data-unused: 0.000%
1041 data-unused: 0.000%
1042
1042
1043 new data appened
1043 new data appened
1044 -----------------
1044 -----------------
1045
1045
1046 Other commit happening on the server during the stream clone
1046 Other commit happening on the server during the stream clone
1047
1047
1048 setup the step-by-step stream cloning
1048 setup the step-by-step stream cloning
1049
1049
1050 $ HG_TEST_STREAM_WALKED_FILE_1="$TESTTMP/sync_file_walked_1"
1050 $ HG_TEST_STREAM_WALKED_FILE_1="$TESTTMP/sync_file_walked_1"
1051 $ export HG_TEST_STREAM_WALKED_FILE_1
1051 $ export HG_TEST_STREAM_WALKED_FILE_1
1052 $ HG_TEST_STREAM_WALKED_FILE_2="$TESTTMP/sync_file_walked_2"
1052 $ HG_TEST_STREAM_WALKED_FILE_2="$TESTTMP/sync_file_walked_2"
1053 $ export HG_TEST_STREAM_WALKED_FILE_2
1053 $ export HG_TEST_STREAM_WALKED_FILE_2
1054 $ HG_TEST_STREAM_WALKED_FILE_3="$TESTTMP/sync_file_walked_3"
1054 $ HG_TEST_STREAM_WALKED_FILE_3="$TESTTMP/sync_file_walked_3"
1055 $ export HG_TEST_STREAM_WALKED_FILE_3
1055 $ export HG_TEST_STREAM_WALKED_FILE_3
1056 $ cat << EOF >> test-repo/.hg/hgrc
1056 $ cat << EOF >> test-repo/.hg/hgrc
1057 > [extensions]
1057 > [extensions]
1058 > steps=$RUNTESTDIR/testlib/ext-stream-clone-steps.py
1058 > steps=$RUNTESTDIR/testlib/ext-stream-clone-steps.py
1059 > EOF
1059 > EOF
1060
1060
1061 Check and record file state beforehand
1061 Check and record file state beforehand
1062
1062
1063 $ f --size test-repo/.hg/store/00changelog*
1063 $ f --size test-repo/.hg/store/00changelog*
1064 test-repo/.hg/store/00changelog-*.nd: size=121088 (glob)
1064 test-repo/.hg/store/00changelog-*.nd: size=121088 (glob)
1065 test-repo/.hg/store/00changelog.d: size=376891 (zstd no-bigendian !)
1065 test-repo/.hg/store/00changelog.d: size=376891 (zstd no-bigendian !)
1066 test-repo/.hg/store/00changelog.d: size=376889 (zstd bigendian !)
1066 test-repo/.hg/store/00changelog.d: size=376889 (zstd bigendian !)
1067 test-repo/.hg/store/00changelog.d: size=368890 (no-zstd !)
1067 test-repo/.hg/store/00changelog.d: size=368890 (no-zstd !)
1068 test-repo/.hg/store/00changelog.i: size=320384
1068 test-repo/.hg/store/00changelog.i: size=320384
1069 test-repo/.hg/store/00changelog.n: size=62
1069 test-repo/.hg/store/00changelog.n: size=62
1070 $ hg -R test-repo debugnodemap --metadata | tee server-metadata.txt
1070 $ hg -R test-repo debugnodemap --metadata | tee server-metadata.txt
1071 uid: * (glob)
1071 uid: * (glob)
1072 tip-rev: 5005
1072 tip-rev: 5005
1073 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1073 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1074 data-length: 121088
1074 data-length: 121088
1075 data-unused: 0
1075 data-unused: 0
1076 data-unused: 0.000%
1076 data-unused: 0.000%
1077
1077
1078 Prepare a commit
1078 Prepare a commit
1079
1079
1080 $ echo foo >> test-repo/foo
1080 $ echo foo >> test-repo/foo
1081 $ hg -R test-repo/ add test-repo/foo
1081 $ hg -R test-repo/ add test-repo/foo
1082
1082
1083 Do a mix of clone and commit at the same time so that the file listed on disk differ at actual transfer time.
1083 Do a mix of clone and commit at the same time so that the file listed on disk differ at actual transfer time.
1084
1084
1085 $ (hg clone -U --stream ssh://user@dummy/test-repo stream-clone-race-1 --debug 2>> clone-output | egrep '00(changelog|manifest)' >> clone-output; touch $HG_TEST_STREAM_WALKED_FILE_3) &
1085 $ (hg clone -U --stream ssh://user@dummy/test-repo stream-clone-race-1 --debug 2>> clone-output | egrep '00(changelog|manifest)' >> clone-output; touch $HG_TEST_STREAM_WALKED_FILE_3) &
1086 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_1
1086 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_1
1087 $ hg -R test-repo/ commit -m foo
1087 $ hg -R test-repo/ commit -m foo
1088 $ touch $HG_TEST_STREAM_WALKED_FILE_2
1088 $ touch $HG_TEST_STREAM_WALKED_FILE_2
1089 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_3
1089 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_3
1090 $ cat clone-output
1090 $ cat clone-output
1091 adding [s] 00manifest.n (62 bytes)
1091 adding [s] 00manifest.n (62 bytes)
1092 adding [s] 00manifest-*.nd (118 KB) (glob)
1092 adding [s] 00manifest-*.nd (118 KB) (glob)
1093 adding [s] 00changelog.n (62 bytes)
1093 adding [s] 00changelog.n (62 bytes)
1094 adding [s] 00changelog-*.nd (118 KB) (glob)
1094 adding [s] 00changelog-*.nd (118 KB) (glob)
1095 adding [s] 00manifest.d (452 KB) (no-zstd !)
1095 adding [s] 00manifest.d (452 KB) (no-zstd !)
1096 adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
1096 adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
1097 adding [s] 00manifest.d (492 KB) (zstd bigendian !)
1097 adding [s] 00manifest.d (492 KB) (zstd bigendian !)
1098 adding [s] 00changelog.d (360 KB) (no-zstd !)
1098 adding [s] 00changelog.d (360 KB) (no-zstd !)
1099 adding [s] 00changelog.d (368 KB) (zstd !)
1099 adding [s] 00changelog.d (368 KB) (zstd !)
1100 adding [s] 00manifest.i (313 KB)
1100 adding [s] 00manifest.i (313 KB)
1101 adding [s] 00changelog.i (313 KB)
1101 adding [s] 00changelog.i (313 KB)
1102
1102
1103 Check the result state
1103 Check the result state
1104
1104
1105 $ f --size stream-clone-race-1/.hg/store/00changelog*
1105 $ f --size stream-clone-race-1/.hg/store/00changelog*
1106 stream-clone-race-1/.hg/store/00changelog-*.nd: size=121088 (glob)
1106 stream-clone-race-1/.hg/store/00changelog-*.nd: size=121088 (glob)
1107 stream-clone-race-1/.hg/store/00changelog.d: size=368890 (no-zstd !)
1107 stream-clone-race-1/.hg/store/00changelog.d: size=368890 (no-zstd !)
1108 stream-clone-race-1/.hg/store/00changelog.d: size=376891 (zstd no-bigendian !)
1108 stream-clone-race-1/.hg/store/00changelog.d: size=376891 (zstd no-bigendian !)
1109 stream-clone-race-1/.hg/store/00changelog.d: size=376889 (zstd bigendian !)
1109 stream-clone-race-1/.hg/store/00changelog.d: size=376889 (zstd bigendian !)
1110 stream-clone-race-1/.hg/store/00changelog.i: size=320384
1110 stream-clone-race-1/.hg/store/00changelog.i: size=320384
1111 stream-clone-race-1/.hg/store/00changelog.n: size=62
1111 stream-clone-race-1/.hg/store/00changelog.n: size=62
1112
1112
1113 $ hg -R stream-clone-race-1 debugnodemap --metadata | tee client-metadata.txt
1113 $ hg -R stream-clone-race-1 debugnodemap --metadata | tee client-metadata.txt
1114 uid: * (glob)
1114 uid: * (glob)
1115 tip-rev: 5005
1115 tip-rev: 5005
1116 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1116 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1117 data-length: 121088
1117 data-length: 121088
1118 data-unused: 0
1118 data-unused: 0
1119 data-unused: 0.000%
1119 data-unused: 0.000%
1120
1120
1121 We get a usable nodemap, so no rewrite would be needed and the metadata should be identical
1121 We get a usable nodemap, so no rewrite would be needed and the metadata should be identical
1122 (ie: the following diff should be empty)
1122 (ie: the following diff should be empty)
1123
1123
1124 This isn't the case for the `no-rust` `no-pure` implementation as it use a very minimal nodemap implementation that unconditionnaly rewrite the nodemap "all the time".
1124 This isn't the case for the `no-rust` `no-pure` implementation as it use a very minimal nodemap implementation that unconditionnaly rewrite the nodemap "all the time".
1125
1125
1126 #if no-rust no-pure
1126 #if no-rust no-pure
1127 $ diff -u server-metadata.txt client-metadata.txt
1127 $ diff -u server-metadata.txt client-metadata.txt
1128 --- server-metadata.txt * (glob)
1128 --- server-metadata.txt * (glob)
1129 +++ client-metadata.txt * (glob)
1129 +++ client-metadata.txt * (glob)
1130 @@ -1,4 +1,4 @@
1130 @@ -1,4 +1,4 @@
1131 -uid: * (glob)
1131 -uid: * (glob)
1132 +uid: * (glob)
1132 +uid: * (glob)
1133 tip-rev: 5005
1133 tip-rev: 5005
1134 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1134 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1135 data-length: 121088
1135 data-length: 121088
1136 [1]
1136 [1]
1137 #else
1137 #else
1138 $ diff -u server-metadata.txt client-metadata.txt
1138 $ diff -u server-metadata.txt client-metadata.txt
1139 #endif
1139 #endif
1140
1140
1141
1141
1142 Clean up after the test.
1142 Clean up after the test.
1143
1143
1144 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_1"
1144 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_1"
1145 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_2"
1145 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_2"
1146 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_3"
1146 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_3"
1147
1147
1148 full regeneration
1148 full regeneration
1149 -----------------
1149 -----------------
1150
1150
1151 A full nodemap is generated
1151 A full nodemap is generated
1152
1152
1153 (ideally this test would append enough data to make sure the nodemap data file
1153 (ideally this test would append enough data to make sure the nodemap data file
1154 get changed, however to make thing simpler we will force the regeneration for
1154 get changed, however to make thing simpler we will force the regeneration for
1155 this test.
1155 this test.
1156
1156
1157 Check the initial state
1157 Check the initial state
1158
1158
1159 $ f --size test-repo/.hg/store/00changelog*
1159 $ f --size test-repo/.hg/store/00changelog*
1160 test-repo/.hg/store/00changelog-*.nd: size=121344 (glob) (rust !)
1160 test-repo/.hg/store/00changelog-*.nd: size=121344 (glob) (rust !)
1161 test-repo/.hg/store/00changelog-*.nd: size=121344 (glob) (pure !)
1161 test-repo/.hg/store/00changelog-*.nd: size=121344 (glob) (pure !)
1162 test-repo/.hg/store/00changelog-*.nd: size=121152 (glob) (no-rust no-pure !)
1162 test-repo/.hg/store/00changelog-*.nd: size=121152 (glob) (no-rust no-pure !)
1163 test-repo/.hg/store/00changelog.d: size=376950 (zstd no-bigendian !)
1163 test-repo/.hg/store/00changelog.d: size=376950 (zstd no-bigendian !)
1164 test-repo/.hg/store/00changelog.d: size=376948 (zstd bigendian !)
1164 test-repo/.hg/store/00changelog.d: size=376948 (zstd bigendian !)
1165 test-repo/.hg/store/00changelog.d: size=368949 (no-zstd !)
1165 test-repo/.hg/store/00changelog.d: size=368949 (no-zstd !)
1166 test-repo/.hg/store/00changelog.i: size=320448
1166 test-repo/.hg/store/00changelog.i: size=320448
1167 test-repo/.hg/store/00changelog.n: size=62
1167 test-repo/.hg/store/00changelog.n: size=62
1168 $ hg -R test-repo debugnodemap --metadata | tee server-metadata-2.txt
1168 $ hg -R test-repo debugnodemap --metadata | tee server-metadata-2.txt
1169 uid: * (glob)
1169 uid: * (glob)
1170 tip-rev: 5006
1170 tip-rev: 5006
1171 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1171 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1172 data-length: 121344 (rust !)
1172 data-length: 121344 (rust !)
1173 data-length: 121344 (pure !)
1173 data-length: 121344 (pure !)
1174 data-length: 121152 (no-rust no-pure !)
1174 data-length: 121152 (no-rust no-pure !)
1175 data-unused: 192 (rust !)
1175 data-unused: 192 (rust !)
1176 data-unused: 192 (pure !)
1176 data-unused: 192 (pure !)
1177 data-unused: 0 (no-rust no-pure !)
1177 data-unused: 0 (no-rust no-pure !)
1178 data-unused: 0.158% (rust !)
1178 data-unused: 0.158% (rust !)
1179 data-unused: 0.158% (pure !)
1179 data-unused: 0.158% (pure !)
1180 data-unused: 0.000% (no-rust no-pure !)
1180 data-unused: 0.000% (no-rust no-pure !)
1181
1181
1182 Performe the mix of clone and full refresh of the nodemap, so that the files
1182 Performe the mix of clone and full refresh of the nodemap, so that the files
1183 (and filenames) are different between listing time and actual transfer time.
1183 (and filenames) are different between listing time and actual transfer time.
1184
1184
1185 $ (hg clone -U --stream ssh://user@dummy/test-repo stream-clone-race-2 --debug 2>> clone-output-2 | egrep '00(changelog|manifest)' >> clone-output-2; touch $HG_TEST_STREAM_WALKED_FILE_3) &
1185 $ (hg clone -U --stream ssh://user@dummy/test-repo stream-clone-race-2 --debug 2>> clone-output-2 | egrep '00(changelog|manifest)' >> clone-output-2; touch $HG_TEST_STREAM_WALKED_FILE_3) &
1186 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_1
1186 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_1
1187 $ rm test-repo/.hg/store/00changelog.n
1187 $ rm test-repo/.hg/store/00changelog.n
1188 $ rm test-repo/.hg/store/00changelog-*.nd
1188 $ rm test-repo/.hg/store/00changelog-*.nd
1189 $ hg -R test-repo/ debugupdatecache
1189 $ hg -R test-repo/ debugupdatecache
1190 $ touch $HG_TEST_STREAM_WALKED_FILE_2
1190 $ touch $HG_TEST_STREAM_WALKED_FILE_2
1191 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_3
1191 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_3
1192
1192
1193 (note: the stream clone code wronly pick the `undo.` files)
1193 (note: the stream clone code wronly pick the `undo.` files)
1194
1194
1195 $ cat clone-output-2
1195 $ cat clone-output-2
1196 adding [s] undo.backup.00manifest.n (62 bytes) (known-bad-output !)
1197 adding [s] undo.backup.00changelog.n (62 bytes) (known-bad-output !)
1198 adding [s] 00manifest.n (62 bytes)
1196 adding [s] 00manifest.n (62 bytes)
1199 adding [s] 00manifest-*.nd (118 KB) (glob)
1197 adding [s] 00manifest-*.nd (118 KB) (glob)
1200 adding [s] 00changelog.n (62 bytes)
1198 adding [s] 00changelog.n (62 bytes)
1201 adding [s] 00changelog-*.nd (118 KB) (glob)
1199 adding [s] 00changelog-*.nd (118 KB) (glob)
1202 adding [s] 00manifest.d (492 KB) (zstd !)
1200 adding [s] 00manifest.d (492 KB) (zstd !)
1203 adding [s] 00manifest.d (452 KB) (no-zstd !)
1201 adding [s] 00manifest.d (452 KB) (no-zstd !)
1204 adding [s] 00changelog.d (360 KB) (no-zstd !)
1202 adding [s] 00changelog.d (360 KB) (no-zstd !)
1205 adding [s] 00changelog.d (368 KB) (zstd !)
1203 adding [s] 00changelog.d (368 KB) (zstd !)
1206 adding [s] 00manifest.i (313 KB)
1204 adding [s] 00manifest.i (313 KB)
1207 adding [s] 00changelog.i (313 KB)
1205 adding [s] 00changelog.i (313 KB)
1208
1206
1209 Check the result.
1207 Check the result.
1210
1208
1211 $ f --size stream-clone-race-2/.hg/store/00changelog*
1209 $ f --size stream-clone-race-2/.hg/store/00changelog*
1212 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121344 (glob) (rust !)
1210 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121344 (glob) (rust !)
1213 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121344 (glob) (pure !)
1211 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121344 (glob) (pure !)
1214 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121152 (glob) (no-rust no-pure !)
1212 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121152 (glob) (no-rust no-pure !)
1215 stream-clone-race-2/.hg/store/00changelog.d: size=376950 (zstd no-bigendian !)
1213 stream-clone-race-2/.hg/store/00changelog.d: size=376950 (zstd no-bigendian !)
1216 stream-clone-race-2/.hg/store/00changelog.d: size=376948 (zstd bigendian !)
1214 stream-clone-race-2/.hg/store/00changelog.d: size=376948 (zstd bigendian !)
1217 stream-clone-race-2/.hg/store/00changelog.d: size=368949 (no-zstd !)
1215 stream-clone-race-2/.hg/store/00changelog.d: size=368949 (no-zstd !)
1218 stream-clone-race-2/.hg/store/00changelog.i: size=320448
1216 stream-clone-race-2/.hg/store/00changelog.i: size=320448
1219 stream-clone-race-2/.hg/store/00changelog.n: size=62
1217 stream-clone-race-2/.hg/store/00changelog.n: size=62
1220
1218
1221 $ hg -R stream-clone-race-2 debugnodemap --metadata | tee client-metadata-2.txt
1219 $ hg -R stream-clone-race-2 debugnodemap --metadata | tee client-metadata-2.txt
1222 uid: * (glob)
1220 uid: * (glob)
1223 tip-rev: 5006
1221 tip-rev: 5006
1224 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1222 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1225 data-length: 121344 (rust !)
1223 data-length: 121344 (rust !)
1226 data-unused: 192 (rust !)
1224 data-unused: 192 (rust !)
1227 data-unused: 0.158% (rust !)
1225 data-unused: 0.158% (rust !)
1228 data-length: 121152 (no-rust no-pure !)
1226 data-length: 121152 (no-rust no-pure !)
1229 data-unused: 0 (no-rust no-pure !)
1227 data-unused: 0 (no-rust no-pure !)
1230 data-unused: 0.000% (no-rust no-pure !)
1228 data-unused: 0.000% (no-rust no-pure !)
1231 data-length: 121344 (pure !)
1229 data-length: 121344 (pure !)
1232 data-unused: 192 (pure !)
1230 data-unused: 192 (pure !)
1233 data-unused: 0.158% (pure !)
1231 data-unused: 0.158% (pure !)
1234
1232
1235 We get a usable nodemap, so no rewrite would be needed and the metadata should be identical
1233 We get a usable nodemap, so no rewrite would be needed and the metadata should be identical
1236 (ie: the following diff should be empty)
1234 (ie: the following diff should be empty)
1237
1235
1238 This isn't the case for the `no-rust` `no-pure` implementation as it use a very minimal nodemap implementation that unconditionnaly rewrite the nodemap "all the time".
1236 This isn't the case for the `no-rust` `no-pure` implementation as it use a very minimal nodemap implementation that unconditionnaly rewrite the nodemap "all the time".
1239
1237
1240 #if no-rust no-pure
1238 #if no-rust no-pure
1241 $ diff -u server-metadata-2.txt client-metadata-2.txt
1239 $ diff -u server-metadata-2.txt client-metadata-2.txt
1242 --- server-metadata-2.txt * (glob)
1240 --- server-metadata-2.txt * (glob)
1243 +++ client-metadata-2.txt * (glob)
1241 +++ client-metadata-2.txt * (glob)
1244 @@ -1,4 +1,4 @@
1242 @@ -1,4 +1,4 @@
1245 -uid: * (glob)
1243 -uid: * (glob)
1246 +uid: * (glob)
1244 +uid: * (glob)
1247 tip-rev: 5006
1245 tip-rev: 5006
1248 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1246 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1249 data-length: 121152
1247 data-length: 121152
1250 [1]
1248 [1]
1251 #else
1249 #else
1252 $ diff -u server-metadata-2.txt client-metadata-2.txt
1250 $ diff -u server-metadata-2.txt client-metadata-2.txt
1253 #endif
1251 #endif
1254
1252
1255 Clean up after the test
1253 Clean up after the test
1256
1254
1257 $ rm -f $HG_TEST_STREAM_WALKED_FILE_1
1255 $ rm -f $HG_TEST_STREAM_WALKED_FILE_1
1258 $ rm -f $HG_TEST_STREAM_WALKED_FILE_2
1256 $ rm -f $HG_TEST_STREAM_WALKED_FILE_2
1259 $ rm -f $HG_TEST_STREAM_WALKED_FILE_3
1257 $ rm -f $HG_TEST_STREAM_WALKED_FILE_3
1260
1258
@@ -1,511 +1,510 b''
1 #testcases abortcommand abortflag
1 #testcases abortcommand abortflag
2 #testcases continuecommand continueflag
2 #testcases continuecommand continueflag
3
3
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [extensions]
5 > [extensions]
6 > rebase=
6 > rebase=
7 >
7 >
8 > [phases]
8 > [phases]
9 > publish=False
9 > publish=False
10 >
10 >
11 > [alias]
11 > [alias]
12 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
12 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
13 > EOF
13 > EOF
14
14
15 #if abortflag
15 #if abortflag
16 $ cat >> $HGRCPATH <<EOF
16 $ cat >> $HGRCPATH <<EOF
17 > [alias]
17 > [alias]
18 > abort = rebase --abort
18 > abort = rebase --abort
19 > EOF
19 > EOF
20 #endif
20 #endif
21
21
22 #if continueflag
22 #if continueflag
23 $ cat >> $HGRCPATH <<EOF
23 $ cat >> $HGRCPATH <<EOF
24 > [alias]
24 > [alias]
25 > continue = rebase --continue
25 > continue = rebase --continue
26 > EOF
26 > EOF
27 #endif
27 #endif
28
28
29 $ hg init a
29 $ hg init a
30 $ cd a
30 $ cd a
31
31
32 $ touch .hg/rebasestate
32 $ touch .hg/rebasestate
33 $ hg sum
33 $ hg sum
34 parent: -1:000000000000 tip (empty repository)
34 parent: -1:000000000000 tip (empty repository)
35 branch: default
35 branch: default
36 commit: (clean)
36 commit: (clean)
37 update: (current)
37 update: (current)
38 abort: .hg/rebasestate is incomplete
38 abort: .hg/rebasestate is incomplete
39 [255]
39 [255]
40 $ rm .hg/rebasestate
40 $ rm .hg/rebasestate
41
41
42 $ echo c1 > common
42 $ echo c1 > common
43 $ hg add common
43 $ hg add common
44 $ hg ci -m C1
44 $ hg ci -m C1
45
45
46 $ echo c2 >> common
46 $ echo c2 >> common
47 $ hg ci -m C2
47 $ hg ci -m C2
48
48
49 $ echo c3 >> common
49 $ echo c3 >> common
50 $ hg ci -m C3
50 $ hg ci -m C3
51
51
52 $ hg up -q -C 1
52 $ hg up -q -C 1
53
53
54 $ echo l1 >> extra
54 $ echo l1 >> extra
55 $ hg add extra
55 $ hg add extra
56 $ hg ci -m L1
56 $ hg ci -m L1
57 created new head
57 created new head
58
58
59 $ sed -e 's/c2/l2/' common > common.new
59 $ sed -e 's/c2/l2/' common > common.new
60 $ mv common.new common
60 $ mv common.new common
61 $ hg ci -m L2
61 $ hg ci -m L2
62
62
63 $ hg phase --force --secret 2
63 $ hg phase --force --secret 2
64
64
65 $ hg tglog
65 $ hg tglog
66 @ 4:draft 'L2'
66 @ 4:draft 'L2'
67 |
67 |
68 o 3:draft 'L1'
68 o 3:draft 'L1'
69 |
69 |
70 | o 2:secret 'C3'
70 | o 2:secret 'C3'
71 |/
71 |/
72 o 1:draft 'C2'
72 o 1:draft 'C2'
73 |
73 |
74 o 0:draft 'C1'
74 o 0:draft 'C1'
75
75
76
76
77 Conflicting rebase:
77 Conflicting rebase:
78
78
79 $ hg rebase -s 3 -d 2
79 $ hg rebase -s 3 -d 2
80 rebasing 3:3163e20567cc "L1"
80 rebasing 3:3163e20567cc "L1"
81 rebasing 4:46f0b057b5c0 tip "L2"
81 rebasing 4:46f0b057b5c0 tip "L2"
82 merging common
82 merging common
83 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
83 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
84 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
84 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
85 [240]
85 [240]
86
86
87 Insert unsupported advisory merge record:
87 Insert unsupported advisory merge record:
88
88
89 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
89 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
90 $ hg debugmergestate
90 $ hg debugmergestate
91 local (dest): 3e046f2ecedb793b97ed32108086edd1a162f8bc
91 local (dest): 3e046f2ecedb793b97ed32108086edd1a162f8bc
92 other (source): 46f0b057b5c061d276b91491c22151f78698abd2
92 other (source): 46f0b057b5c061d276b91491c22151f78698abd2
93 file: common (state "u")
93 file: common (state "u")
94 local path: common (hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1, flags "")
94 local path: common (hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1, flags "")
95 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
95 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
96 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
96 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
97 extra: ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c
97 extra: ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c
98 extra: merged = yes
98 extra: merged = yes
99 $ hg resolve -l
99 $ hg resolve -l
100 U common
100 U common
101
101
102 Insert unsupported mandatory merge record:
102 Insert unsupported mandatory merge record:
103
103
104 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
104 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
105 $ hg debugmergestate
105 $ hg debugmergestate
106 abort: unsupported merge state records: X
106 abort: unsupported merge state records: X
107 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
107 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
108 [255]
108 [255]
109 $ hg resolve -l
109 $ hg resolve -l
110 abort: unsupported merge state records: X
110 abort: unsupported merge state records: X
111 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
111 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
112 [255]
112 [255]
113 $ hg resolve -ma
113 $ hg resolve -ma
114 abort: unsupported merge state records: X
114 abort: unsupported merge state records: X
115 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
115 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
116 [255]
116 [255]
117
117
118 Abort (should clear out unsupported merge state):
118 Abort (should clear out unsupported merge state):
119
119
120 #if abortcommand
120 #if abortcommand
121 when in dry-run mode
121 when in dry-run mode
122 $ hg abort --dry-run
122 $ hg abort --dry-run
123 rebase in progress, will be aborted
123 rebase in progress, will be aborted
124 #endif
124 #endif
125
125
126 $ hg abort
126 $ hg abort
127 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3e046f2ecedb-6beef7d5-backup.hg
127 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3e046f2ecedb-6beef7d5-backup.hg
128 rebase aborted
128 rebase aborted
129 $ hg debugmergestate
129 $ hg debugmergestate
130 no merge state found
130 no merge state found
131
131
132 $ hg tglog
132 $ hg tglog
133 @ 4:draft 'L2'
133 @ 4:draft 'L2'
134 |
134 |
135 o 3:draft 'L1'
135 o 3:draft 'L1'
136 |
136 |
137 | o 2:secret 'C3'
137 | o 2:secret 'C3'
138 |/
138 |/
139 o 1:draft 'C2'
139 o 1:draft 'C2'
140 |
140 |
141 o 0:draft 'C1'
141 o 0:draft 'C1'
142
142
143 Test safety for inconsistent rebase state, which may be created (and
143 Test safety for inconsistent rebase state, which may be created (and
144 forgotten) by Mercurial earlier than 2.7. This emulates Mercurial
144 forgotten) by Mercurial earlier than 2.7. This emulates Mercurial
145 earlier than 2.7 by renaming ".hg/rebasestate" temporarily.
145 earlier than 2.7 by renaming ".hg/rebasestate" temporarily.
146
146
147 $ hg rebase -s 3 -d 2
147 $ hg rebase -s 3 -d 2
148 rebasing 3:3163e20567cc "L1"
148 rebasing 3:3163e20567cc "L1"
149 rebasing 4:46f0b057b5c0 tip "L2"
149 rebasing 4:46f0b057b5c0 tip "L2"
150 merging common
150 merging common
151 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
151 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
152 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
152 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
153 [240]
153 [240]
154
154
155 $ mv .hg/rebasestate .hg/rebasestate.back
155 $ mv .hg/rebasestate .hg/rebasestate.back
156 $ hg update --quiet --clean 2
156 $ hg update --quiet --clean 2
157 $ hg --config extensions.mq= strip --quiet "destination()"
157 $ hg --config extensions.mq= strip --quiet "destination()"
158 $ mv .hg/rebasestate.back .hg/rebasestate
158 $ mv .hg/rebasestate.back .hg/rebasestate
159
159
160 $ hg continue
160 $ hg continue
161 abort: cannot continue inconsistent rebase
161 abort: cannot continue inconsistent rebase
162 (use "hg rebase --abort" to clear broken state)
162 (use "hg rebase --abort" to clear broken state)
163 [255]
163 [255]
164 $ hg summary | grep '^rebase: '
164 $ hg summary | grep '^rebase: '
165 rebase: (use "hg rebase --abort" to clear broken state)
165 rebase: (use "hg rebase --abort" to clear broken state)
166 $ hg abort
166 $ hg abort
167 rebase aborted (no revision is removed, only broken state is cleared)
167 rebase aborted (no revision is removed, only broken state is cleared)
168
168
169 $ cd ..
169 $ cd ..
170
170
171
171
172 Construct new repo:
172 Construct new repo:
173
173
174 $ hg init b
174 $ hg init b
175 $ cd b
175 $ cd b
176
176
177 $ echo a > a
177 $ echo a > a
178 $ hg ci -Am A
178 $ hg ci -Am A
179 adding a
179 adding a
180
180
181 $ echo b > b
181 $ echo b > b
182 $ hg ci -Am B
182 $ hg ci -Am B
183 adding b
183 adding b
184
184
185 $ echo c > c
185 $ echo c > c
186 $ hg ci -Am C
186 $ hg ci -Am C
187 adding c
187 adding c
188
188
189 $ hg up -q 0
189 $ hg up -q 0
190
190
191 $ echo b > b
191 $ echo b > b
192 $ hg ci -Am 'B bis'
192 $ hg ci -Am 'B bis'
193 adding b
193 adding b
194 created new head
194 created new head
195
195
196 $ echo c1 > c
196 $ echo c1 > c
197 $ hg ci -Am C1
197 $ hg ci -Am C1
198 adding c
198 adding c
199
199
200 $ hg phase --force --secret 1
200 $ hg phase --force --secret 1
201 $ hg phase --public 1
201 $ hg phase --public 1
202
202
203 Rebase and abort without generating new changesets:
203 Rebase and abort without generating new changesets:
204
204
205 $ hg tglog
205 $ hg tglog
206 @ 4:draft 'C1'
206 @ 4:draft 'C1'
207 |
207 |
208 o 3:draft 'B bis'
208 o 3:draft 'B bis'
209 |
209 |
210 | o 2:secret 'C'
210 | o 2:secret 'C'
211 | |
211 | |
212 | o 1:public 'B'
212 | o 1:public 'B'
213 |/
213 |/
214 o 0:public 'A'
214 o 0:public 'A'
215
215
216 $ hg rebase -b 4 -d 2
216 $ hg rebase -b 4 -d 2
217 rebasing 3:a6484957d6b9 "B bis"
217 rebasing 3:a6484957d6b9 "B bis"
218 note: not rebasing 3:a6484957d6b9 "B bis", its destination already has all its changes
218 note: not rebasing 3:a6484957d6b9 "B bis", its destination already has all its changes
219 rebasing 4:145842775fec tip "C1"
219 rebasing 4:145842775fec tip "C1"
220 merging c
220 merging c
221 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
221 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
222 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
222 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
223 [240]
223 [240]
224
224
225 $ hg tglog
225 $ hg tglog
226 % 4:draft 'C1'
226 % 4:draft 'C1'
227 |
227 |
228 o 3:draft 'B bis'
228 o 3:draft 'B bis'
229 |
229 |
230 | @ 2:secret 'C'
230 | @ 2:secret 'C'
231 | |
231 | |
232 | o 1:public 'B'
232 | o 1:public 'B'
233 |/
233 |/
234 o 0:public 'A'
234 o 0:public 'A'
235
235
236 $ hg rebase -a
236 $ hg rebase -a
237 rebase aborted
237 rebase aborted
238
238
239 $ hg tglog
239 $ hg tglog
240 @ 4:draft 'C1'
240 @ 4:draft 'C1'
241 |
241 |
242 o 3:draft 'B bis'
242 o 3:draft 'B bis'
243 |
243 |
244 | o 2:secret 'C'
244 | o 2:secret 'C'
245 | |
245 | |
246 | o 1:public 'B'
246 | o 1:public 'B'
247 |/
247 |/
248 o 0:public 'A'
248 o 0:public 'A'
249
249
250
250
251 $ cd ..
251 $ cd ..
252
252
253 rebase abort should not leave working copy in a merge state if tip-1 is public
253 rebase abort should not leave working copy in a merge state if tip-1 is public
254 (issue4082)
254 (issue4082)
255
255
256 $ hg init abortpublic
256 $ hg init abortpublic
257 $ cd abortpublic
257 $ cd abortpublic
258 $ echo a > a && hg ci -Aqm a
258 $ echo a > a && hg ci -Aqm a
259 $ hg book master
259 $ hg book master
260 $ hg book foo
260 $ hg book foo
261 $ echo b > b && hg ci -Aqm b
261 $ echo b > b && hg ci -Aqm b
262 $ hg up -q master
262 $ hg up -q master
263 $ echo c > c && hg ci -Aqm c
263 $ echo c > c && hg ci -Aqm c
264 $ hg phase -p -r .
264 $ hg phase -p -r .
265 $ hg up -q foo
265 $ hg up -q foo
266 $ echo C > c && hg ci -Aqm C
266 $ echo C > c && hg ci -Aqm C
267 $ hg log -G --template "{rev} {desc} {bookmarks}"
267 $ hg log -G --template "{rev} {desc} {bookmarks}"
268 @ 3 C foo
268 @ 3 C foo
269 |
269 |
270 | o 2 c master
270 | o 2 c master
271 | |
271 | |
272 o | 1 b
272 o | 1 b
273 |/
273 |/
274 o 0 a
274 o 0 a
275
275
276
276
277 $ hg rebase -d master -r foo
277 $ hg rebase -d master -r foo
278 rebasing 3:6c0f977a22d8 foo tip "C"
278 rebasing 3:6c0f977a22d8 foo tip "C"
279 merging c
279 merging c
280 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
280 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
281 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
281 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
282 [240]
282 [240]
283 $ hg abort
283 $ hg abort
284 rebase aborted
284 rebase aborted
285 $ hg log -G --template "{rev} {desc} {bookmarks}"
285 $ hg log -G --template "{rev} {desc} {bookmarks}"
286 @ 3 C foo
286 @ 3 C foo
287 |
287 |
288 | o 2 c master
288 | o 2 c master
289 | |
289 | |
290 o | 1 b
290 o | 1 b
291 |/
291 |/
292 o 0 a
292 o 0 a
293
293
294 $ cd ..
294 $ cd ..
295
295
296 Make sure we don't clobber changes in the working directory when the
296 Make sure we don't clobber changes in the working directory when the
297 user has somehow managed to update to a different revision (issue4009)
297 user has somehow managed to update to a different revision (issue4009)
298
298
299 $ hg init noupdate
299 $ hg init noupdate
300 $ cd noupdate
300 $ cd noupdate
301 $ hg book @
301 $ hg book @
302 $ echo original > a
302 $ echo original > a
303 $ hg add a
303 $ hg add a
304 $ hg commit -m a
304 $ hg commit -m a
305 $ echo x > b
305 $ echo x > b
306 $ hg add b
306 $ hg add b
307 $ hg commit -m b1
307 $ hg commit -m b1
308 $ hg up 0
308 $ hg up 0
309 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
309 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
310 (leaving bookmark @)
310 (leaving bookmark @)
311 $ hg book foo
311 $ hg book foo
312 $ echo y > b
312 $ echo y > b
313 $ hg add b
313 $ hg add b
314 $ hg commit -m b2
314 $ hg commit -m b2
315 created new head
315 created new head
316
316
317 $ hg rebase -d @ -b foo --tool=internal:fail
317 $ hg rebase -d @ -b foo --tool=internal:fail
318 rebasing 2:070cf4580bb5 foo tip "b2"
318 rebasing 2:070cf4580bb5 foo tip "b2"
319 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
319 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
320 [240]
320 [240]
321
321
322 $ mv .hg/rebasestate ./ # so we're allowed to hg up like in mercurial <2.6.3
322 $ mv .hg/rebasestate ./ # so we're allowed to hg up like in mercurial <2.6.3
323 $ hg up -C 0 # user does other stuff in the repo
323 $ hg up -C 0 # user does other stuff in the repo
324 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
324 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
325
325
326 $ mv rebasestate .hg/ # user upgrades to 2.7
326 $ mv rebasestate .hg/ # user upgrades to 2.7
327
327
328 $ echo new > a
328 $ echo new > a
329 $ hg up 1 # user gets an error saying to run hg rebase --abort
329 $ hg up 1 # user gets an error saying to run hg rebase --abort
330 abort: rebase in progress
330 abort: rebase in progress
331 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
331 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
332 [20]
332 [20]
333
333
334 $ cat a
334 $ cat a
335 new
335 new
336 $ hg abort
336 $ hg abort
337 rebase aborted
337 rebase aborted
338 $ cat a
338 $ cat a
339 new
339 new
340
340
341 $ cd ..
341 $ cd ..
342
342
343 test aborting an interrupted series (issue5084)
343 test aborting an interrupted series (issue5084)
344 $ hg init interrupted
344 $ hg init interrupted
345 $ cd interrupted
345 $ cd interrupted
346 $ touch base
346 $ touch base
347 $ hg add base
347 $ hg add base
348 $ hg commit -m base
348 $ hg commit -m base
349 $ touch a
349 $ touch a
350 $ hg add a
350 $ hg add a
351 $ hg commit -m a
351 $ hg commit -m a
352 $ echo 1 > a
352 $ echo 1 > a
353 $ hg commit -m 1
353 $ hg commit -m 1
354 $ touch b
354 $ touch b
355 $ hg add b
355 $ hg add b
356 $ hg commit -m b
356 $ hg commit -m b
357 $ echo 2 >> a
357 $ echo 2 >> a
358 $ hg commit -m c
358 $ hg commit -m c
359 $ touch d
359 $ touch d
360 $ hg add d
360 $ hg add d
361 $ hg commit -m d
361 $ hg commit -m d
362 $ hg co -q 1
362 $ hg co -q 1
363 $ hg rm a
363 $ hg rm a
364 $ hg commit -m no-a
364 $ hg commit -m no-a
365 created new head
365 created new head
366 $ hg co 0
366 $ hg co 0
367 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
367 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
368 $ hg log -G --template "{rev} {desc} {bookmarks}"
368 $ hg log -G --template "{rev} {desc} {bookmarks}"
369 o 6 no-a
369 o 6 no-a
370 |
370 |
371 | o 5 d
371 | o 5 d
372 | |
372 | |
373 | o 4 c
373 | o 4 c
374 | |
374 | |
375 | o 3 b
375 | o 3 b
376 | |
376 | |
377 | o 2 1
377 | o 2 1
378 |/
378 |/
379 o 1 a
379 o 1 a
380 |
380 |
381 @ 0 base
381 @ 0 base
382
382
383 $ hg --config extensions.n=$TESTDIR/failfilemerge.py rebase -s 3 -d tip
383 $ hg --config extensions.n=$TESTDIR/failfilemerge.py rebase -s 3 -d tip
384 rebasing 3:3a71550954f1 "b"
384 rebasing 3:3a71550954f1 "b"
385 rebasing 4:e80b69427d80 "c"
385 rebasing 4:e80b69427d80 "c"
386 abort: ^C
386 abort: ^C
387 [255]
387 [255]
388
388
389 New operations are blocked with the correct state message
389 New operations are blocked with the correct state message
390
390
391 $ find .hg -name '*state' -prune | sort
391 $ find .hg -name '*state' -prune | sort
392 .hg/dirstate
392 .hg/dirstate
393 .hg/merge/state
393 .hg/merge/state
394 .hg/rebasestate
394 .hg/rebasestate
395 .hg/undo.backup.dirstate
396 .hg/updatestate
395 .hg/updatestate
397
396
398 $ hg rebase -s 3 -d tip
397 $ hg rebase -s 3 -d tip
399 abort: rebase in progress
398 abort: rebase in progress
400 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
399 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
401 [20]
400 [20]
402 $ hg up .
401 $ hg up .
403 abort: rebase in progress
402 abort: rebase in progress
404 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
403 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
405 [20]
404 [20]
406 $ hg up -C .
405 $ hg up -C .
407 abort: rebase in progress
406 abort: rebase in progress
408 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
407 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
409 [20]
408 [20]
410
409
411 $ hg graft 3
410 $ hg graft 3
412 abort: rebase in progress
411 abort: rebase in progress
413 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
412 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
414 [20]
413 [20]
415
414
416 $ hg abort
415 $ hg abort
417 saved backup bundle to $TESTTMP/interrupted/.hg/strip-backup/3d8812cf300d-93041a90-backup.hg
416 saved backup bundle to $TESTTMP/interrupted/.hg/strip-backup/3d8812cf300d-93041a90-backup.hg
418 rebase aborted
417 rebase aborted
419 $ hg log -G --template "{rev} {desc} {bookmarks}"
418 $ hg log -G --template "{rev} {desc} {bookmarks}"
420 o 6 no-a
419 o 6 no-a
421 |
420 |
422 | o 5 d
421 | o 5 d
423 | |
422 | |
424 | o 4 c
423 | o 4 c
425 | |
424 | |
426 | o 3 b
425 | o 3 b
427 | |
426 | |
428 | o 2 1
427 | o 2 1
429 |/
428 |/
430 o 1 a
429 o 1 a
431 |
430 |
432 @ 0 base
431 @ 0 base
433
432
434 $ hg summary
433 $ hg summary
435 parent: 0:df4f53cec30a
434 parent: 0:df4f53cec30a
436 base
435 base
437 branch: default
436 branch: default
438 commit: (clean)
437 commit: (clean)
439 update: 6 new changesets (update)
438 update: 6 new changesets (update)
440 phases: 7 draft
439 phases: 7 draft
441
440
442 $ cd ..
441 $ cd ..
443 On the other hand, make sure we *do* clobber changes whenever we
442 On the other hand, make sure we *do* clobber changes whenever we
444 haven't somehow managed to update the repo to a different revision
443 haven't somehow managed to update the repo to a different revision
445 during a rebase (issue4661)
444 during a rebase (issue4661)
446
445
447 $ hg ini yesupdate
446 $ hg ini yesupdate
448 $ cd yesupdate
447 $ cd yesupdate
449 $ echo "initial data" > foo.txt
448 $ echo "initial data" > foo.txt
450 $ hg add
449 $ hg add
451 adding foo.txt
450 adding foo.txt
452 $ hg ci -m "initial checkin"
451 $ hg ci -m "initial checkin"
453 $ echo "change 1" > foo.txt
452 $ echo "change 1" > foo.txt
454 $ hg ci -m "change 1"
453 $ hg ci -m "change 1"
455 $ hg up 0
454 $ hg up 0
456 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
455 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
457 $ echo "conflicting change 1" > foo.txt
456 $ echo "conflicting change 1" > foo.txt
458 $ hg ci -m "conflicting 1"
457 $ hg ci -m "conflicting 1"
459 created new head
458 created new head
460 $ echo "conflicting change 2" > foo.txt
459 $ echo "conflicting change 2" > foo.txt
461 $ hg ci -m "conflicting 2"
460 $ hg ci -m "conflicting 2"
462
461
463 $ hg rebase -d 1 --tool 'internal:fail'
462 $ hg rebase -d 1 --tool 'internal:fail'
464 rebasing 2:e4ea5cdc9789 "conflicting 1"
463 rebasing 2:e4ea5cdc9789 "conflicting 1"
465 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
464 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
466 [240]
465 [240]
467 $ hg abort
466 $ hg abort
468 rebase aborted
467 rebase aborted
469 $ hg summary
468 $ hg summary
470 parent: 3:b16646383533 tip
469 parent: 3:b16646383533 tip
471 conflicting 2
470 conflicting 2
472 branch: default
471 branch: default
473 commit: (clean)
472 commit: (clean)
474 update: 1 new changesets, 2 branch heads (merge)
473 update: 1 new changesets, 2 branch heads (merge)
475 phases: 4 draft
474 phases: 4 draft
476 $ cd ..
475 $ cd ..
477
476
478 test aborting a rebase succeeds after rebasing with skipped commits onto a
477 test aborting a rebase succeeds after rebasing with skipped commits onto a
479 public changeset (issue4896)
478 public changeset (issue4896)
480
479
481 $ hg init succeedonpublic
480 $ hg init succeedonpublic
482 $ cd succeedonpublic
481 $ cd succeedonpublic
483 $ echo 'content' > root
482 $ echo 'content' > root
484 $ hg commit -A -m 'root' -q
483 $ hg commit -A -m 'root' -q
485
484
486 set up public branch
485 set up public branch
487 $ echo 'content' > disappear
486 $ echo 'content' > disappear
488 $ hg commit -A -m 'disappear public' -q
487 $ hg commit -A -m 'disappear public' -q
489 commit will cause merge conflict on rebase
488 commit will cause merge conflict on rebase
490 $ echo '' > root
489 $ echo '' > root
491 $ hg commit -m 'remove content public' -q
490 $ hg commit -m 'remove content public' -q
492 $ hg phase --public
491 $ hg phase --public
493
492
494 setup the draft branch that will be rebased onto public commit
493 setup the draft branch that will be rebased onto public commit
495 $ hg up -r 0 -q
494 $ hg up -r 0 -q
496 $ echo 'content' > disappear
495 $ echo 'content' > disappear
497 commit will disappear
496 commit will disappear
498 $ hg commit -A -m 'disappear draft' -q
497 $ hg commit -A -m 'disappear draft' -q
499 $ echo 'addedcontADDEDentadded' > root
498 $ echo 'addedcontADDEDentadded' > root
500 commit will cause merge conflict on rebase
499 commit will cause merge conflict on rebase
501 $ hg commit -m 'add content draft' -q
500 $ hg commit -m 'add content draft' -q
502
501
503 $ hg rebase -d 'public()' --tool :merge -q
502 $ hg rebase -d 'public()' --tool :merge -q
504 note: not rebasing 3:0682fd3dabf5 "disappear draft", its destination already has all its changes
503 note: not rebasing 3:0682fd3dabf5 "disappear draft", its destination already has all its changes
505 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
504 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
506 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
505 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
507 [240]
506 [240]
508 $ hg abort
507 $ hg abort
509 rebase aborted
508 rebase aborted
510 $ cd ..
509 $ cd ..
511
510
@@ -1,457 +1,457 b''
1 setup repo
1 setup repo
2 $ hg init t
2 $ hg init t
3 $ cd t
3 $ cd t
4 $ echo a > a
4 $ echo a > a
5 $ hg add a
5 $ hg add a
6 $ hg commit -m 'add a'
6 $ hg commit -m 'add a'
7 $ hg verify -q
7 $ hg verify -q
8 $ hg parents
8 $ hg parents
9 changeset: 0:1f0dee641bb7
9 changeset: 0:1f0dee641bb7
10 tag: tip
10 tag: tip
11 user: test
11 user: test
12 date: Thu Jan 01 00:00:00 1970 +0000
12 date: Thu Jan 01 00:00:00 1970 +0000
13 summary: add a
13 summary: add a
14
14
15
15
16 rollback to null revision
16 rollback to null revision
17 $ hg status
17 $ hg status
18 $ hg rollback
18 $ hg rollback
19 repository tip rolled back to revision -1 (undo commit)
19 repository tip rolled back to revision -1 (undo commit)
20 working directory now based on revision -1
20 working directory now based on revision -1
21 $ hg verify -q
21 $ hg verify -q
22 $ hg parents
22 $ hg parents
23 $ hg status
23 $ hg status
24 A a
24 A a
25
25
26 Two changesets this time so we rollback to a real changeset
26 Two changesets this time so we rollback to a real changeset
27 $ hg commit -m'add a again'
27 $ hg commit -m'add a again'
28 $ echo a >> a
28 $ echo a >> a
29 $ hg commit -m'modify a'
29 $ hg commit -m'modify a'
30
30
31 Test issue 902 (current branch is preserved)
31 Test issue 902 (current branch is preserved)
32 $ hg branch test
32 $ hg branch test
33 marked working directory as branch test
33 marked working directory as branch test
34 (branches are permanent and global, did you want a bookmark?)
34 (branches are permanent and global, did you want a bookmark?)
35 $ hg rollback
35 $ hg rollback
36 repository tip rolled back to revision 0 (undo commit)
36 repository tip rolled back to revision 0 (undo commit)
37 working directory now based on revision 0
37 working directory now based on revision 0
38 $ hg branch
38 $ hg branch
39 default
39 default
40
40
41 Test issue 1635 (commit message saved)
41 Test issue 1635 (commit message saved)
42 $ cat .hg/last-message.txt ; echo
42 $ cat .hg/last-message.txt ; echo
43 modify a
43 modify a
44
44
45
45
46 working dir unaffected by rollback: do not restore dirstate et. al.
46 working dir unaffected by rollback: do not restore dirstate et. al.
47 $ hg branch test --quiet
47 $ hg branch test --quiet
48 $ hg branch
48 $ hg branch
49 test
49 test
50 $ hg log --template '{rev} {branch} {desc|firstline}\n'
50 $ hg log --template '{rev} {branch} {desc|firstline}\n'
51 0 default add a again
51 0 default add a again
52 $ hg status
52 $ hg status
53 M a
53 M a
54 $ hg bookmark foo
54 $ hg bookmark foo
55 $ hg commit -m'modify a again'
55 $ hg commit -m'modify a again'
56 $ echo b > b
56 $ echo b > b
57 $ hg bookmark bar -r default #making bar active, before the transaction
57 $ hg bookmark bar -r default #making bar active, before the transaction
58 $ hg log -G --template '{rev} [{branch}] ({bookmarks}) {desc|firstline}\n'
58 $ hg log -G --template '{rev} [{branch}] ({bookmarks}) {desc|firstline}\n'
59 @ 1 [test] (foo) modify a again
59 @ 1 [test] (foo) modify a again
60 |
60 |
61 o 0 [default] (bar) add a again
61 o 0 [default] (bar) add a again
62
62
63 $ hg add b
63 $ hg add b
64 $ hg commit -m'add b'
64 $ hg commit -m'add b'
65 $ hg log -G --template '{rev} [{branch}] ({bookmarks}) {desc|firstline}\n'
65 $ hg log -G --template '{rev} [{branch}] ({bookmarks}) {desc|firstline}\n'
66 @ 2 [test] (foo) add b
66 @ 2 [test] (foo) add b
67 |
67 |
68 o 1 [test] () modify a again
68 o 1 [test] () modify a again
69 |
69 |
70 o 0 [default] (bar) add a again
70 o 0 [default] (bar) add a again
71
71
72 $ hg update bar
72 $ hg update bar
73 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
73 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
74 (activating bookmark bar)
74 (activating bookmark bar)
75 $ cat .hg/undo.backup.branch
75 $ cat .hg/undo.backup.branch.bck
76 test
76 test
77 $ hg log -G --template '{rev} [{branch}] ({bookmarks}) {desc|firstline}\n'
77 $ hg log -G --template '{rev} [{branch}] ({bookmarks}) {desc|firstline}\n'
78 o 2 [test] (foo) add b
78 o 2 [test] (foo) add b
79 |
79 |
80 o 1 [test] () modify a again
80 o 1 [test] () modify a again
81 |
81 |
82 @ 0 [default] (bar) add a again
82 @ 0 [default] (bar) add a again
83
83
84 $ hg rollback
84 $ hg rollback
85 abort: rollback of last commit while not checked out may lose data
85 abort: rollback of last commit while not checked out may lose data
86 (use -f to force)
86 (use -f to force)
87 [255]
87 [255]
88 $ hg rollback -f
88 $ hg rollback -f
89 repository tip rolled back to revision 1 (undo commit)
89 repository tip rolled back to revision 1 (undo commit)
90 $ hg id -n
90 $ hg id -n
91 0
91 0
92 $ hg log -G --template '{rev} [{branch}] ({bookmarks}) {desc|firstline}\n'
92 $ hg log -G --template '{rev} [{branch}] ({bookmarks}) {desc|firstline}\n'
93 o 1 [test] (foo) modify a again
93 o 1 [test] (foo) modify a again
94 |
94 |
95 @ 0 [default] (bar) add a again
95 @ 0 [default] (bar) add a again
96
96
97 $ hg branch
97 $ hg branch
98 default
98 default
99 $ cat .hg/bookmarks.current ; echo
99 $ cat .hg/bookmarks.current ; echo
100 bar
100 bar
101 $ hg bookmark --delete foo bar
101 $ hg bookmark --delete foo bar
102
102
103 rollback by pretxncommit saves commit message (issue1635)
103 rollback by pretxncommit saves commit message (issue1635)
104
104
105 $ echo a >> a
105 $ echo a >> a
106 $ hg --config hooks.pretxncommit=false commit -m"precious commit message"
106 $ hg --config hooks.pretxncommit=false commit -m"precious commit message"
107 transaction abort!
107 transaction abort!
108 rollback completed
108 rollback completed
109 abort: pretxncommit hook exited with status * (glob)
109 abort: pretxncommit hook exited with status * (glob)
110 [40]
110 [40]
111 $ cat .hg/last-message.txt ; echo
111 $ cat .hg/last-message.txt ; echo
112 precious commit message
112 precious commit message
113
113
114 same thing, but run $EDITOR
114 same thing, but run $EDITOR
115
115
116 $ cat > editor.sh << '__EOF__'
116 $ cat > editor.sh << '__EOF__'
117 > echo "another precious commit message" > "$1"
117 > echo "another precious commit message" > "$1"
118 > __EOF__
118 > __EOF__
119 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg --config hooks.pretxncommit=false commit 2>&1
119 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg --config hooks.pretxncommit=false commit 2>&1
120 transaction abort!
120 transaction abort!
121 rollback completed
121 rollback completed
122 note: commit message saved in .hg/last-message.txt
122 note: commit message saved in .hg/last-message.txt
123 note: use 'hg commit --logfile .hg/last-message.txt --edit' to reuse it
123 note: use 'hg commit --logfile .hg/last-message.txt --edit' to reuse it
124 abort: pretxncommit hook exited with status * (glob)
124 abort: pretxncommit hook exited with status * (glob)
125 [40]
125 [40]
126 $ cat .hg/last-message.txt
126 $ cat .hg/last-message.txt
127 another precious commit message
127 another precious commit message
128
128
129 test rollback on served repository
129 test rollback on served repository
130
130
131 #if serve
131 #if serve
132 $ hg commit -m "precious commit message"
132 $ hg commit -m "precious commit message"
133 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
133 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
134 $ cat hg.pid >> $DAEMON_PIDS
134 $ cat hg.pid >> $DAEMON_PIDS
135 $ cd ..
135 $ cd ..
136 $ hg clone http://localhost:$HGPORT u
136 $ hg clone http://localhost:$HGPORT u
137 requesting all changes
137 requesting all changes
138 adding changesets
138 adding changesets
139 adding manifests
139 adding manifests
140 adding file changes
140 adding file changes
141 added 3 changesets with 2 changes to 1 files (+1 heads)
141 added 3 changesets with 2 changes to 1 files (+1 heads)
142 new changesets 23b0221f3370:068774709090
142 new changesets 23b0221f3370:068774709090
143 updating to branch default
143 updating to branch default
144 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
144 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
145 $ cd u
145 $ cd u
146 $ hg id default
146 $ hg id default
147 068774709090
147 068774709090
148
148
149 now rollback and observe that 'hg serve' reloads the repository and
149 now rollback and observe that 'hg serve' reloads the repository and
150 presents the correct tip changeset:
150 presents the correct tip changeset:
151
151
152 $ hg -R ../t rollback
152 $ hg -R ../t rollback
153 repository tip rolled back to revision 1 (undo commit)
153 repository tip rolled back to revision 1 (undo commit)
154 working directory now based on revision 0
154 working directory now based on revision 0
155 $ hg id default
155 $ hg id default
156 791dd2169706
156 791dd2169706
157
157
158 $ killdaemons.py
158 $ killdaemons.py
159 #endif
159 #endif
160
160
161 update to older changeset and then refuse rollback, because
161 update to older changeset and then refuse rollback, because
162 that would lose data (issue2998)
162 that would lose data (issue2998)
163 $ cd ../t
163 $ cd ../t
164 $ hg -q update
164 $ hg -q update
165 $ rm `hg status -un`
165 $ rm `hg status -un`
166 $ template='{rev}:{node|short} [{branch}] {desc|firstline}\n'
166 $ template='{rev}:{node|short} [{branch}] {desc|firstline}\n'
167 $ echo 'valuable new file' > b
167 $ echo 'valuable new file' > b
168 $ echo 'valuable modification' >> a
168 $ echo 'valuable modification' >> a
169 $ hg commit -A -m'a valuable change'
169 $ hg commit -A -m'a valuable change'
170 adding b
170 adding b
171 $ hg update 0
171 $ hg update 0
172 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
172 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
173 $ hg rollback
173 $ hg rollback
174 abort: rollback of last commit while not checked out may lose data
174 abort: rollback of last commit while not checked out may lose data
175 (use -f to force)
175 (use -f to force)
176 [255]
176 [255]
177 $ hg tip -q
177 $ hg tip -q
178 2:4d9cd3795eea
178 2:4d9cd3795eea
179 $ hg rollback -f
179 $ hg rollback -f
180 repository tip rolled back to revision 1 (undo commit)
180 repository tip rolled back to revision 1 (undo commit)
181 $ hg status
181 $ hg status
182 $ hg log --removed b # yep, it's gone
182 $ hg log --removed b # yep, it's gone
183
183
184 same again, but emulate an old client that doesn't write undo.desc
184 same again, but emulate an old client that doesn't write undo.desc
185 $ hg -q update
185 $ hg -q update
186 $ echo 'valuable modification redux' >> a
186 $ echo 'valuable modification redux' >> a
187 $ hg commit -m'a valuable change redux'
187 $ hg commit -m'a valuable change redux'
188 $ rm .hg/undo.desc
188 $ rm .hg/undo.desc
189 $ hg update 0
189 $ hg update 0
190 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
190 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 $ hg rollback
191 $ hg rollback
192 rolling back unknown transaction
192 rolling back unknown transaction
193 working directory now based on revision 0
193 working directory now based on revision 0
194 $ cat a
194 $ cat a
195 a
195 a
196
196
197 corrupt journal test
197 corrupt journal test
198 $ echo "foo" > .hg/store/journal
198 $ echo "foo" > .hg/store/journal
199 $ hg recover --verify -q
199 $ hg recover --verify -q
200 couldn't read journal entry 'foo\n'!
200 couldn't read journal entry 'foo\n'!
201
201
202 rollback disabled by config
202 rollback disabled by config
203 $ cat >> $HGRCPATH <<EOF
203 $ cat >> $HGRCPATH <<EOF
204 > [ui]
204 > [ui]
205 > rollback = false
205 > rollback = false
206 > EOF
206 > EOF
207 $ echo narf >> pinky-sayings.txt
207 $ echo narf >> pinky-sayings.txt
208 $ hg add pinky-sayings.txt
208 $ hg add pinky-sayings.txt
209 $ hg ci -m 'First one.'
209 $ hg ci -m 'First one.'
210 $ hg rollback
210 $ hg rollback
211 abort: rollback is disabled because it is unsafe
211 abort: rollback is disabled because it is unsafe
212 (see `hg help -v rollback` for information)
212 (see `hg help -v rollback` for information)
213 [255]
213 [255]
214
214
215 $ cd ..
215 $ cd ..
216
216
217 I/O errors on stdio are handled properly (issue5658)
217 I/O errors on stdio are handled properly (issue5658)
218
218
219 $ cat > badui.py << EOF
219 $ cat > badui.py << EOF
220 > import errno
220 > import errno
221 > from mercurial.i18n import _
221 > from mercurial.i18n import _
222 > from mercurial import (
222 > from mercurial import (
223 > error,
223 > error,
224 > registrar,
224 > registrar,
225 > ui as uimod,
225 > ui as uimod,
226 > )
226 > )
227 >
227 >
228 > configtable = {}
228 > configtable = {}
229 > configitem = registrar.configitem(configtable)
229 > configitem = registrar.configitem(configtable)
230 >
230 >
231 > configitem(b'ui', b'ioerrors',
231 > configitem(b'ui', b'ioerrors',
232 > default=list,
232 > default=list,
233 > )
233 > )
234 >
234 >
235 > def pretxncommit(ui, repo, **kwargs):
235 > def pretxncommit(ui, repo, **kwargs):
236 > ui.warn(b'warn during pretxncommit\n')
236 > ui.warn(b'warn during pretxncommit\n')
237 >
237 >
238 > def pretxnclose(ui, repo, **kwargs):
238 > def pretxnclose(ui, repo, **kwargs):
239 > ui.warn(b'warn during pretxnclose\n')
239 > ui.warn(b'warn during pretxnclose\n')
240 >
240 >
241 > def txnclose(ui, repo, **kwargs):
241 > def txnclose(ui, repo, **kwargs):
242 > ui.warn(b'warn during txnclose\n')
242 > ui.warn(b'warn during txnclose\n')
243 >
243 >
244 > def txnabort(ui, repo, **kwargs):
244 > def txnabort(ui, repo, **kwargs):
245 > ui.warn(b'warn during abort\n')
245 > ui.warn(b'warn during abort\n')
246 >
246 >
247 > class fdproxy(object):
247 > class fdproxy(object):
248 > def __init__(self, ui, o):
248 > def __init__(self, ui, o):
249 > self._ui = ui
249 > self._ui = ui
250 > self._o = o
250 > self._o = o
251 >
251 >
252 > def __getattr__(self, attr):
252 > def __getattr__(self, attr):
253 > return getattr(self._o, attr)
253 > return getattr(self._o, attr)
254 >
254 >
255 > def write(self, msg):
255 > def write(self, msg):
256 > errors = set(self._ui.configlist(b'ui', b'ioerrors'))
256 > errors = set(self._ui.configlist(b'ui', b'ioerrors'))
257 > pretxncommit = msg == b'warn during pretxncommit\n'
257 > pretxncommit = msg == b'warn during pretxncommit\n'
258 > pretxnclose = msg == b'warn during pretxnclose\n'
258 > pretxnclose = msg == b'warn during pretxnclose\n'
259 > txnclose = msg == b'warn during txnclose\n'
259 > txnclose = msg == b'warn during txnclose\n'
260 > txnabort = msg == b'warn during abort\n'
260 > txnabort = msg == b'warn during abort\n'
261 > msgabort = msg == _(b'transaction abort!\n')
261 > msgabort = msg == _(b'transaction abort!\n')
262 > msgrollback = msg == _(b'rollback completed\n')
262 > msgrollback = msg == _(b'rollback completed\n')
263 >
263 >
264 > if pretxncommit and b'pretxncommit' in errors:
264 > if pretxncommit and b'pretxncommit' in errors:
265 > raise IOError(errno.EPIPE, 'simulated epipe')
265 > raise IOError(errno.EPIPE, 'simulated epipe')
266 > if pretxnclose and b'pretxnclose' in errors:
266 > if pretxnclose and b'pretxnclose' in errors:
267 > raise IOError(errno.EIO, 'simulated eio')
267 > raise IOError(errno.EIO, 'simulated eio')
268 > if txnclose and b'txnclose' in errors:
268 > if txnclose and b'txnclose' in errors:
269 > raise IOError(errno.EBADF, 'simulated badf')
269 > raise IOError(errno.EBADF, 'simulated badf')
270 > if txnabort and b'txnabort' in errors:
270 > if txnabort and b'txnabort' in errors:
271 > raise IOError(errno.EPIPE, 'simulated epipe')
271 > raise IOError(errno.EPIPE, 'simulated epipe')
272 > if msgabort and b'msgabort' in errors:
272 > if msgabort and b'msgabort' in errors:
273 > raise IOError(errno.EBADF, 'simulated ebadf')
273 > raise IOError(errno.EBADF, 'simulated ebadf')
274 > if msgrollback and b'msgrollback' in errors:
274 > if msgrollback and b'msgrollback' in errors:
275 > raise IOError(errno.EIO, 'simulated eio')
275 > raise IOError(errno.EIO, 'simulated eio')
276 >
276 >
277 > return self._o.write(msg)
277 > return self._o.write(msg)
278 >
278 >
279 > def uisetup(ui):
279 > def uisetup(ui):
280 > class badui(ui.__class__):
280 > class badui(ui.__class__):
281 > def _write(self, dest, *args, **kwargs):
281 > def _write(self, dest, *args, **kwargs):
282 > olderr = self.ferr
282 > olderr = self.ferr
283 > try:
283 > try:
284 > if dest is self.ferr:
284 > if dest is self.ferr:
285 > self.ferr = dest = fdproxy(self, olderr)
285 > self.ferr = dest = fdproxy(self, olderr)
286 > return super(badui, self)._write(dest, *args, **kwargs)
286 > return super(badui, self)._write(dest, *args, **kwargs)
287 > finally:
287 > finally:
288 > self.ferr = olderr
288 > self.ferr = olderr
289 >
289 >
290 > ui.__class__ = badui
290 > ui.__class__ = badui
291 >
291 >
292 > def reposetup(ui, repo):
292 > def reposetup(ui, repo):
293 > ui.setconfig(b'hooks', b'pretxnclose.badui', pretxnclose, b'badui')
293 > ui.setconfig(b'hooks', b'pretxnclose.badui', pretxnclose, b'badui')
294 > ui.setconfig(b'hooks', b'txnclose.badui', txnclose, b'badui')
294 > ui.setconfig(b'hooks', b'txnclose.badui', txnclose, b'badui')
295 > ui.setconfig(b'hooks', b'pretxncommit.badui', pretxncommit, b'badui')
295 > ui.setconfig(b'hooks', b'pretxncommit.badui', pretxncommit, b'badui')
296 > ui.setconfig(b'hooks', b'txnabort.badui', txnabort, b'badui')
296 > ui.setconfig(b'hooks', b'txnabort.badui', txnabort, b'badui')
297 > EOF
297 > EOF
298
298
299 $ cat >> $HGRCPATH << EOF
299 $ cat >> $HGRCPATH << EOF
300 > [extensions]
300 > [extensions]
301 > badui = $TESTTMP/badui.py
301 > badui = $TESTTMP/badui.py
302 > EOF
302 > EOF
303
303
304 An I/O error during pretxncommit is handled
304 An I/O error during pretxncommit is handled
305
305
306 $ hg init ioerror-pretxncommit
306 $ hg init ioerror-pretxncommit
307 $ cd ioerror-pretxncommit
307 $ cd ioerror-pretxncommit
308 $ echo 0 > foo
308 $ echo 0 > foo
309 $ hg -q commit -A -m initial
309 $ hg -q commit -A -m initial
310 warn during pretxncommit
310 warn during pretxncommit
311 warn during pretxnclose
311 warn during pretxnclose
312 warn during txnclose
312 warn during txnclose
313 $ echo 1 > foo
313 $ echo 1 > foo
314 $ hg --config ui.ioerrors=pretxncommit commit -m 'error during pretxncommit'
314 $ hg --config ui.ioerrors=pretxncommit commit -m 'error during pretxncommit'
315 warn during pretxnclose
315 warn during pretxnclose
316 warn during txnclose
316 warn during txnclose
317
317
318 $ hg commit -m 'commit 1'
318 $ hg commit -m 'commit 1'
319 nothing changed
319 nothing changed
320 [1]
320 [1]
321
321
322 $ cd ..
322 $ cd ..
323
323
324 An I/O error during pretxnclose is handled
324 An I/O error during pretxnclose is handled
325
325
326 $ hg init ioerror-pretxnclose
326 $ hg init ioerror-pretxnclose
327 $ cd ioerror-pretxnclose
327 $ cd ioerror-pretxnclose
328 $ echo 0 > foo
328 $ echo 0 > foo
329 $ hg -q commit -A -m initial
329 $ hg -q commit -A -m initial
330 warn during pretxncommit
330 warn during pretxncommit
331 warn during pretxnclose
331 warn during pretxnclose
332 warn during txnclose
332 warn during txnclose
333
333
334 $ echo 1 > foo
334 $ echo 1 > foo
335 $ hg --config ui.ioerrors=pretxnclose commit -m 'error during pretxnclose'
335 $ hg --config ui.ioerrors=pretxnclose commit -m 'error during pretxnclose'
336 warn during pretxncommit
336 warn during pretxncommit
337 warn during txnclose
337 warn during txnclose
338
338
339 $ hg commit -m 'commit 1'
339 $ hg commit -m 'commit 1'
340 nothing changed
340 nothing changed
341 [1]
341 [1]
342
342
343 $ cd ..
343 $ cd ..
344
344
345 An I/O error during txnclose is handled
345 An I/O error during txnclose is handled
346
346
347 $ hg init ioerror-txnclose
347 $ hg init ioerror-txnclose
348 $ cd ioerror-txnclose
348 $ cd ioerror-txnclose
349 $ echo 0 > foo
349 $ echo 0 > foo
350 $ hg -q commit -A -m initial
350 $ hg -q commit -A -m initial
351 warn during pretxncommit
351 warn during pretxncommit
352 warn during pretxnclose
352 warn during pretxnclose
353 warn during txnclose
353 warn during txnclose
354
354
355 $ echo 1 > foo
355 $ echo 1 > foo
356 $ hg --config ui.ioerrors=txnclose commit -m 'error during txnclose'
356 $ hg --config ui.ioerrors=txnclose commit -m 'error during txnclose'
357 warn during pretxncommit
357 warn during pretxncommit
358 warn during pretxnclose
358 warn during pretxnclose
359
359
360 $ hg commit -m 'commit 1'
360 $ hg commit -m 'commit 1'
361 nothing changed
361 nothing changed
362 [1]
362 [1]
363
363
364 $ cd ..
364 $ cd ..
365
365
366 An I/O error writing "transaction abort" is handled
366 An I/O error writing "transaction abort" is handled
367
367
368 $ hg init ioerror-msgabort
368 $ hg init ioerror-msgabort
369 $ cd ioerror-msgabort
369 $ cd ioerror-msgabort
370
370
371 $ echo 0 > foo
371 $ echo 0 > foo
372 $ hg -q commit -A -m initial
372 $ hg -q commit -A -m initial
373 warn during pretxncommit
373 warn during pretxncommit
374 warn during pretxnclose
374 warn during pretxnclose
375 warn during txnclose
375 warn during txnclose
376
376
377 $ echo 1 > foo
377 $ echo 1 > foo
378 $ hg --config ui.ioerrors=msgabort --config hooks.pretxncommit=false commit -m 'error during abort message'
378 $ hg --config ui.ioerrors=msgabort --config hooks.pretxncommit=false commit -m 'error during abort message'
379 warn during abort
379 warn during abort
380 rollback completed
380 rollback completed
381 abort: pretxncommit hook exited with status 1
381 abort: pretxncommit hook exited with status 1
382 [40]
382 [40]
383
383
384 $ hg commit -m 'commit 1'
384 $ hg commit -m 'commit 1'
385 warn during pretxncommit
385 warn during pretxncommit
386 warn during pretxnclose
386 warn during pretxnclose
387 warn during txnclose
387 warn during txnclose
388
388
389 $ cd ..
389 $ cd ..
390
390
391 An I/O error during txnabort should still result in rollback
391 An I/O error during txnabort should still result in rollback
392
392
393 $ hg init ioerror-txnabort
393 $ hg init ioerror-txnabort
394 $ cd ioerror-txnabort
394 $ cd ioerror-txnabort
395
395
396 $ echo 0 > foo
396 $ echo 0 > foo
397 $ hg -q commit -A -m initial
397 $ hg -q commit -A -m initial
398 warn during pretxncommit
398 warn during pretxncommit
399 warn during pretxnclose
399 warn during pretxnclose
400 warn during txnclose
400 warn during txnclose
401
401
402 $ echo 1 > foo
402 $ echo 1 > foo
403 $ hg --config ui.ioerrors=txnabort --config hooks.pretxncommit=false commit -m 'error during abort'
403 $ hg --config ui.ioerrors=txnabort --config hooks.pretxncommit=false commit -m 'error during abort'
404 transaction abort!
404 transaction abort!
405 rollback completed
405 rollback completed
406 abort: pretxncommit hook exited with status 1
406 abort: pretxncommit hook exited with status 1
407 [40]
407 [40]
408
408
409 $ hg commit -m 'commit 1'
409 $ hg commit -m 'commit 1'
410 warn during pretxncommit
410 warn during pretxncommit
411 warn during pretxnclose
411 warn during pretxnclose
412 warn during txnclose
412 warn during txnclose
413
413
414 $ cd ..
414 $ cd ..
415
415
416 An I/O error writing "rollback completed" is handled
416 An I/O error writing "rollback completed" is handled
417
417
418 $ hg init ioerror-msgrollback
418 $ hg init ioerror-msgrollback
419 $ cd ioerror-msgrollback
419 $ cd ioerror-msgrollback
420
420
421 $ echo 0 > foo
421 $ echo 0 > foo
422 $ hg -q commit -A -m initial
422 $ hg -q commit -A -m initial
423 warn during pretxncommit
423 warn during pretxncommit
424 warn during pretxnclose
424 warn during pretxnclose
425 warn during txnclose
425 warn during txnclose
426
426
427 $ echo 1 > foo
427 $ echo 1 > foo
428
428
429 $ hg --config ui.ioerrors=msgrollback --config hooks.pretxncommit=false commit -m 'error during rollback message'
429 $ hg --config ui.ioerrors=msgrollback --config hooks.pretxncommit=false commit -m 'error during rollback message'
430 transaction abort!
430 transaction abort!
431 warn during abort
431 warn during abort
432 abort: pretxncommit hook exited with status 1
432 abort: pretxncommit hook exited with status 1
433 [40]
433 [40]
434
434
435 $ hg verify -q
435 $ hg verify -q
436
436
437 $ cd ..
437 $ cd ..
438
438
439 Multiple I/O errors after transaction open are handled.
439 Multiple I/O errors after transaction open are handled.
440 This is effectively what happens if a peer disconnects in the middle
440 This is effectively what happens if a peer disconnects in the middle
441 of a transaction.
441 of a transaction.
442
442
443 $ hg init ioerror-multiple
443 $ hg init ioerror-multiple
444 $ cd ioerror-multiple
444 $ cd ioerror-multiple
445 $ echo 0 > foo
445 $ echo 0 > foo
446 $ hg -q commit -A -m initial
446 $ hg -q commit -A -m initial
447 warn during pretxncommit
447 warn during pretxncommit
448 warn during pretxnclose
448 warn during pretxnclose
449 warn during txnclose
449 warn during txnclose
450
450
451 $ echo 1 > foo
451 $ echo 1 > foo
452
452
453 $ hg --config ui.ioerrors=pretxncommit,pretxnclose,txnclose,txnabort,msgabort,msgrollback commit -m 'multiple errors'
453 $ hg --config ui.ioerrors=pretxncommit,pretxnclose,txnclose,txnabort,msgabort,msgrollback commit -m 'multiple errors'
454
454
455 $ hg verify -q
455 $ hg verify -q
456
456
457 $ cd ..
457 $ cd ..
@@ -1,448 +1,448 b''
1 Test correctness of revlog inline -> non-inline transition
1 Test correctness of revlog inline -> non-inline transition
2 ----------------------------------------------------------
2 ----------------------------------------------------------
3
3
4 We test various file length and naming pattern as this created issue in the
4 We test various file length and naming pattern as this created issue in the
5 past.
5 past.
6
6
7 Helper extension to intercept renames and kill process
7 Helper extension to intercept renames and kill process
8
8
9 $ cat > $TESTTMP/intercept_before_rename.py << EOF
9 $ cat > $TESTTMP/intercept_before_rename.py << EOF
10 > import os
10 > import os
11 > import signal
11 > import signal
12 > from mercurial import extensions, util
12 > from mercurial import extensions, util
13 >
13 >
14 > def extsetup(ui):
14 > def extsetup(ui):
15 > def rename(orig, src, dest, *args, **kwargs):
15 > def rename(orig, src, dest, *args, **kwargs):
16 > path = util.normpath(dest)
16 > path = util.normpath(dest)
17 > if path.endswith(b'data/file.i'):
17 > if path.endswith(b'data/file.i'):
18 > os.kill(os.getpid(), signal.SIGKILL)
18 > os.kill(os.getpid(), signal.SIGKILL)
19 > return orig(src, dest, *args, **kwargs)
19 > return orig(src, dest, *args, **kwargs)
20 > extensions.wrapfunction(util, 'rename', rename)
20 > extensions.wrapfunction(util, 'rename', rename)
21 > EOF
21 > EOF
22
22
23 $ cat > $TESTTMP/intercept_after_rename.py << EOF
23 $ cat > $TESTTMP/intercept_after_rename.py << EOF
24 > import os
24 > import os
25 > import signal
25 > import signal
26 > from mercurial import extensions, util
26 > from mercurial import extensions, util
27 >
27 >
28 > def extsetup(ui):
28 > def extsetup(ui):
29 > def close(orig, *args, **kwargs):
29 > def close(orig, *args, **kwargs):
30 > path = util.normpath(args[0]._atomictempfile__name)
30 > path = util.normpath(args[0]._atomictempfile__name)
31 > r = orig(*args, **kwargs)
31 > r = orig(*args, **kwargs)
32 > if path.endswith(b'/.hg/store/data/file.i'):
32 > if path.endswith(b'/.hg/store/data/file.i'):
33 > os.kill(os.getpid(), signal.SIGKILL)
33 > os.kill(os.getpid(), signal.SIGKILL)
34 > return r
34 > return r
35 > extensions.wrapfunction(util.atomictempfile, 'close', close)
35 > extensions.wrapfunction(util.atomictempfile, 'close', close)
36 > def extsetup(ui):
36 > def extsetup(ui):
37 > def rename(orig, src, dest, *args, **kwargs):
37 > def rename(orig, src, dest, *args, **kwargs):
38 > path = util.normpath(dest)
38 > path = util.normpath(dest)
39 > r = orig(src, dest, *args, **kwargs)
39 > r = orig(src, dest, *args, **kwargs)
40 > if path.endswith(b'data/file.i'):
40 > if path.endswith(b'data/file.i'):
41 > os.kill(os.getpid(), signal.SIGKILL)
41 > os.kill(os.getpid(), signal.SIGKILL)
42 > return r
42 > return r
43 > extensions.wrapfunction(util, 'rename', rename)
43 > extensions.wrapfunction(util, 'rename', rename)
44 > EOF
44 > EOF
45
45
46 $ cat > $TESTTMP/killme.py << EOF
46 $ cat > $TESTTMP/killme.py << EOF
47 > import os
47 > import os
48 > import signal
48 > import signal
49 >
49 >
50 > def killme(ui, repo, hooktype, **kwargs):
50 > def killme(ui, repo, hooktype, **kwargs):
51 > os.kill(os.getpid(), signal.SIGKILL)
51 > os.kill(os.getpid(), signal.SIGKILL)
52 > EOF
52 > EOF
53
53
54 $ cat > $TESTTMP/reader_wait_split.py << EOF
54 $ cat > $TESTTMP/reader_wait_split.py << EOF
55 > import os
55 > import os
56 > import signal
56 > import signal
57 > from mercurial import extensions, revlog, testing
57 > from mercurial import extensions, revlog, testing
58 > def _wait_post_load(orig, self, *args, **kwargs):
58 > def _wait_post_load(orig, self, *args, **kwargs):
59 > wait = b'data/file' in self.radix
59 > wait = b'data/file' in self.radix
60 > if wait:
60 > if wait:
61 > testing.wait_file(b"$TESTTMP/writer-revlog-split")
61 > testing.wait_file(b"$TESTTMP/writer-revlog-split")
62 > r = orig(self, *args, **kwargs)
62 > r = orig(self, *args, **kwargs)
63 > if wait:
63 > if wait:
64 > testing.write_file(b"$TESTTMP/reader-index-read")
64 > testing.write_file(b"$TESTTMP/reader-index-read")
65 > testing.wait_file(b"$TESTTMP/writer-revlog-unsplit")
65 > testing.wait_file(b"$TESTTMP/writer-revlog-unsplit")
66 > return r
66 > return r
67 >
67 >
68 > def extsetup(ui):
68 > def extsetup(ui):
69 > extensions.wrapfunction(revlog.revlog, '_loadindex', _wait_post_load)
69 > extensions.wrapfunction(revlog.revlog, '_loadindex', _wait_post_load)
70 > EOF
70 > EOF
71
71
72 setup a repository for tests
72 setup a repository for tests
73 ----------------------------
73 ----------------------------
74
74
75 $ cat >> $HGRCPATH << EOF
75 $ cat >> $HGRCPATH << EOF
76 > [format]
76 > [format]
77 > revlog-compression=none
77 > revlog-compression=none
78 > EOF
78 > EOF
79
79
80 $ hg init troffset-computation
80 $ hg init troffset-computation
81 $ cd troffset-computation
81 $ cd troffset-computation
82 $ files="
82 $ files="
83 > file
83 > file
84 > Directory_With,Special%Char/Complex_File.babar
84 > Directory_With,Special%Char/Complex_File.babar
85 > foo/bar/babar_celeste/foo
85 > foo/bar/babar_celeste/foo
86 > 1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/f
86 > 1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/f
87 > "
87 > "
88 $ for f in $files; do
88 $ for f in $files; do
89 > mkdir -p `dirname $f`
89 > mkdir -p `dirname $f`
90 > done
90 > done
91 $ for f in $files; do
91 $ for f in $files; do
92 > printf '%20d' '1' > $f
92 > printf '%20d' '1' > $f
93 > done
93 > done
94 $ hg commit -Aqma
94 $ hg commit -Aqma
95 $ for f in $files; do
95 $ for f in $files; do
96 > printf '%1024d' '1' > $f
96 > printf '%1024d' '1' > $f
97 > done
97 > done
98 $ hg commit -Aqmb
98 $ hg commit -Aqmb
99 $ for f in $files; do
99 $ for f in $files; do
100 > printf '%20d' '1' > $f
100 > printf '%20d' '1' > $f
101 > done
101 > done
102 $ hg commit -Aqmc
102 $ hg commit -Aqmc
103 $ for f in $files; do
103 $ for f in $files; do
104 > dd if=/dev/zero of=$f bs=1k count=128 > /dev/null 2>&1
104 > dd if=/dev/zero of=$f bs=1k count=128 > /dev/null 2>&1
105 > done
105 > done
106 $ hg commit -AqmD --traceback
106 $ hg commit -AqmD --traceback
107
107
108 Reference size:
108 Reference size:
109 $ f -s file
109 $ f -s file
110 file: size=131072
110 file: size=131072
111 $ f -s .hg/store/data/file*
111 $ f -s .hg/store/data/file*
112 .hg/store/data/file.d: size=132139
112 .hg/store/data/file.d: size=132139
113 .hg/store/data/file.i: size=256
113 .hg/store/data/file.i: size=256
114
114
115 $ cd ..
115 $ cd ..
116
116
117
117
118 Test a hard crash after the file was split but before the transaction was committed
118 Test a hard crash after the file was split but before the transaction was committed
119 ===================================================================================
119 ===================================================================================
120
120
121 Test offset computation to correctly factor in the index entries themselves.
121 Test offset computation to correctly factor in the index entries themselves.
122 Also test that the new data size has the correct size if the transaction is aborted
122 Also test that the new data size has the correct size if the transaction is aborted
123 after the index has been replaced.
123 after the index has been replaced.
124
124
125 Test repo has commits a, b, c, D, where D is large (grows the revlog enough that it
125 Test repo has commits a, b, c, D, where D is large (grows the revlog enough that it
126 transitions to non-inline storage). The clone initially has changes a, b
126 transitions to non-inline storage). The clone initially has changes a, b
127 and will transition to non-inline storage when adding c, D.
127 and will transition to non-inline storage when adding c, D.
128
128
129 If the transaction adding c, D is rolled back, then we don't undo the revlog split,
129 If the transaction adding c, D is rolled back, then we don't undo the revlog split,
130 but truncate the index and the data to remove both c and D.
130 but truncate the index and the data to remove both c and D.
131
131
132
132
133 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy
133 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy
134 $ cd troffset-computation-copy
134 $ cd troffset-computation-copy
135
135
136 Reference size:
136 Reference size:
137 $ f -s file
137 $ f -s file
138 file: size=1024
138 file: size=1024
139 $ f -s .hg/store/data/file*
139 $ f -s .hg/store/data/file*
140 .hg/store/data/file.i: size=1174
140 .hg/store/data/file.i: size=1174
141
141
142 $ cat > .hg/hgrc <<EOF
142 $ cat > .hg/hgrc <<EOF
143 > [hooks]
143 > [hooks]
144 > pretxnchangegroup = python:$TESTTMP/killme.py:killme
144 > pretxnchangegroup = python:$TESTTMP/killme.py:killme
145 > EOF
145 > EOF
146 #if chg
146 #if chg
147 $ hg pull ../troffset-computation
147 $ hg pull ../troffset-computation
148 pulling from ../troffset-computation
148 pulling from ../troffset-computation
149 [255]
149 [255]
150 #else
150 #else
151 $ hg pull ../troffset-computation
151 $ hg pull ../troffset-computation
152 pulling from ../troffset-computation
152 pulling from ../troffset-computation
153 *Killed* (glob)
153 *Killed* (glob)
154 [137]
154 [137]
155 #endif
155 #endif
156
156
157
157
158 The inline revlog still exist, but a split version exist next to it
158 The inline revlog still exist, but a split version exist next to it
159
159
160 $ f -s .hg/store/data/file*
160 $ f -s .hg/store/data/file*
161 .hg/store/data/file.d: size=132139
161 .hg/store/data/file.d: size=132139
162 .hg/store/data/file.i: size=132395
162 .hg/store/data/file.i: size=132395
163 .hg/store/data/file.i.s: size=256
163 .hg/store/data/file.i.s: size=256
164
164
165
165
166 The first file.i entry should match the "Reference size" above.
166 The first file.i entry should match the "Reference size" above.
167 The first file.d entry is the temporary record during the split,
167 The first file.d entry is the temporary record during the split,
168
168
169 A "temporary file" entry exist for the split index.
169 A "temporary file" entry exist for the split index.
170
170
171 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
171 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
172 data/file.i 1174
172 data/file.i 1174
173 data/file.d 0
173 data/file.d 0
174 $ cat .hg/store/journal.backupfiles | tr -s '\000' ' ' | tr -s '\00' ' '| grep data/file
174 $ cat .hg/store/journal.backupfiles | tr -s '\000' ' ' | tr -s '\00' ' '| grep data/file
175 data/file.i data/journal.backup.file.i 0
175 data/file.i data/journal.backup.file.i.bck 0
176 data/file.i.s 0
176 data/file.i.s 0
177
177
178 recover is rolling the split back, the fncache is still valid
178 recover is rolling the split back, the fncache is still valid
179
179
180 $ hg recover
180 $ hg recover
181 rolling back interrupted transaction
181 rolling back interrupted transaction
182 (verify step skipped, run `hg verify` to check your repository content)
182 (verify step skipped, run `hg verify` to check your repository content)
183 $ f -s .hg/store/data/file*
183 $ f -s .hg/store/data/file*
184 .hg/store/data/file.i: size=1174
184 .hg/store/data/file.i: size=1174
185 $ hg tip
185 $ hg tip
186 changeset: 1:cc8dfb126534
186 changeset: 1:cc8dfb126534
187 tag: tip
187 tag: tip
188 user: test
188 user: test
189 date: Thu Jan 01 00:00:00 1970 +0000
189 date: Thu Jan 01 00:00:00 1970 +0000
190 summary: b
190 summary: b
191
191
192 $ hg verify -q
192 $ hg verify -q
193 $ hg debugrebuildfncache --only-data
193 $ hg debugrebuildfncache --only-data
194 fncache already up to date
194 fncache already up to date
195 $ hg verify -q
195 $ hg verify -q
196 $ cd ..
196 $ cd ..
197
197
198 Test a hard crash right before the index is move into place
198 Test a hard crash right before the index is move into place
199 ===========================================================
199 ===========================================================
200
200
201 Now retry the procedure but intercept the rename of the index and check that
201 Now retry the procedure but intercept the rename of the index and check that
202 the journal does not contain the new index size. This demonstrates the edge case
202 the journal does not contain the new index size. This demonstrates the edge case
203 where the data file is left as garbage.
203 where the data file is left as garbage.
204
204
205 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy2
205 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy2
206 $ cd troffset-computation-copy2
206 $ cd troffset-computation-copy2
207
207
208 Reference size:
208 Reference size:
209 $ f -s file
209 $ f -s file
210 file: size=1024
210 file: size=1024
211 $ f -s .hg/store/data/file*
211 $ f -s .hg/store/data/file*
212 .hg/store/data/file.i: size=1174
212 .hg/store/data/file.i: size=1174
213
213
214 $ cat > .hg/hgrc <<EOF
214 $ cat > .hg/hgrc <<EOF
215 > [extensions]
215 > [extensions]
216 > intercept_rename = $TESTTMP/intercept_before_rename.py
216 > intercept_rename = $TESTTMP/intercept_before_rename.py
217 > EOF
217 > EOF
218 #if chg
218 #if chg
219 $ hg pull ../troffset-computation
219 $ hg pull ../troffset-computation
220 pulling from ../troffset-computation
220 pulling from ../troffset-computation
221 searching for changes
221 searching for changes
222 adding changesets
222 adding changesets
223 adding manifests
223 adding manifests
224 adding file changes
224 adding file changes
225 [255]
225 [255]
226 #else
226 #else
227 $ hg pull ../troffset-computation
227 $ hg pull ../troffset-computation
228 pulling from ../troffset-computation
228 pulling from ../troffset-computation
229 searching for changes
229 searching for changes
230 adding changesets
230 adding changesets
231 adding manifests
231 adding manifests
232 adding file changes
232 adding file changes
233 *Killed* (glob)
233 *Killed* (glob)
234 [137]
234 [137]
235 #endif
235 #endif
236
236
237 The inline revlog still exist, but a split version exist next to it
237 The inline revlog still exist, but a split version exist next to it
238
238
239 $ f -s .hg/store/data/file*
239 $ f -s .hg/store/data/file*
240 .hg/store/data/file.d: size=132139
240 .hg/store/data/file.d: size=132139
241 .hg/store/data/file.i: size=132395
241 .hg/store/data/file.i: size=132395
242 .hg/store/data/file.i.s: size=256
242 .hg/store/data/file.i.s: size=256
243
243
244 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
244 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
245 data/file.i 1174
245 data/file.i 1174
246 data/file.d 0
246 data/file.d 0
247
247
248 recover is rolling the split back, the fncache is still valid
248 recover is rolling the split back, the fncache is still valid
249
249
250 $ hg recover
250 $ hg recover
251 rolling back interrupted transaction
251 rolling back interrupted transaction
252 (verify step skipped, run `hg verify` to check your repository content)
252 (verify step skipped, run `hg verify` to check your repository content)
253 $ f -s .hg/store/data/file*
253 $ f -s .hg/store/data/file*
254 .hg/store/data/file.i: size=1174
254 .hg/store/data/file.i: size=1174
255 $ hg tip
255 $ hg tip
256 changeset: 1:cc8dfb126534
256 changeset: 1:cc8dfb126534
257 tag: tip
257 tag: tip
258 user: test
258 user: test
259 date: Thu Jan 01 00:00:00 1970 +0000
259 date: Thu Jan 01 00:00:00 1970 +0000
260 summary: b
260 summary: b
261
261
262 $ hg verify -q
262 $ hg verify -q
263 $ cd ..
263 $ cd ..
264
264
265 Test a hard crash right after the index is move into place
265 Test a hard crash right after the index is move into place
266 ===========================================================
266 ===========================================================
267
267
268 Now retry the procedure but intercept the rename of the index.
268 Now retry the procedure but intercept the rename of the index.
269
269
270 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-crash-after-rename
270 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-crash-after-rename
271 $ cd troffset-computation-crash-after-rename
271 $ cd troffset-computation-crash-after-rename
272
272
273 Reference size:
273 Reference size:
274 $ f -s file
274 $ f -s file
275 file: size=1024
275 file: size=1024
276 $ f -s .hg/store/data/file*
276 $ f -s .hg/store/data/file*
277 .hg/store/data/file.i: size=1174
277 .hg/store/data/file.i: size=1174
278
278
279 $ cat > .hg/hgrc <<EOF
279 $ cat > .hg/hgrc <<EOF
280 > [extensions]
280 > [extensions]
281 > intercept_rename = $TESTTMP/intercept_after_rename.py
281 > intercept_rename = $TESTTMP/intercept_after_rename.py
282 > EOF
282 > EOF
283 #if chg
283 #if chg
284 $ hg pull ../troffset-computation
284 $ hg pull ../troffset-computation
285 pulling from ../troffset-computation
285 pulling from ../troffset-computation
286 searching for changes
286 searching for changes
287 adding changesets
287 adding changesets
288 adding manifests
288 adding manifests
289 adding file changes
289 adding file changes
290 [255]
290 [255]
291 #else
291 #else
292 $ hg pull ../troffset-computation
292 $ hg pull ../troffset-computation
293 pulling from ../troffset-computation
293 pulling from ../troffset-computation
294 searching for changes
294 searching for changes
295 adding changesets
295 adding changesets
296 adding manifests
296 adding manifests
297 adding file changes
297 adding file changes
298 *Killed* (glob)
298 *Killed* (glob)
299 [137]
299 [137]
300 #endif
300 #endif
301
301
302 The inline revlog was over written on disk
302 The inline revlog was over written on disk
303
303
304 $ f -s .hg/store/data/file*
304 $ f -s .hg/store/data/file*
305 .hg/store/data/file.d: size=132139
305 .hg/store/data/file.d: size=132139
306 .hg/store/data/file.i: size=256
306 .hg/store/data/file.i: size=256
307
307
308 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
308 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
309 data/file.i 1174
309 data/file.i 1174
310 data/file.d 0
310 data/file.d 0
311
311
312 recover is rolling the split back, the fncache is still valid
312 recover is rolling the split back, the fncache is still valid
313
313
314 $ hg recover
314 $ hg recover
315 rolling back interrupted transaction
315 rolling back interrupted transaction
316 (verify step skipped, run `hg verify` to check your repository content)
316 (verify step skipped, run `hg verify` to check your repository content)
317 $ f -s .hg/store/data/file*
317 $ f -s .hg/store/data/file*
318 .hg/store/data/file.i: size=1174
318 .hg/store/data/file.i: size=1174
319 $ hg tip
319 $ hg tip
320 changeset: 1:cc8dfb126534
320 changeset: 1:cc8dfb126534
321 tag: tip
321 tag: tip
322 user: test
322 user: test
323 date: Thu Jan 01 00:00:00 1970 +0000
323 date: Thu Jan 01 00:00:00 1970 +0000
324 summary: b
324 summary: b
325
325
326 $ hg verify -q
326 $ hg verify -q
327 $ cd ..
327 $ cd ..
328
328
329 Have the transaction rollback itself without any hard crash
329 Have the transaction rollback itself without any hard crash
330 ===========================================================
330 ===========================================================
331
331
332
332
333 Repeat the original test but let hg rollback the transaction.
333 Repeat the original test but let hg rollback the transaction.
334
334
335 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy-rb
335 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy-rb
336 $ cd troffset-computation-copy-rb
336 $ cd troffset-computation-copy-rb
337 $ cat > .hg/hgrc <<EOF
337 $ cat > .hg/hgrc <<EOF
338 > [hooks]
338 > [hooks]
339 > pretxnchangegroup = false
339 > pretxnchangegroup = false
340 > EOF
340 > EOF
341 $ hg pull ../troffset-computation
341 $ hg pull ../troffset-computation
342 pulling from ../troffset-computation
342 pulling from ../troffset-computation
343 searching for changes
343 searching for changes
344 adding changesets
344 adding changesets
345 adding manifests
345 adding manifests
346 adding file changes
346 adding file changes
347 transaction abort!
347 transaction abort!
348 rollback completed
348 rollback completed
349 abort: pretxnchangegroup hook exited with status 1
349 abort: pretxnchangegroup hook exited with status 1
350 [40]
350 [40]
351
351
352 The split was rollback
352 The split was rollback
353
353
354 $ f -s .hg/store/data/file*
354 $ f -s .hg/store/data/file*
355 .hg/store/data/file.d: size=0
355 .hg/store/data/file.d: size=0
356 .hg/store/data/file.i: size=1174
356 .hg/store/data/file.i: size=1174
357
357
358
358
359 $ hg tip
359 $ hg tip
360 changeset: 1:cc8dfb126534
360 changeset: 1:cc8dfb126534
361 tag: tip
361 tag: tip
362 user: test
362 user: test
363 date: Thu Jan 01 00:00:00 1970 +0000
363 date: Thu Jan 01 00:00:00 1970 +0000
364 summary: b
364 summary: b
365
365
366 $ hg verify -q
366 $ hg verify -q
367 $ cd ..
367 $ cd ..
368
368
369 Read race
369 Read race
370 =========
370 =========
371
371
372 We check that a client that started reading a revlog (its index) after the
372 We check that a client that started reading a revlog (its index) after the
373 split and end reading (the data) after the rollback should be fine
373 split and end reading (the data) after the rollback should be fine
374
374
375 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-race
375 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-race
376 $ cd troffset-computation-race
376 $ cd troffset-computation-race
377 $ cat > .hg/hgrc <<EOF
377 $ cat > .hg/hgrc <<EOF
378 > [hooks]
378 > [hooks]
379 > pretxnchangegroup=$RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/reader-index-read $TESTTMP/writer-revlog-split
379 > pretxnchangegroup=$RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/reader-index-read $TESTTMP/writer-revlog-split
380 > pretxnclose = false
380 > pretxnclose = false
381 > EOF
381 > EOF
382
382
383 start a reader
383 start a reader
384
384
385 $ hg cat --rev 0 file \
385 $ hg cat --rev 0 file \
386 > --config "extensions.wait_read=$TESTTMP/reader_wait_split.py" \
386 > --config "extensions.wait_read=$TESTTMP/reader_wait_split.py" \
387 > 2> $TESTTMP/reader.stderr \
387 > 2> $TESTTMP/reader.stderr \
388 > > $TESTTMP/reader.stdout &
388 > > $TESTTMP/reader.stdout &
389
389
390 Do a failed pull in //
390 Do a failed pull in //
391
391
392 $ hg pull ../troffset-computation
392 $ hg pull ../troffset-computation
393 pulling from ../troffset-computation
393 pulling from ../troffset-computation
394 searching for changes
394 searching for changes
395 adding changesets
395 adding changesets
396 adding manifests
396 adding manifests
397 adding file changes
397 adding file changes
398 transaction abort!
398 transaction abort!
399 rollback completed
399 rollback completed
400 abort: pretxnclose hook exited with status 1
400 abort: pretxnclose hook exited with status 1
401 [40]
401 [40]
402 $ touch $TESTTMP/writer-revlog-unsplit
402 $ touch $TESTTMP/writer-revlog-unsplit
403 $ wait
403 $ wait
404
404
405 The reader should be fine
405 The reader should be fine
406 $ cat $TESTTMP/reader.stderr
406 $ cat $TESTTMP/reader.stderr
407 $ cat $TESTTMP/reader.stdout
407 $ cat $TESTTMP/reader.stdout
408 1 (no-eol)
408 1 (no-eol)
409 $ cd ..
409 $ cd ..
410
410
411 pending hooks
411 pending hooks
412 =============
412 =============
413
413
414 We checks that hooks properly see the inside of the transaction, while other process don't.
414 We checks that hooks properly see the inside of the transaction, while other process don't.
415
415
416 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-hooks
416 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-hooks
417 $ cd troffset-computation-hooks
417 $ cd troffset-computation-hooks
418 $ cat > .hg/hgrc <<EOF
418 $ cat > .hg/hgrc <<EOF
419 > [hooks]
419 > [hooks]
420 > pretxnclose.01-echo = hg cat -r 'max(all())' file | f --size
420 > pretxnclose.01-echo = hg cat -r 'max(all())' file | f --size
421 > pretxnclose.02-echo = $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/hook-done $TESTTMP/hook-tr-ready
421 > pretxnclose.02-echo = $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/hook-done $TESTTMP/hook-tr-ready
422 > pretxnclose.03-abort = false
422 > pretxnclose.03-abort = false
423 > EOF
423 > EOF
424
424
425 $ (
425 $ (
426 > $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/hook-tr-ready;\
426 > $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/hook-tr-ready;\
427 > hg cat -r 'max(all())' file | f --size;\
427 > hg cat -r 'max(all())' file | f --size;\
428 > touch $TESTTMP/hook-done
428 > touch $TESTTMP/hook-done
429 > ) >stdout 2>stderr &
429 > ) >stdout 2>stderr &
430
430
431 $ hg pull ../troffset-computation
431 $ hg pull ../troffset-computation
432 pulling from ../troffset-computation
432 pulling from ../troffset-computation
433 searching for changes
433 searching for changes
434 adding changesets
434 adding changesets
435 adding manifests
435 adding manifests
436 adding file changes
436 adding file changes
437 size=131072
437 size=131072
438 transaction abort!
438 transaction abort!
439 rollback completed
439 rollback completed
440 abort: pretxnclose.03-abort hook exited with status 1
440 abort: pretxnclose.03-abort hook exited with status 1
441 [40]
441 [40]
442
442
443 $ cat stdout
443 $ cat stdout
444 size=1024
444 size=1024
445 $ cat stderr
445 $ cat stderr
446
446
447
447
448 $ cd ..
448 $ cd ..
@@ -1,2101 +1,2101 b''
1 #require no-reposimplestore
1 #require no-reposimplestore
2
2
3 $ cat >> $HGRCPATH << EOF
3 $ cat >> $HGRCPATH << EOF
4 > [extensions]
4 > [extensions]
5 > share =
5 > share =
6 > [format]
6 > [format]
7 > # stabilize test accross variant
7 > # stabilize test accross variant
8 > revlog-compression=zlib
8 > revlog-compression=zlib
9 > [storage]
9 > [storage]
10 > dirstate-v2.slow-path=allow
10 > dirstate-v2.slow-path=allow
11 > EOF
11 > EOF
12
12
13 store and revlogv1 are required in source
13 store and revlogv1 are required in source
14
14
15 $ hg --config format.usestore=false init no-store
15 $ hg --config format.usestore=false init no-store
16 $ hg -R no-store debugupgraderepo
16 $ hg -R no-store debugupgraderepo
17 abort: cannot upgrade repository; requirement missing: store
17 abort: cannot upgrade repository; requirement missing: store
18 [255]
18 [255]
19
19
20 $ hg init no-revlogv1
20 $ hg init no-revlogv1
21 $ cat > no-revlogv1/.hg/requires << EOF
21 $ cat > no-revlogv1/.hg/requires << EOF
22 > dotencode
22 > dotencode
23 > fncache
23 > fncache
24 > generaldelta
24 > generaldelta
25 > store
25 > store
26 > EOF
26 > EOF
27
27
28 $ hg -R no-revlogv1 debugupgraderepo
28 $ hg -R no-revlogv1 debugupgraderepo
29 abort: cannot upgrade repository; missing a revlog version
29 abort: cannot upgrade repository; missing a revlog version
30 [255]
30 [255]
31
31
32 Cannot upgrade shared repositories
32 Cannot upgrade shared repositories
33
33
34 $ hg init share-parent
34 $ hg init share-parent
35 $ hg -R share-parent debugbuilddag -n .+9
35 $ hg -R share-parent debugbuilddag -n .+9
36 $ hg -R share-parent up tip
36 $ hg -R share-parent up tip
37 10 files updated, 0 files merged, 0 files removed, 0 files unresolved
37 10 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 $ hg -q share share-parent share-child
38 $ hg -q share share-parent share-child
39
39
40 $ hg -R share-child debugupgraderepo --config format.sparse-revlog=no
40 $ hg -R share-child debugupgraderepo --config format.sparse-revlog=no
41 abort: cannot use these actions on a share repository: sparserevlog
41 abort: cannot use these actions on a share repository: sparserevlog
42 (upgrade the main repository directly)
42 (upgrade the main repository directly)
43 [255]
43 [255]
44
44
45 Unless the action is compatible with share
45 Unless the action is compatible with share
46
46
47 $ hg -R share-child debugupgraderepo --config format.use-dirstate-v2=yes --quiet
47 $ hg -R share-child debugupgraderepo --config format.use-dirstate-v2=yes --quiet
48 requirements
48 requirements
49 preserved: * (glob)
49 preserved: * (glob)
50 added: dirstate-v2
50 added: dirstate-v2
51
51
52 no revlogs to process
52 no revlogs to process
53
53
54
54
55 $ hg -R share-child debugupgraderepo --config format.use-dirstate-v2=yes --quiet --run
55 $ hg -R share-child debugupgraderepo --config format.use-dirstate-v2=yes --quiet --run
56 upgrade will perform the following actions:
56 upgrade will perform the following actions:
57
57
58 requirements
58 requirements
59 preserved: * (glob)
59 preserved: * (glob)
60 added: dirstate-v2
60 added: dirstate-v2
61
61
62 no revlogs to process
62 no revlogs to process
63
63
64 $ hg debugformat -R share-child | grep dirstate-v2
64 $ hg debugformat -R share-child | grep dirstate-v2
65 dirstate-v2: yes
65 dirstate-v2: yes
66 $ hg debugformat -R share-parent | grep dirstate-v2
66 $ hg debugformat -R share-parent | grep dirstate-v2
67 dirstate-v2: no
67 dirstate-v2: no
68 $ hg status --all -R share-child
68 $ hg status --all -R share-child
69 C nf0
69 C nf0
70 C nf1
70 C nf1
71 C nf2
71 C nf2
72 C nf3
72 C nf3
73 C nf4
73 C nf4
74 C nf5
74 C nf5
75 C nf6
75 C nf6
76 C nf7
76 C nf7
77 C nf8
77 C nf8
78 C nf9
78 C nf9
79 $ hg log -l 3 -R share-child
79 $ hg log -l 3 -R share-child
80 changeset: 9:0059eb38e4a4
80 changeset: 9:0059eb38e4a4
81 tag: tip
81 tag: tip
82 user: debugbuilddag
82 user: debugbuilddag
83 date: Thu Jan 01 00:00:09 1970 +0000
83 date: Thu Jan 01 00:00:09 1970 +0000
84 summary: r9
84 summary: r9
85
85
86 changeset: 8:4d5be70c8130
86 changeset: 8:4d5be70c8130
87 user: debugbuilddag
87 user: debugbuilddag
88 date: Thu Jan 01 00:00:08 1970 +0000
88 date: Thu Jan 01 00:00:08 1970 +0000
89 summary: r8
89 summary: r8
90
90
91 changeset: 7:e60bfe72517e
91 changeset: 7:e60bfe72517e
92 user: debugbuilddag
92 user: debugbuilddag
93 date: Thu Jan 01 00:00:07 1970 +0000
93 date: Thu Jan 01 00:00:07 1970 +0000
94 summary: r7
94 summary: r7
95
95
96 $ hg status --all -R share-parent
96 $ hg status --all -R share-parent
97 C nf0
97 C nf0
98 C nf1
98 C nf1
99 C nf2
99 C nf2
100 C nf3
100 C nf3
101 C nf4
101 C nf4
102 C nf5
102 C nf5
103 C nf6
103 C nf6
104 C nf7
104 C nf7
105 C nf8
105 C nf8
106 C nf9
106 C nf9
107 $ hg log -l 3 -R share-parent
107 $ hg log -l 3 -R share-parent
108 changeset: 9:0059eb38e4a4
108 changeset: 9:0059eb38e4a4
109 tag: tip
109 tag: tip
110 user: debugbuilddag
110 user: debugbuilddag
111 date: Thu Jan 01 00:00:09 1970 +0000
111 date: Thu Jan 01 00:00:09 1970 +0000
112 summary: r9
112 summary: r9
113
113
114 changeset: 8:4d5be70c8130
114 changeset: 8:4d5be70c8130
115 user: debugbuilddag
115 user: debugbuilddag
116 date: Thu Jan 01 00:00:08 1970 +0000
116 date: Thu Jan 01 00:00:08 1970 +0000
117 summary: r8
117 summary: r8
118
118
119 changeset: 7:e60bfe72517e
119 changeset: 7:e60bfe72517e
120 user: debugbuilddag
120 user: debugbuilddag
121 date: Thu Jan 01 00:00:07 1970 +0000
121 date: Thu Jan 01 00:00:07 1970 +0000
122 summary: r7
122 summary: r7
123
123
124
124
125 $ hg -R share-child debugupgraderepo --config format.use-dirstate-v2=no --quiet --run
125 $ hg -R share-child debugupgraderepo --config format.use-dirstate-v2=no --quiet --run
126 upgrade will perform the following actions:
126 upgrade will perform the following actions:
127
127
128 requirements
128 requirements
129 preserved: * (glob)
129 preserved: * (glob)
130 removed: dirstate-v2
130 removed: dirstate-v2
131
131
132 no revlogs to process
132 no revlogs to process
133
133
134 $ hg debugformat -R share-child | grep dirstate-v2
134 $ hg debugformat -R share-child | grep dirstate-v2
135 dirstate-v2: no
135 dirstate-v2: no
136 $ hg debugformat -R share-parent | grep dirstate-v2
136 $ hg debugformat -R share-parent | grep dirstate-v2
137 dirstate-v2: no
137 dirstate-v2: no
138 $ hg status --all -R share-child
138 $ hg status --all -R share-child
139 C nf0
139 C nf0
140 C nf1
140 C nf1
141 C nf2
141 C nf2
142 C nf3
142 C nf3
143 C nf4
143 C nf4
144 C nf5
144 C nf5
145 C nf6
145 C nf6
146 C nf7
146 C nf7
147 C nf8
147 C nf8
148 C nf9
148 C nf9
149 $ hg log -l 3 -R share-child
149 $ hg log -l 3 -R share-child
150 changeset: 9:0059eb38e4a4
150 changeset: 9:0059eb38e4a4
151 tag: tip
151 tag: tip
152 user: debugbuilddag
152 user: debugbuilddag
153 date: Thu Jan 01 00:00:09 1970 +0000
153 date: Thu Jan 01 00:00:09 1970 +0000
154 summary: r9
154 summary: r9
155
155
156 changeset: 8:4d5be70c8130
156 changeset: 8:4d5be70c8130
157 user: debugbuilddag
157 user: debugbuilddag
158 date: Thu Jan 01 00:00:08 1970 +0000
158 date: Thu Jan 01 00:00:08 1970 +0000
159 summary: r8
159 summary: r8
160
160
161 changeset: 7:e60bfe72517e
161 changeset: 7:e60bfe72517e
162 user: debugbuilddag
162 user: debugbuilddag
163 date: Thu Jan 01 00:00:07 1970 +0000
163 date: Thu Jan 01 00:00:07 1970 +0000
164 summary: r7
164 summary: r7
165
165
166 $ hg status --all -R share-parent
166 $ hg status --all -R share-parent
167 C nf0
167 C nf0
168 C nf1
168 C nf1
169 C nf2
169 C nf2
170 C nf3
170 C nf3
171 C nf4
171 C nf4
172 C nf5
172 C nf5
173 C nf6
173 C nf6
174 C nf7
174 C nf7
175 C nf8
175 C nf8
176 C nf9
176 C nf9
177 $ hg log -l 3 -R share-parent
177 $ hg log -l 3 -R share-parent
178 changeset: 9:0059eb38e4a4
178 changeset: 9:0059eb38e4a4
179 tag: tip
179 tag: tip
180 user: debugbuilddag
180 user: debugbuilddag
181 date: Thu Jan 01 00:00:09 1970 +0000
181 date: Thu Jan 01 00:00:09 1970 +0000
182 summary: r9
182 summary: r9
183
183
184 changeset: 8:4d5be70c8130
184 changeset: 8:4d5be70c8130
185 user: debugbuilddag
185 user: debugbuilddag
186 date: Thu Jan 01 00:00:08 1970 +0000
186 date: Thu Jan 01 00:00:08 1970 +0000
187 summary: r8
187 summary: r8
188
188
189 changeset: 7:e60bfe72517e
189 changeset: 7:e60bfe72517e
190 user: debugbuilddag
190 user: debugbuilddag
191 date: Thu Jan 01 00:00:07 1970 +0000
191 date: Thu Jan 01 00:00:07 1970 +0000
192 summary: r7
192 summary: r7
193
193
194
194
195 Do not yet support upgrading treemanifest repos
195 Do not yet support upgrading treemanifest repos
196
196
197 $ hg --config experimental.treemanifest=true init treemanifest
197 $ hg --config experimental.treemanifest=true init treemanifest
198 $ hg -R treemanifest debugupgraderepo
198 $ hg -R treemanifest debugupgraderepo
199 abort: cannot upgrade repository; unsupported source requirement: treemanifest
199 abort: cannot upgrade repository; unsupported source requirement: treemanifest
200 [255]
200 [255]
201
201
202 Cannot add treemanifest requirement during upgrade
202 Cannot add treemanifest requirement during upgrade
203
203
204 $ hg init disallowaddedreq
204 $ hg init disallowaddedreq
205 $ hg -R disallowaddedreq --config experimental.treemanifest=true debugupgraderepo
205 $ hg -R disallowaddedreq --config experimental.treemanifest=true debugupgraderepo
206 abort: cannot upgrade repository; do not support adding requirement: treemanifest
206 abort: cannot upgrade repository; do not support adding requirement: treemanifest
207 [255]
207 [255]
208
208
209 An upgrade of a repository created with recommended settings only suggests optimizations
209 An upgrade of a repository created with recommended settings only suggests optimizations
210
210
211 $ hg init empty
211 $ hg init empty
212 $ cd empty
212 $ cd empty
213 $ hg debugformat
213 $ hg debugformat
214 format-variant repo
214 format-variant repo
215 fncache: yes
215 fncache: yes
216 dirstate-v2: no
216 dirstate-v2: no
217 tracked-hint: no
217 tracked-hint: no
218 dotencode: yes
218 dotencode: yes
219 generaldelta: yes
219 generaldelta: yes
220 share-safe: yes
220 share-safe: yes
221 sparserevlog: yes
221 sparserevlog: yes
222 persistent-nodemap: no (no-rust !)
222 persistent-nodemap: no (no-rust !)
223 persistent-nodemap: yes (rust !)
223 persistent-nodemap: yes (rust !)
224 copies-sdc: no
224 copies-sdc: no
225 revlog-v2: no
225 revlog-v2: no
226 changelog-v2: no
226 changelog-v2: no
227 plain-cl-delta: yes
227 plain-cl-delta: yes
228 compression: zlib
228 compression: zlib
229 compression-level: default
229 compression-level: default
230 $ hg debugformat --verbose
230 $ hg debugformat --verbose
231 format-variant repo config default
231 format-variant repo config default
232 fncache: yes yes yes
232 fncache: yes yes yes
233 dirstate-v2: no no no
233 dirstate-v2: no no no
234 tracked-hint: no no no
234 tracked-hint: no no no
235 dotencode: yes yes yes
235 dotencode: yes yes yes
236 generaldelta: yes yes yes
236 generaldelta: yes yes yes
237 share-safe: yes yes yes
237 share-safe: yes yes yes
238 sparserevlog: yes yes yes
238 sparserevlog: yes yes yes
239 persistent-nodemap: no no no (no-rust !)
239 persistent-nodemap: no no no (no-rust !)
240 persistent-nodemap: yes yes no (rust !)
240 persistent-nodemap: yes yes no (rust !)
241 copies-sdc: no no no
241 copies-sdc: no no no
242 revlog-v2: no no no
242 revlog-v2: no no no
243 changelog-v2: no no no
243 changelog-v2: no no no
244 plain-cl-delta: yes yes yes
244 plain-cl-delta: yes yes yes
245 compression: zlib zlib zlib (no-zstd !)
245 compression: zlib zlib zlib (no-zstd !)
246 compression: zlib zlib zstd (zstd !)
246 compression: zlib zlib zstd (zstd !)
247 compression-level: default default default
247 compression-level: default default default
248 $ hg debugformat --verbose --config format.usefncache=no
248 $ hg debugformat --verbose --config format.usefncache=no
249 format-variant repo config default
249 format-variant repo config default
250 fncache: yes no yes
250 fncache: yes no yes
251 dirstate-v2: no no no
251 dirstate-v2: no no no
252 tracked-hint: no no no
252 tracked-hint: no no no
253 dotencode: yes no yes
253 dotencode: yes no yes
254 generaldelta: yes yes yes
254 generaldelta: yes yes yes
255 share-safe: yes yes yes
255 share-safe: yes yes yes
256 sparserevlog: yes yes yes
256 sparserevlog: yes yes yes
257 persistent-nodemap: no no no (no-rust !)
257 persistent-nodemap: no no no (no-rust !)
258 persistent-nodemap: yes yes no (rust !)
258 persistent-nodemap: yes yes no (rust !)
259 copies-sdc: no no no
259 copies-sdc: no no no
260 revlog-v2: no no no
260 revlog-v2: no no no
261 changelog-v2: no no no
261 changelog-v2: no no no
262 plain-cl-delta: yes yes yes
262 plain-cl-delta: yes yes yes
263 compression: zlib zlib zlib (no-zstd !)
263 compression: zlib zlib zlib (no-zstd !)
264 compression: zlib zlib zstd (zstd !)
264 compression: zlib zlib zstd (zstd !)
265 compression-level: default default default
265 compression-level: default default default
266 $ hg debugformat --verbose --config format.usefncache=no --color=debug
266 $ hg debugformat --verbose --config format.usefncache=no --color=debug
267 format-variant repo config default
267 format-variant repo config default
268 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
268 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
269 [formatvariant.name.uptodate|dirstate-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
269 [formatvariant.name.uptodate|dirstate-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
270 [formatvariant.name.uptodate|tracked-hint: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
270 [formatvariant.name.uptodate|tracked-hint: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
271 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
271 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
272 [formatvariant.name.uptodate|generaldelta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
272 [formatvariant.name.uptodate|generaldelta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
273 [formatvariant.name.uptodate|share-safe: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
273 [formatvariant.name.uptodate|share-safe: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
274 [formatvariant.name.uptodate|sparserevlog: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
274 [formatvariant.name.uptodate|sparserevlog: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
275 [formatvariant.name.uptodate|persistent-nodemap:][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no] (no-rust !)
275 [formatvariant.name.uptodate|persistent-nodemap:][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no] (no-rust !)
276 [formatvariant.name.mismatchdefault|persistent-nodemap:][formatvariant.repo.mismatchdefault| yes][formatvariant.config.special| yes][formatvariant.default| no] (rust !)
276 [formatvariant.name.mismatchdefault|persistent-nodemap:][formatvariant.repo.mismatchdefault| yes][formatvariant.config.special| yes][formatvariant.default| no] (rust !)
277 [formatvariant.name.uptodate|copies-sdc: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
277 [formatvariant.name.uptodate|copies-sdc: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
278 [formatvariant.name.uptodate|revlog-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
278 [formatvariant.name.uptodate|revlog-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
279 [formatvariant.name.uptodate|changelog-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
279 [formatvariant.name.uptodate|changelog-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
280 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
280 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
281 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib] (no-zstd !)
281 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib] (no-zstd !)
282 [formatvariant.name.mismatchdefault|compression: ][formatvariant.repo.mismatchdefault| zlib][formatvariant.config.special| zlib][formatvariant.default| zstd] (zstd !)
282 [formatvariant.name.mismatchdefault|compression: ][formatvariant.repo.mismatchdefault| zlib][formatvariant.config.special| zlib][formatvariant.default| zstd] (zstd !)
283 [formatvariant.name.uptodate|compression-level: ][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
283 [formatvariant.name.uptodate|compression-level: ][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
284 $ hg debugformat -Tjson
284 $ hg debugformat -Tjson
285 [
285 [
286 {
286 {
287 "config": true,
287 "config": true,
288 "default": true,
288 "default": true,
289 "name": "fncache",
289 "name": "fncache",
290 "repo": true
290 "repo": true
291 },
291 },
292 {
292 {
293 "config": false,
293 "config": false,
294 "default": false,
294 "default": false,
295 "name": "dirstate-v2",
295 "name": "dirstate-v2",
296 "repo": false
296 "repo": false
297 },
297 },
298 {
298 {
299 "config": false,
299 "config": false,
300 "default": false,
300 "default": false,
301 "name": "tracked-hint",
301 "name": "tracked-hint",
302 "repo": false
302 "repo": false
303 },
303 },
304 {
304 {
305 "config": true,
305 "config": true,
306 "default": true,
306 "default": true,
307 "name": "dotencode",
307 "name": "dotencode",
308 "repo": true
308 "repo": true
309 },
309 },
310 {
310 {
311 "config": true,
311 "config": true,
312 "default": true,
312 "default": true,
313 "name": "generaldelta",
313 "name": "generaldelta",
314 "repo": true
314 "repo": true
315 },
315 },
316 {
316 {
317 "config": true,
317 "config": true,
318 "default": true,
318 "default": true,
319 "name": "share-safe",
319 "name": "share-safe",
320 "repo": true
320 "repo": true
321 },
321 },
322 {
322 {
323 "config": true,
323 "config": true,
324 "default": true,
324 "default": true,
325 "name": "sparserevlog",
325 "name": "sparserevlog",
326 "repo": true
326 "repo": true
327 },
327 },
328 {
328 {
329 "config": false, (no-rust !)
329 "config": false, (no-rust !)
330 "config": true, (rust !)
330 "config": true, (rust !)
331 "default": false,
331 "default": false,
332 "name": "persistent-nodemap",
332 "name": "persistent-nodemap",
333 "repo": false (no-rust !)
333 "repo": false (no-rust !)
334 "repo": true (rust !)
334 "repo": true (rust !)
335 },
335 },
336 {
336 {
337 "config": false,
337 "config": false,
338 "default": false,
338 "default": false,
339 "name": "copies-sdc",
339 "name": "copies-sdc",
340 "repo": false
340 "repo": false
341 },
341 },
342 {
342 {
343 "config": false,
343 "config": false,
344 "default": false,
344 "default": false,
345 "name": "revlog-v2",
345 "name": "revlog-v2",
346 "repo": false
346 "repo": false
347 },
347 },
348 {
348 {
349 "config": false,
349 "config": false,
350 "default": false,
350 "default": false,
351 "name": "changelog-v2",
351 "name": "changelog-v2",
352 "repo": false
352 "repo": false
353 },
353 },
354 {
354 {
355 "config": true,
355 "config": true,
356 "default": true,
356 "default": true,
357 "name": "plain-cl-delta",
357 "name": "plain-cl-delta",
358 "repo": true
358 "repo": true
359 },
359 },
360 {
360 {
361 "config": "zlib",
361 "config": "zlib",
362 "default": "zlib", (no-zstd !)
362 "default": "zlib", (no-zstd !)
363 "default": "zstd", (zstd !)
363 "default": "zstd", (zstd !)
364 "name": "compression",
364 "name": "compression",
365 "repo": "zlib"
365 "repo": "zlib"
366 },
366 },
367 {
367 {
368 "config": "default",
368 "config": "default",
369 "default": "default",
369 "default": "default",
370 "name": "compression-level",
370 "name": "compression-level",
371 "repo": "default"
371 "repo": "default"
372 }
372 }
373 ]
373 ]
374 $ hg debugupgraderepo
374 $ hg debugupgraderepo
375 (no format upgrades found in existing repository)
375 (no format upgrades found in existing repository)
376 performing an upgrade with "--run" will make the following changes:
376 performing an upgrade with "--run" will make the following changes:
377
377
378 requirements
378 requirements
379 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
379 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
380 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
380 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
381
381
382 no revlogs to process
382 no revlogs to process
383
383
384 additional optimizations are available by specifying "--optimize <name>":
384 additional optimizations are available by specifying "--optimize <name>":
385
385
386 re-delta-parent
386 re-delta-parent
387 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
387 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
388
388
389 re-delta-multibase
389 re-delta-multibase
390 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
390 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
391
391
392 re-delta-all
392 re-delta-all
393 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
393 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
394
394
395 re-delta-fulladd
395 re-delta-fulladd
396 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
396 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
397
397
398
398
399 $ hg debugupgraderepo --quiet
399 $ hg debugupgraderepo --quiet
400 requirements
400 requirements
401 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
401 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
402 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
402 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
403
403
404 no revlogs to process
404 no revlogs to process
405
405
406
406
407 --optimize can be used to add optimizations
407 --optimize can be used to add optimizations
408
408
409 $ hg debugupgrade --optimize 're-delta-parent'
409 $ hg debugupgrade --optimize 're-delta-parent'
410 (no format upgrades found in existing repository)
410 (no format upgrades found in existing repository)
411 performing an upgrade with "--run" will make the following changes:
411 performing an upgrade with "--run" will make the following changes:
412
412
413 requirements
413 requirements
414 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
414 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
415 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
415 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
416
416
417 optimisations: re-delta-parent
417 optimisations: re-delta-parent
418
418
419 re-delta-parent
419 re-delta-parent
420 deltas within internal storage will choose a new base revision if needed
420 deltas within internal storage will choose a new base revision if needed
421
421
422 processed revlogs:
422 processed revlogs:
423 - all-filelogs
423 - all-filelogs
424 - changelog
424 - changelog
425 - manifest
425 - manifest
426
426
427 additional optimizations are available by specifying "--optimize <name>":
427 additional optimizations are available by specifying "--optimize <name>":
428
428
429 re-delta-multibase
429 re-delta-multibase
430 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
430 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
431
431
432 re-delta-all
432 re-delta-all
433 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
433 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
434
434
435 re-delta-fulladd
435 re-delta-fulladd
436 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
436 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
437
437
438
438
439 modern form of the option
439 modern form of the option
440
440
441 $ hg debugupgrade --optimize re-delta-parent
441 $ hg debugupgrade --optimize re-delta-parent
442 (no format upgrades found in existing repository)
442 (no format upgrades found in existing repository)
443 performing an upgrade with "--run" will make the following changes:
443 performing an upgrade with "--run" will make the following changes:
444
444
445 requirements
445 requirements
446 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
446 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
447 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
447 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
448
448
449 optimisations: re-delta-parent
449 optimisations: re-delta-parent
450
450
451 re-delta-parent
451 re-delta-parent
452 deltas within internal storage will choose a new base revision if needed
452 deltas within internal storage will choose a new base revision if needed
453
453
454 processed revlogs:
454 processed revlogs:
455 - all-filelogs
455 - all-filelogs
456 - changelog
456 - changelog
457 - manifest
457 - manifest
458
458
459 additional optimizations are available by specifying "--optimize <name>":
459 additional optimizations are available by specifying "--optimize <name>":
460
460
461 re-delta-multibase
461 re-delta-multibase
462 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
462 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
463
463
464 re-delta-all
464 re-delta-all
465 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
465 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
466
466
467 re-delta-fulladd
467 re-delta-fulladd
468 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
468 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
469
469
470
470
471 $ hg debugupgrade --optimize re-delta-parent --quiet
471 $ hg debugupgrade --optimize re-delta-parent --quiet
472 requirements
472 requirements
473 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
473 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
474 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
474 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
475
475
476 optimisations: re-delta-parent
476 optimisations: re-delta-parent
477
477
478 processed revlogs:
478 processed revlogs:
479 - all-filelogs
479 - all-filelogs
480 - changelog
480 - changelog
481 - manifest
481 - manifest
482
482
483
483
484 passing multiple optimization:
484 passing multiple optimization:
485
485
486 $ hg debugupgrade --optimize re-delta-parent --optimize re-delta-multibase --quiet
486 $ hg debugupgrade --optimize re-delta-parent --optimize re-delta-multibase --quiet
487 requirements
487 requirements
488 preserved: * (glob)
488 preserved: * (glob)
489
489
490 optimisations: re-delta-multibase, re-delta-parent
490 optimisations: re-delta-multibase, re-delta-parent
491
491
492 processed revlogs:
492 processed revlogs:
493 - all-filelogs
493 - all-filelogs
494 - changelog
494 - changelog
495 - manifest
495 - manifest
496
496
497
497
498 unknown optimization:
498 unknown optimization:
499
499
500 $ hg debugupgrade --optimize foobar
500 $ hg debugupgrade --optimize foobar
501 abort: unknown optimization action requested: foobar
501 abort: unknown optimization action requested: foobar
502 (run without arguments to see valid optimizations)
502 (run without arguments to see valid optimizations)
503 [255]
503 [255]
504
504
505 Various sub-optimal detections work
505 Various sub-optimal detections work
506
506
507 $ cat > .hg/requires << EOF
507 $ cat > .hg/requires << EOF
508 > revlogv1
508 > revlogv1
509 > store
509 > store
510 > EOF
510 > EOF
511
511
512 $ hg debugformat
512 $ hg debugformat
513 format-variant repo
513 format-variant repo
514 fncache: no
514 fncache: no
515 dirstate-v2: no
515 dirstate-v2: no
516 tracked-hint: no
516 tracked-hint: no
517 dotencode: no
517 dotencode: no
518 generaldelta: no
518 generaldelta: no
519 share-safe: no
519 share-safe: no
520 sparserevlog: no
520 sparserevlog: no
521 persistent-nodemap: no
521 persistent-nodemap: no
522 copies-sdc: no
522 copies-sdc: no
523 revlog-v2: no
523 revlog-v2: no
524 changelog-v2: no
524 changelog-v2: no
525 plain-cl-delta: yes
525 plain-cl-delta: yes
526 compression: zlib
526 compression: zlib
527 compression-level: default
527 compression-level: default
528 $ hg debugformat --verbose
528 $ hg debugformat --verbose
529 format-variant repo config default
529 format-variant repo config default
530 fncache: no yes yes
530 fncache: no yes yes
531 dirstate-v2: no no no
531 dirstate-v2: no no no
532 tracked-hint: no no no
532 tracked-hint: no no no
533 dotencode: no yes yes
533 dotencode: no yes yes
534 generaldelta: no yes yes
534 generaldelta: no yes yes
535 share-safe: no yes yes
535 share-safe: no yes yes
536 sparserevlog: no yes yes
536 sparserevlog: no yes yes
537 persistent-nodemap: no no no (no-rust !)
537 persistent-nodemap: no no no (no-rust !)
538 persistent-nodemap: no yes no (rust !)
538 persistent-nodemap: no yes no (rust !)
539 copies-sdc: no no no
539 copies-sdc: no no no
540 revlog-v2: no no no
540 revlog-v2: no no no
541 changelog-v2: no no no
541 changelog-v2: no no no
542 plain-cl-delta: yes yes yes
542 plain-cl-delta: yes yes yes
543 compression: zlib zlib zlib (no-zstd !)
543 compression: zlib zlib zlib (no-zstd !)
544 compression: zlib zlib zstd (zstd !)
544 compression: zlib zlib zstd (zstd !)
545 compression-level: default default default
545 compression-level: default default default
546 $ hg debugformat --verbose --config format.usegeneraldelta=no
546 $ hg debugformat --verbose --config format.usegeneraldelta=no
547 format-variant repo config default
547 format-variant repo config default
548 fncache: no yes yes
548 fncache: no yes yes
549 dirstate-v2: no no no
549 dirstate-v2: no no no
550 tracked-hint: no no no
550 tracked-hint: no no no
551 dotencode: no yes yes
551 dotencode: no yes yes
552 generaldelta: no no yes
552 generaldelta: no no yes
553 share-safe: no yes yes
553 share-safe: no yes yes
554 sparserevlog: no no yes
554 sparserevlog: no no yes
555 persistent-nodemap: no no no (no-rust !)
555 persistent-nodemap: no no no (no-rust !)
556 persistent-nodemap: no yes no (rust !)
556 persistent-nodemap: no yes no (rust !)
557 copies-sdc: no no no
557 copies-sdc: no no no
558 revlog-v2: no no no
558 revlog-v2: no no no
559 changelog-v2: no no no
559 changelog-v2: no no no
560 plain-cl-delta: yes yes yes
560 plain-cl-delta: yes yes yes
561 compression: zlib zlib zlib (no-zstd !)
561 compression: zlib zlib zlib (no-zstd !)
562 compression: zlib zlib zstd (zstd !)
562 compression: zlib zlib zstd (zstd !)
563 compression-level: default default default
563 compression-level: default default default
564 $ hg debugformat --verbose --config format.usegeneraldelta=no --color=debug
564 $ hg debugformat --verbose --config format.usegeneraldelta=no --color=debug
565 format-variant repo config default
565 format-variant repo config default
566 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
566 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
567 [formatvariant.name.uptodate|dirstate-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
567 [formatvariant.name.uptodate|dirstate-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
568 [formatvariant.name.uptodate|tracked-hint: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
568 [formatvariant.name.uptodate|tracked-hint: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
569 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
569 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
570 [formatvariant.name.mismatchdefault|generaldelta: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
570 [formatvariant.name.mismatchdefault|generaldelta: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
571 [formatvariant.name.mismatchconfig|share-safe: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
571 [formatvariant.name.mismatchconfig|share-safe: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
572 [formatvariant.name.mismatchdefault|sparserevlog: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
572 [formatvariant.name.mismatchdefault|sparserevlog: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
573 [formatvariant.name.uptodate|persistent-nodemap:][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no] (no-rust !)
573 [formatvariant.name.uptodate|persistent-nodemap:][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no] (no-rust !)
574 [formatvariant.name.mismatchconfig|persistent-nodemap:][formatvariant.repo.mismatchconfig| no][formatvariant.config.special| yes][formatvariant.default| no] (rust !)
574 [formatvariant.name.mismatchconfig|persistent-nodemap:][formatvariant.repo.mismatchconfig| no][formatvariant.config.special| yes][formatvariant.default| no] (rust !)
575 [formatvariant.name.uptodate|copies-sdc: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
575 [formatvariant.name.uptodate|copies-sdc: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
576 [formatvariant.name.uptodate|revlog-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
576 [formatvariant.name.uptodate|revlog-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
577 [formatvariant.name.uptodate|changelog-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
577 [formatvariant.name.uptodate|changelog-v2: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
578 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
578 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
579 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib] (no-zstd !)
579 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib] (no-zstd !)
580 [formatvariant.name.mismatchdefault|compression: ][formatvariant.repo.mismatchdefault| zlib][formatvariant.config.special| zlib][formatvariant.default| zstd] (zstd !)
580 [formatvariant.name.mismatchdefault|compression: ][formatvariant.repo.mismatchdefault| zlib][formatvariant.config.special| zlib][formatvariant.default| zstd] (zstd !)
581 [formatvariant.name.uptodate|compression-level: ][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
581 [formatvariant.name.uptodate|compression-level: ][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
582 $ hg debugupgraderepo
582 $ hg debugupgraderepo
583 note: selecting all-filelogs for processing to change: dotencode
583 note: selecting all-filelogs for processing to change: dotencode
584 note: selecting all-manifestlogs for processing to change: dotencode
584 note: selecting all-manifestlogs for processing to change: dotencode
585 note: selecting changelog for processing to change: dotencode
585 note: selecting changelog for processing to change: dotencode
586
586
587 repository lacks features recommended by current config options:
587 repository lacks features recommended by current config options:
588
588
589 fncache
589 fncache
590 long and reserved filenames may not work correctly; repository performance is sub-optimal
590 long and reserved filenames may not work correctly; repository performance is sub-optimal
591
591
592 dotencode
592 dotencode
593 storage of filenames beginning with a period or space may not work correctly
593 storage of filenames beginning with a period or space may not work correctly
594
594
595 generaldelta
595 generaldelta
596 deltas within internal storage are unable to choose optimal revisions; repository is larger and slower than it could be; interaction with other repositories may require extra network and CPU resources, making "hg push" and "hg pull" slower
596 deltas within internal storage are unable to choose optimal revisions; repository is larger and slower than it could be; interaction with other repositories may require extra network and CPU resources, making "hg push" and "hg pull" slower
597
597
598 share-safe
598 share-safe
599 old shared repositories do not share source repository requirements and config. This leads to various problems when the source repository format is upgraded or some new extensions are enabled.
599 old shared repositories do not share source repository requirements and config. This leads to various problems when the source repository format is upgraded or some new extensions are enabled.
600
600
601 sparserevlog
601 sparserevlog
602 in order to limit disk reading and memory usage on older version, the span of a delta chain from its root to its end is limited, whatever the relevant data in this span. This can severly limit Mercurial ability to build good chain of delta resulting is much more storage space being taken and limit reusability of on disk delta during exchange.
602 in order to limit disk reading and memory usage on older version, the span of a delta chain from its root to its end is limited, whatever the relevant data in this span. This can severly limit Mercurial ability to build good chain of delta resulting is much more storage space being taken and limit reusability of on disk delta during exchange.
603
603
604 persistent-nodemap (rust !)
604 persistent-nodemap (rust !)
605 persist the node -> rev mapping on disk to speedup lookup (rust !)
605 persist the node -> rev mapping on disk to speedup lookup (rust !)
606 (rust !)
606 (rust !)
607
607
608 performing an upgrade with "--run" will make the following changes:
608 performing an upgrade with "--run" will make the following changes:
609
609
610 requirements
610 requirements
611 preserved: revlogv1, store
611 preserved: revlogv1, store
612 added: dotencode, fncache, generaldelta, share-safe, sparserevlog (no-rust !)
612 added: dotencode, fncache, generaldelta, share-safe, sparserevlog (no-rust !)
613 added: dotencode, fncache, generaldelta, persistent-nodemap, share-safe, sparserevlog (rust !)
613 added: dotencode, fncache, generaldelta, persistent-nodemap, share-safe, sparserevlog (rust !)
614
614
615 fncache
615 fncache
616 repository will be more resilient to storing certain paths and performance of certain operations should be improved
616 repository will be more resilient to storing certain paths and performance of certain operations should be improved
617
617
618 dotencode
618 dotencode
619 repository will be better able to store files beginning with a space or period
619 repository will be better able to store files beginning with a space or period
620
620
621 generaldelta
621 generaldelta
622 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
622 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
623
623
624 share-safe
624 share-safe
625 Upgrades a repository to share-safe format so that future shares of this repository share its requirements and configs.
625 Upgrades a repository to share-safe format so that future shares of this repository share its requirements and configs.
626
626
627 sparserevlog
627 sparserevlog
628 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
628 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
629
629
630 persistent-nodemap (rust !)
630 persistent-nodemap (rust !)
631 Speedup revision lookup by node id. (rust !)
631 Speedup revision lookup by node id. (rust !)
632 (rust !)
632 (rust !)
633 processed revlogs:
633 processed revlogs:
634 - all-filelogs
634 - all-filelogs
635 - changelog
635 - changelog
636 - manifest
636 - manifest
637
637
638 additional optimizations are available by specifying "--optimize <name>":
638 additional optimizations are available by specifying "--optimize <name>":
639
639
640 re-delta-parent
640 re-delta-parent
641 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
641 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
642
642
643 re-delta-multibase
643 re-delta-multibase
644 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
644 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
645
645
646 re-delta-all
646 re-delta-all
647 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
647 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
648
648
649 re-delta-fulladd
649 re-delta-fulladd
650 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
650 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
651
651
652 $ hg debugupgraderepo --quiet
652 $ hg debugupgraderepo --quiet
653 requirements
653 requirements
654 preserved: revlogv1, store
654 preserved: revlogv1, store
655 added: dotencode, fncache, generaldelta, share-safe, sparserevlog (no-rust !)
655 added: dotencode, fncache, generaldelta, share-safe, sparserevlog (no-rust !)
656 added: dotencode, fncache, generaldelta, persistent-nodemap, share-safe, sparserevlog (rust !)
656 added: dotencode, fncache, generaldelta, persistent-nodemap, share-safe, sparserevlog (rust !)
657
657
658 processed revlogs:
658 processed revlogs:
659 - all-filelogs
659 - all-filelogs
660 - changelog
660 - changelog
661 - manifest
661 - manifest
662
662
663
663
664 $ hg --config format.dotencode=false debugupgraderepo
664 $ hg --config format.dotencode=false debugupgraderepo
665 note: selecting all-filelogs for processing to change: fncache
665 note: selecting all-filelogs for processing to change: fncache
666 note: selecting all-manifestlogs for processing to change: fncache
666 note: selecting all-manifestlogs for processing to change: fncache
667 note: selecting changelog for processing to change: fncache
667 note: selecting changelog for processing to change: fncache
668
668
669 repository lacks features recommended by current config options:
669 repository lacks features recommended by current config options:
670
670
671 fncache
671 fncache
672 long and reserved filenames may not work correctly; repository performance is sub-optimal
672 long and reserved filenames may not work correctly; repository performance is sub-optimal
673
673
674 generaldelta
674 generaldelta
675 deltas within internal storage are unable to choose optimal revisions; repository is larger and slower than it could be; interaction with other repositories may require extra network and CPU resources, making "hg push" and "hg pull" slower
675 deltas within internal storage are unable to choose optimal revisions; repository is larger and slower than it could be; interaction with other repositories may require extra network and CPU resources, making "hg push" and "hg pull" slower
676
676
677 share-safe
677 share-safe
678 old shared repositories do not share source repository requirements and config. This leads to various problems when the source repository format is upgraded or some new extensions are enabled.
678 old shared repositories do not share source repository requirements and config. This leads to various problems when the source repository format is upgraded or some new extensions are enabled.
679
679
680 sparserevlog
680 sparserevlog
681 in order to limit disk reading and memory usage on older version, the span of a delta chain from its root to its end is limited, whatever the relevant data in this span. This can severly limit Mercurial ability to build good chain of delta resulting is much more storage space being taken and limit reusability of on disk delta during exchange.
681 in order to limit disk reading and memory usage on older version, the span of a delta chain from its root to its end is limited, whatever the relevant data in this span. This can severly limit Mercurial ability to build good chain of delta resulting is much more storage space being taken and limit reusability of on disk delta during exchange.
682
682
683 persistent-nodemap (rust !)
683 persistent-nodemap (rust !)
684 persist the node -> rev mapping on disk to speedup lookup (rust !)
684 persist the node -> rev mapping on disk to speedup lookup (rust !)
685 (rust !)
685 (rust !)
686 repository lacks features used by the default config options:
686 repository lacks features used by the default config options:
687
687
688 dotencode
688 dotencode
689 storage of filenames beginning with a period or space may not work correctly
689 storage of filenames beginning with a period or space may not work correctly
690
690
691
691
692 performing an upgrade with "--run" will make the following changes:
692 performing an upgrade with "--run" will make the following changes:
693
693
694 requirements
694 requirements
695 preserved: revlogv1, store
695 preserved: revlogv1, store
696 added: fncache, generaldelta, share-safe, sparserevlog (no-rust !)
696 added: fncache, generaldelta, share-safe, sparserevlog (no-rust !)
697 added: fncache, generaldelta, persistent-nodemap, share-safe, sparserevlog (rust !)
697 added: fncache, generaldelta, persistent-nodemap, share-safe, sparserevlog (rust !)
698
698
699 fncache
699 fncache
700 repository will be more resilient to storing certain paths and performance of certain operations should be improved
700 repository will be more resilient to storing certain paths and performance of certain operations should be improved
701
701
702 generaldelta
702 generaldelta
703 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
703 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
704
704
705 share-safe
705 share-safe
706 Upgrades a repository to share-safe format so that future shares of this repository share its requirements and configs.
706 Upgrades a repository to share-safe format so that future shares of this repository share its requirements and configs.
707
707
708 sparserevlog
708 sparserevlog
709 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
709 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
710
710
711 persistent-nodemap (rust !)
711 persistent-nodemap (rust !)
712 Speedup revision lookup by node id. (rust !)
712 Speedup revision lookup by node id. (rust !)
713 (rust !)
713 (rust !)
714 processed revlogs:
714 processed revlogs:
715 - all-filelogs
715 - all-filelogs
716 - changelog
716 - changelog
717 - manifest
717 - manifest
718
718
719 additional optimizations are available by specifying "--optimize <name>":
719 additional optimizations are available by specifying "--optimize <name>":
720
720
721 re-delta-parent
721 re-delta-parent
722 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
722 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
723
723
724 re-delta-multibase
724 re-delta-multibase
725 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
725 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
726
726
727 re-delta-all
727 re-delta-all
728 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
728 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
729
729
730 re-delta-fulladd
730 re-delta-fulladd
731 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
731 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
732
732
733
733
734 $ cd ..
734 $ cd ..
735
735
736 Upgrading a repository that is already modern essentially no-ops
736 Upgrading a repository that is already modern essentially no-ops
737
737
738 $ hg init modern
738 $ hg init modern
739 $ hg -R modern debugupgraderepo --run
739 $ hg -R modern debugupgraderepo --run
740 nothing to do
740 nothing to do
741
741
742 Upgrading a repository to generaldelta works
742 Upgrading a repository to generaldelta works
743
743
744 $ hg --config format.usegeneraldelta=false init upgradegd
744 $ hg --config format.usegeneraldelta=false init upgradegd
745 $ cd upgradegd
745 $ cd upgradegd
746 $ touch f0
746 $ touch f0
747 $ hg -q commit -A -m initial
747 $ hg -q commit -A -m initial
748 $ mkdir FooBarDirectory.d
748 $ mkdir FooBarDirectory.d
749 $ touch FooBarDirectory.d/f1
749 $ touch FooBarDirectory.d/f1
750 $ hg -q commit -A -m 'add f1'
750 $ hg -q commit -A -m 'add f1'
751 $ hg -q up -r 0
751 $ hg -q up -r 0
752 >>> import random
752 >>> import random
753 >>> random.seed(0) # have a reproducible content
753 >>> random.seed(0) # have a reproducible content
754 >>> with open("f2", "wb") as f:
754 >>> with open("f2", "wb") as f:
755 ... for i in range(100000):
755 ... for i in range(100000):
756 ... f.write(b"%d\n" % random.randint(1000000000, 9999999999)) and None
756 ... f.write(b"%d\n" % random.randint(1000000000, 9999999999)) and None
757 $ hg -q commit -A -m 'add f2'
757 $ hg -q commit -A -m 'add f2'
758
758
759 make sure we have a .d file
759 make sure we have a .d file
760
760
761 $ ls -d .hg/store/data/*
761 $ ls -d .hg/store/data/*
762 .hg/store/data/_foo_bar_directory.d.hg
762 .hg/store/data/_foo_bar_directory.d.hg
763 .hg/store/data/f0.i
763 .hg/store/data/f0.i
764 .hg/store/data/f2.d
764 .hg/store/data/f2.d
765 .hg/store/data/f2.i
765 .hg/store/data/f2.i
766
766
767 $ hg debugupgraderepo --run --config format.sparse-revlog=false
767 $ hg debugupgraderepo --run --config format.sparse-revlog=false
768 note: selecting all-filelogs for processing to change: generaldelta
768 note: selecting all-filelogs for processing to change: generaldelta
769 note: selecting all-manifestlogs for processing to change: generaldelta
769 note: selecting all-manifestlogs for processing to change: generaldelta
770 note: selecting changelog for processing to change: generaldelta
770 note: selecting changelog for processing to change: generaldelta
771
771
772 upgrade will perform the following actions:
772 upgrade will perform the following actions:
773
773
774 requirements
774 requirements
775 preserved: dotencode, fncache, revlogv1, share-safe, store (no-rust !)
775 preserved: dotencode, fncache, revlogv1, share-safe, store (no-rust !)
776 preserved: dotencode, fncache, persistent-nodemap, revlogv1, share-safe, store (rust !)
776 preserved: dotencode, fncache, persistent-nodemap, revlogv1, share-safe, store (rust !)
777 added: generaldelta
777 added: generaldelta
778
778
779 generaldelta
779 generaldelta
780 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
780 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
781
781
782 processed revlogs:
782 processed revlogs:
783 - all-filelogs
783 - all-filelogs
784 - changelog
784 - changelog
785 - manifest
785 - manifest
786
786
787 beginning upgrade...
787 beginning upgrade...
788 repository locked and read-only
788 repository locked and read-only
789 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
789 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
790 (it is safe to interrupt this process any time before data migration completes)
790 (it is safe to interrupt this process any time before data migration completes)
791 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
791 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
792 migrating 519 KB in store; 1.05 MB tracked data
792 migrating 519 KB in store; 1.05 MB tracked data
793 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
793 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
794 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
794 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
795 migrating 1 manifests containing 3 revisions (384 bytes in store; 238 bytes tracked data)
795 migrating 1 manifests containing 3 revisions (384 bytes in store; 238 bytes tracked data)
796 finished migrating 3 manifest revisions across 1 manifests; change in size: -17 bytes
796 finished migrating 3 manifest revisions across 1 manifests; change in size: -17 bytes
797 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
797 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
798 finished migrating 3 changelog revisions; change in size: 0 bytes
798 finished migrating 3 changelog revisions; change in size: 0 bytes
799 finished migrating 9 total revisions; total change in store size: -17 bytes
799 finished migrating 9 total revisions; total change in store size: -17 bytes
800 copying phaseroots
800 copying phaseroots
801 copying requires
801 copying requires
802 data fully upgraded in a temporary repository
802 data fully upgraded in a temporary repository
803 marking source repository as being upgraded; clients will be unable to read from repository
803 marking source repository as being upgraded; clients will be unable to read from repository
804 starting in-place swap of repository data
804 starting in-place swap of repository data
805 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
805 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
806 replacing store...
806 replacing store...
807 store replacement complete; repository was inconsistent for *s (glob)
807 store replacement complete; repository was inconsistent for *s (glob)
808 finalizing requirements file and making repository readable again
808 finalizing requirements file and making repository readable again
809 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
809 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
810 copy of old repository backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
810 copy of old repository backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
811 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
811 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
812
812
813 Original requirements backed up
813 Original requirements backed up
814
814
815 $ cat .hg/upgradebackup.*/requires
815 $ cat .hg/upgradebackup.*/requires
816 share-safe
816 share-safe
817 $ cat .hg/upgradebackup.*/store/requires
817 $ cat .hg/upgradebackup.*/store/requires
818 dotencode
818 dotencode
819 fncache
819 fncache
820 persistent-nodemap (rust !)
820 persistent-nodemap (rust !)
821 revlogv1
821 revlogv1
822 store
822 store
823 upgradeinprogress
823 upgradeinprogress
824
824
825 generaldelta added to original requirements files
825 generaldelta added to original requirements files
826
826
827 $ hg debugrequires
827 $ hg debugrequires
828 dotencode
828 dotencode
829 fncache
829 fncache
830 generaldelta
830 generaldelta
831 persistent-nodemap (rust !)
831 persistent-nodemap (rust !)
832 revlogv1
832 revlogv1
833 share-safe
833 share-safe
834 store
834 store
835
835
836 store directory has files we expect
836 store directory has files we expect
837
837
838 $ ls .hg/store
838 $ ls .hg/store
839 00changelog.i
839 00changelog.i
840 00manifest.i
840 00manifest.i
841 data
841 data
842 fncache
842 fncache
843 phaseroots
843 phaseroots
844 requires
844 requires
845 undo
845 undo
846 undo.backupfiles
846 undo.backupfiles
847
847
848 manifest should be generaldelta
848 manifest should be generaldelta
849
849
850 $ hg debugrevlog -m | grep flags
850 $ hg debugrevlog -m | grep flags
851 flags : inline, generaldelta
851 flags : inline, generaldelta
852
852
853 verify should be happy
853 verify should be happy
854
854
855 $ hg verify -q
855 $ hg verify -q
856
856
857 old store should be backed up
857 old store should be backed up
858
858
859 $ ls -d .hg/upgradebackup.*/
859 $ ls -d .hg/upgradebackup.*/
860 .hg/upgradebackup.*/ (glob)
860 .hg/upgradebackup.*/ (glob)
861 $ ls .hg/upgradebackup.*/store
861 $ ls .hg/upgradebackup.*/store
862 00changelog.i
862 00changelog.i
863 00manifest.i
863 00manifest.i
864 data
864 data
865 fncache
865 fncache
866 phaseroots
866 phaseroots
867 requires
867 requires
868 undo
868 undo
869 undo.backup.fncache
869 undo.backup.fncache.bck
870 undo.backupfiles
870 undo.backupfiles
871
871
872 unless --no-backup is passed
872 unless --no-backup is passed
873
873
874 $ rm -rf .hg/upgradebackup.*/
874 $ rm -rf .hg/upgradebackup.*/
875 $ hg debugupgraderepo --run --no-backup
875 $ hg debugupgraderepo --run --no-backup
876 note: selecting all-filelogs for processing to change: sparserevlog
876 note: selecting all-filelogs for processing to change: sparserevlog
877 note: selecting all-manifestlogs for processing to change: sparserevlog
877 note: selecting all-manifestlogs for processing to change: sparserevlog
878 note: selecting changelog for processing to change: sparserevlog
878 note: selecting changelog for processing to change: sparserevlog
879
879
880 upgrade will perform the following actions:
880 upgrade will perform the following actions:
881
881
882 requirements
882 requirements
883 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
883 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
884 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
884 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
885 added: sparserevlog
885 added: sparserevlog
886
886
887 sparserevlog
887 sparserevlog
888 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
888 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
889
889
890 processed revlogs:
890 processed revlogs:
891 - all-filelogs
891 - all-filelogs
892 - changelog
892 - changelog
893 - manifest
893 - manifest
894
894
895 beginning upgrade...
895 beginning upgrade...
896 repository locked and read-only
896 repository locked and read-only
897 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
897 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
898 (it is safe to interrupt this process any time before data migration completes)
898 (it is safe to interrupt this process any time before data migration completes)
899 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
899 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
900 migrating 519 KB in store; 1.05 MB tracked data
900 migrating 519 KB in store; 1.05 MB tracked data
901 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
901 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
902 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
902 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
903 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
903 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
904 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
904 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
905 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
905 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
906 finished migrating 3 changelog revisions; change in size: 0 bytes
906 finished migrating 3 changelog revisions; change in size: 0 bytes
907 finished migrating 9 total revisions; total change in store size: 0 bytes
907 finished migrating 9 total revisions; total change in store size: 0 bytes
908 copying phaseroots
908 copying phaseroots
909 copying requires
909 copying requires
910 data fully upgraded in a temporary repository
910 data fully upgraded in a temporary repository
911 marking source repository as being upgraded; clients will be unable to read from repository
911 marking source repository as being upgraded; clients will be unable to read from repository
912 starting in-place swap of repository data
912 starting in-place swap of repository data
913 replacing store...
913 replacing store...
914 store replacement complete; repository was inconsistent for * (glob)
914 store replacement complete; repository was inconsistent for * (glob)
915 finalizing requirements file and making repository readable again
915 finalizing requirements file and making repository readable again
916 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
916 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
917 $ ls -1 .hg/ | grep upgradebackup
917 $ ls -1 .hg/ | grep upgradebackup
918 [1]
918 [1]
919
919
920 We can restrict optimization to some revlog:
920 We can restrict optimization to some revlog:
921
921
922 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
922 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
923 upgrade will perform the following actions:
923 upgrade will perform the following actions:
924
924
925 requirements
925 requirements
926 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
926 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
927 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
927 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
928
928
929 optimisations: re-delta-parent
929 optimisations: re-delta-parent
930
930
931 re-delta-parent
931 re-delta-parent
932 deltas within internal storage will choose a new base revision if needed
932 deltas within internal storage will choose a new base revision if needed
933
933
934 processed revlogs:
934 processed revlogs:
935 - manifest
935 - manifest
936
936
937 beginning upgrade...
937 beginning upgrade...
938 repository locked and read-only
938 repository locked and read-only
939 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
939 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
940 (it is safe to interrupt this process any time before data migration completes)
940 (it is safe to interrupt this process any time before data migration completes)
941 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
941 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
942 migrating 519 KB in store; 1.05 MB tracked data
942 migrating 519 KB in store; 1.05 MB tracked data
943 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
943 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
944 blindly copying data/FooBarDirectory.d/f1.i containing 1 revisions
944 blindly copying data/FooBarDirectory.d/f1.i containing 1 revisions
945 blindly copying data/f0.i containing 1 revisions
945 blindly copying data/f0.i containing 1 revisions
946 blindly copying data/f2.i containing 1 revisions
946 blindly copying data/f2.i containing 1 revisions
947 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
947 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
948 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
948 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
949 cloning 3 revisions from 00manifest.i
949 cloning 3 revisions from 00manifest.i
950 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
950 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
951 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
951 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
952 blindly copying 00changelog.i containing 3 revisions
952 blindly copying 00changelog.i containing 3 revisions
953 finished migrating 3 changelog revisions; change in size: 0 bytes
953 finished migrating 3 changelog revisions; change in size: 0 bytes
954 finished migrating 9 total revisions; total change in store size: 0 bytes
954 finished migrating 9 total revisions; total change in store size: 0 bytes
955 copying phaseroots
955 copying phaseroots
956 copying requires
956 copying requires
957 data fully upgraded in a temporary repository
957 data fully upgraded in a temporary repository
958 marking source repository as being upgraded; clients will be unable to read from repository
958 marking source repository as being upgraded; clients will be unable to read from repository
959 starting in-place swap of repository data
959 starting in-place swap of repository data
960 replacing store...
960 replacing store...
961 store replacement complete; repository was inconsistent for *s (glob)
961 store replacement complete; repository was inconsistent for *s (glob)
962 finalizing requirements file and making repository readable again
962 finalizing requirements file and making repository readable again
963 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
963 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
964
964
965 Check that the repo still works fine
965 Check that the repo still works fine
966
966
967 $ hg log -G --stat
967 $ hg log -G --stat
968 @ changeset: 2:fca376863211
968 @ changeset: 2:fca376863211
969 | tag: tip
969 | tag: tip
970 | parent: 0:ba592bf28da2
970 | parent: 0:ba592bf28da2
971 | user: test
971 | user: test
972 | date: Thu Jan 01 00:00:00 1970 +0000
972 | date: Thu Jan 01 00:00:00 1970 +0000
973 | summary: add f2
973 | summary: add f2
974 |
974 |
975 | f2 | 100000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
975 | f2 | 100000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
976 | 1 files changed, 100000 insertions(+), 0 deletions(-)
976 | 1 files changed, 100000 insertions(+), 0 deletions(-)
977 |
977 |
978 | o changeset: 1:2029ce2354e2
978 | o changeset: 1:2029ce2354e2
979 |/ user: test
979 |/ user: test
980 | date: Thu Jan 01 00:00:00 1970 +0000
980 | date: Thu Jan 01 00:00:00 1970 +0000
981 | summary: add f1
981 | summary: add f1
982 |
982 |
983 |
983 |
984 o changeset: 0:ba592bf28da2
984 o changeset: 0:ba592bf28da2
985 user: test
985 user: test
986 date: Thu Jan 01 00:00:00 1970 +0000
986 date: Thu Jan 01 00:00:00 1970 +0000
987 summary: initial
987 summary: initial
988
988
989
989
990
990
991 $ hg verify -q
991 $ hg verify -q
992
992
993 Check we can select negatively
993 Check we can select negatively
994
994
995 $ hg debugupgrade --optimize re-delta-parent --run --no-manifest --no-backup --debug --traceback
995 $ hg debugupgrade --optimize re-delta-parent --run --no-manifest --no-backup --debug --traceback
996 upgrade will perform the following actions:
996 upgrade will perform the following actions:
997
997
998 requirements
998 requirements
999 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
999 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1000 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1000 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1001
1001
1002 optimisations: re-delta-parent
1002 optimisations: re-delta-parent
1003
1003
1004 re-delta-parent
1004 re-delta-parent
1005 deltas within internal storage will choose a new base revision if needed
1005 deltas within internal storage will choose a new base revision if needed
1006
1006
1007 processed revlogs:
1007 processed revlogs:
1008 - all-filelogs
1008 - all-filelogs
1009 - changelog
1009 - changelog
1010
1010
1011 beginning upgrade...
1011 beginning upgrade...
1012 repository locked and read-only
1012 repository locked and read-only
1013 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1013 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1014 (it is safe to interrupt this process any time before data migration completes)
1014 (it is safe to interrupt this process any time before data migration completes)
1015 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1015 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1016 migrating 519 KB in store; 1.05 MB tracked data
1016 migrating 519 KB in store; 1.05 MB tracked data
1017 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
1017 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
1018 cloning 1 revisions from data/FooBarDirectory.d/f1.i
1018 cloning 1 revisions from data/FooBarDirectory.d/f1.i
1019 cloning 1 revisions from data/f0.i
1019 cloning 1 revisions from data/f0.i
1020 cloning 1 revisions from data/f2.i
1020 cloning 1 revisions from data/f2.i
1021 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
1021 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
1022 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
1022 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
1023 blindly copying 00manifest.i containing 3 revisions
1023 blindly copying 00manifest.i containing 3 revisions
1024 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1024 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1025 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
1025 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
1026 cloning 3 revisions from 00changelog.i
1026 cloning 3 revisions from 00changelog.i
1027 finished migrating 3 changelog revisions; change in size: 0 bytes
1027 finished migrating 3 changelog revisions; change in size: 0 bytes
1028 finished migrating 9 total revisions; total change in store size: 0 bytes
1028 finished migrating 9 total revisions; total change in store size: 0 bytes
1029 copying phaseroots
1029 copying phaseroots
1030 copying requires
1030 copying requires
1031 data fully upgraded in a temporary repository
1031 data fully upgraded in a temporary repository
1032 marking source repository as being upgraded; clients will be unable to read from repository
1032 marking source repository as being upgraded; clients will be unable to read from repository
1033 starting in-place swap of repository data
1033 starting in-place swap of repository data
1034 replacing store...
1034 replacing store...
1035 store replacement complete; repository was inconsistent for *s (glob)
1035 store replacement complete; repository was inconsistent for *s (glob)
1036 finalizing requirements file and making repository readable again
1036 finalizing requirements file and making repository readable again
1037 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1037 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1038 $ hg verify -q
1038 $ hg verify -q
1039
1039
1040 Check that we can select changelog only
1040 Check that we can select changelog only
1041
1041
1042 $ hg debugupgrade --optimize re-delta-parent --run --changelog --no-backup --debug --traceback
1042 $ hg debugupgrade --optimize re-delta-parent --run --changelog --no-backup --debug --traceback
1043 upgrade will perform the following actions:
1043 upgrade will perform the following actions:
1044
1044
1045 requirements
1045 requirements
1046 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1046 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1047 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1047 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1048
1048
1049 optimisations: re-delta-parent
1049 optimisations: re-delta-parent
1050
1050
1051 re-delta-parent
1051 re-delta-parent
1052 deltas within internal storage will choose a new base revision if needed
1052 deltas within internal storage will choose a new base revision if needed
1053
1053
1054 processed revlogs:
1054 processed revlogs:
1055 - changelog
1055 - changelog
1056
1056
1057 beginning upgrade...
1057 beginning upgrade...
1058 repository locked and read-only
1058 repository locked and read-only
1059 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1059 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1060 (it is safe to interrupt this process any time before data migration completes)
1060 (it is safe to interrupt this process any time before data migration completes)
1061 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1061 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1062 migrating 519 KB in store; 1.05 MB tracked data
1062 migrating 519 KB in store; 1.05 MB tracked data
1063 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
1063 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
1064 blindly copying data/FooBarDirectory.d/f1.i containing 1 revisions
1064 blindly copying data/FooBarDirectory.d/f1.i containing 1 revisions
1065 blindly copying data/f0.i containing 1 revisions
1065 blindly copying data/f0.i containing 1 revisions
1066 blindly copying data/f2.i containing 1 revisions
1066 blindly copying data/f2.i containing 1 revisions
1067 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
1067 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
1068 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
1068 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
1069 blindly copying 00manifest.i containing 3 revisions
1069 blindly copying 00manifest.i containing 3 revisions
1070 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1070 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1071 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
1071 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
1072 cloning 3 revisions from 00changelog.i
1072 cloning 3 revisions from 00changelog.i
1073 finished migrating 3 changelog revisions; change in size: 0 bytes
1073 finished migrating 3 changelog revisions; change in size: 0 bytes
1074 finished migrating 9 total revisions; total change in store size: 0 bytes
1074 finished migrating 9 total revisions; total change in store size: 0 bytes
1075 copying phaseroots
1075 copying phaseroots
1076 copying requires
1076 copying requires
1077 data fully upgraded in a temporary repository
1077 data fully upgraded in a temporary repository
1078 marking source repository as being upgraded; clients will be unable to read from repository
1078 marking source repository as being upgraded; clients will be unable to read from repository
1079 starting in-place swap of repository data
1079 starting in-place swap of repository data
1080 replacing store...
1080 replacing store...
1081 store replacement complete; repository was inconsistent for *s (glob)
1081 store replacement complete; repository was inconsistent for *s (glob)
1082 finalizing requirements file and making repository readable again
1082 finalizing requirements file and making repository readable again
1083 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1083 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1084 $ hg verify -q
1084 $ hg verify -q
1085
1085
1086 Check that we can select filelog only
1086 Check that we can select filelog only
1087
1087
1088 $ hg debugupgrade --optimize re-delta-parent --run --no-changelog --no-manifest --no-backup --debug --traceback
1088 $ hg debugupgrade --optimize re-delta-parent --run --no-changelog --no-manifest --no-backup --debug --traceback
1089 upgrade will perform the following actions:
1089 upgrade will perform the following actions:
1090
1090
1091 requirements
1091 requirements
1092 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1092 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1093 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1093 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1094
1094
1095 optimisations: re-delta-parent
1095 optimisations: re-delta-parent
1096
1096
1097 re-delta-parent
1097 re-delta-parent
1098 deltas within internal storage will choose a new base revision if needed
1098 deltas within internal storage will choose a new base revision if needed
1099
1099
1100 processed revlogs:
1100 processed revlogs:
1101 - all-filelogs
1101 - all-filelogs
1102
1102
1103 beginning upgrade...
1103 beginning upgrade...
1104 repository locked and read-only
1104 repository locked and read-only
1105 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1105 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1106 (it is safe to interrupt this process any time before data migration completes)
1106 (it is safe to interrupt this process any time before data migration completes)
1107 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1107 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1108 migrating 519 KB in store; 1.05 MB tracked data
1108 migrating 519 KB in store; 1.05 MB tracked data
1109 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
1109 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
1110 cloning 1 revisions from data/FooBarDirectory.d/f1.i
1110 cloning 1 revisions from data/FooBarDirectory.d/f1.i
1111 cloning 1 revisions from data/f0.i
1111 cloning 1 revisions from data/f0.i
1112 cloning 1 revisions from data/f2.i
1112 cloning 1 revisions from data/f2.i
1113 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
1113 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
1114 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
1114 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
1115 blindly copying 00manifest.i containing 3 revisions
1115 blindly copying 00manifest.i containing 3 revisions
1116 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1116 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1117 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
1117 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
1118 blindly copying 00changelog.i containing 3 revisions
1118 blindly copying 00changelog.i containing 3 revisions
1119 finished migrating 3 changelog revisions; change in size: 0 bytes
1119 finished migrating 3 changelog revisions; change in size: 0 bytes
1120 finished migrating 9 total revisions; total change in store size: 0 bytes
1120 finished migrating 9 total revisions; total change in store size: 0 bytes
1121 copying phaseroots
1121 copying phaseroots
1122 copying requires
1122 copying requires
1123 data fully upgraded in a temporary repository
1123 data fully upgraded in a temporary repository
1124 marking source repository as being upgraded; clients will be unable to read from repository
1124 marking source repository as being upgraded; clients will be unable to read from repository
1125 starting in-place swap of repository data
1125 starting in-place swap of repository data
1126 replacing store...
1126 replacing store...
1127 store replacement complete; repository was inconsistent for *s (glob)
1127 store replacement complete; repository was inconsistent for *s (glob)
1128 finalizing requirements file and making repository readable again
1128 finalizing requirements file and making repository readable again
1129 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1129 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1130 $ hg verify -q
1130 $ hg verify -q
1131
1131
1132
1132
1133 Check you can't skip revlog clone during important format downgrade
1133 Check you can't skip revlog clone during important format downgrade
1134
1134
1135 $ echo "[format]" > .hg/hgrc
1135 $ echo "[format]" > .hg/hgrc
1136 $ echo "sparse-revlog=no" >> .hg/hgrc
1136 $ echo "sparse-revlog=no" >> .hg/hgrc
1137 $ hg debugupgrade --optimize re-delta-parent --no-manifest --no-backup --quiet
1137 $ hg debugupgrade --optimize re-delta-parent --no-manifest --no-backup --quiet
1138 warning: ignoring --no-manifest, as upgrade is changing: sparserevlog
1138 warning: ignoring --no-manifest, as upgrade is changing: sparserevlog
1139
1139
1140 requirements
1140 requirements
1141 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1141 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1142 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1142 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1143 removed: sparserevlog
1143 removed: sparserevlog
1144
1144
1145 optimisations: re-delta-parent
1145 optimisations: re-delta-parent
1146
1146
1147 processed revlogs:
1147 processed revlogs:
1148 - all-filelogs
1148 - all-filelogs
1149 - changelog
1149 - changelog
1150 - manifest
1150 - manifest
1151
1151
1152 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
1152 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
1153 note: selecting all-filelogs for processing to change: sparserevlog
1153 note: selecting all-filelogs for processing to change: sparserevlog
1154 note: selecting changelog for processing to change: sparserevlog
1154 note: selecting changelog for processing to change: sparserevlog
1155
1155
1156 upgrade will perform the following actions:
1156 upgrade will perform the following actions:
1157
1157
1158 requirements
1158 requirements
1159 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1159 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1160 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1160 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1161 removed: sparserevlog
1161 removed: sparserevlog
1162
1162
1163 optimisations: re-delta-parent
1163 optimisations: re-delta-parent
1164
1164
1165 re-delta-parent
1165 re-delta-parent
1166 deltas within internal storage will choose a new base revision if needed
1166 deltas within internal storage will choose a new base revision if needed
1167
1167
1168 processed revlogs:
1168 processed revlogs:
1169 - all-filelogs
1169 - all-filelogs
1170 - changelog
1170 - changelog
1171 - manifest
1171 - manifest
1172
1172
1173 beginning upgrade...
1173 beginning upgrade...
1174 repository locked and read-only
1174 repository locked and read-only
1175 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1175 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1176 (it is safe to interrupt this process any time before data migration completes)
1176 (it is safe to interrupt this process any time before data migration completes)
1177 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1177 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1178 migrating 519 KB in store; 1.05 MB tracked data
1178 migrating 519 KB in store; 1.05 MB tracked data
1179 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
1179 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
1180 cloning 1 revisions from data/FooBarDirectory.d/f1.i
1180 cloning 1 revisions from data/FooBarDirectory.d/f1.i
1181 cloning 1 revisions from data/f0.i
1181 cloning 1 revisions from data/f0.i
1182 cloning 1 revisions from data/f2.i
1182 cloning 1 revisions from data/f2.i
1183 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
1183 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
1184 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
1184 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
1185 cloning 3 revisions from 00manifest.i
1185 cloning 3 revisions from 00manifest.i
1186 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1186 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1187 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
1187 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
1188 cloning 3 revisions from 00changelog.i
1188 cloning 3 revisions from 00changelog.i
1189 finished migrating 3 changelog revisions; change in size: 0 bytes
1189 finished migrating 3 changelog revisions; change in size: 0 bytes
1190 finished migrating 9 total revisions; total change in store size: 0 bytes
1190 finished migrating 9 total revisions; total change in store size: 0 bytes
1191 copying phaseroots
1191 copying phaseroots
1192 copying requires
1192 copying requires
1193 data fully upgraded in a temporary repository
1193 data fully upgraded in a temporary repository
1194 marking source repository as being upgraded; clients will be unable to read from repository
1194 marking source repository as being upgraded; clients will be unable to read from repository
1195 starting in-place swap of repository data
1195 starting in-place swap of repository data
1196 replacing store...
1196 replacing store...
1197 store replacement complete; repository was inconsistent for *s (glob)
1197 store replacement complete; repository was inconsistent for *s (glob)
1198 finalizing requirements file and making repository readable again
1198 finalizing requirements file and making repository readable again
1199 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1199 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1200 $ hg verify -q
1200 $ hg verify -q
1201
1201
1202 Check you can't skip revlog clone during important format upgrade
1202 Check you can't skip revlog clone during important format upgrade
1203
1203
1204 $ echo "sparse-revlog=yes" >> .hg/hgrc
1204 $ echo "sparse-revlog=yes" >> .hg/hgrc
1205 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
1205 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
1206 note: selecting all-filelogs for processing to change: sparserevlog
1206 note: selecting all-filelogs for processing to change: sparserevlog
1207 note: selecting changelog for processing to change: sparserevlog
1207 note: selecting changelog for processing to change: sparserevlog
1208
1208
1209 upgrade will perform the following actions:
1209 upgrade will perform the following actions:
1210
1210
1211 requirements
1211 requirements
1212 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1212 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1213 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1213 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1214 added: sparserevlog
1214 added: sparserevlog
1215
1215
1216 optimisations: re-delta-parent
1216 optimisations: re-delta-parent
1217
1217
1218 sparserevlog
1218 sparserevlog
1219 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
1219 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
1220
1220
1221 re-delta-parent
1221 re-delta-parent
1222 deltas within internal storage will choose a new base revision if needed
1222 deltas within internal storage will choose a new base revision if needed
1223
1223
1224 processed revlogs:
1224 processed revlogs:
1225 - all-filelogs
1225 - all-filelogs
1226 - changelog
1226 - changelog
1227 - manifest
1227 - manifest
1228
1228
1229 beginning upgrade...
1229 beginning upgrade...
1230 repository locked and read-only
1230 repository locked and read-only
1231 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1231 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1232 (it is safe to interrupt this process any time before data migration completes)
1232 (it is safe to interrupt this process any time before data migration completes)
1233 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1233 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1234 migrating 519 KB in store; 1.05 MB tracked data
1234 migrating 519 KB in store; 1.05 MB tracked data
1235 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
1235 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
1236 cloning 1 revisions from data/FooBarDirectory.d/f1.i
1236 cloning 1 revisions from data/FooBarDirectory.d/f1.i
1237 cloning 1 revisions from data/f0.i
1237 cloning 1 revisions from data/f0.i
1238 cloning 1 revisions from data/f2.i
1238 cloning 1 revisions from data/f2.i
1239 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
1239 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
1240 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
1240 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
1241 cloning 3 revisions from 00manifest.i
1241 cloning 3 revisions from 00manifest.i
1242 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1242 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1243 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
1243 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
1244 cloning 3 revisions from 00changelog.i
1244 cloning 3 revisions from 00changelog.i
1245 finished migrating 3 changelog revisions; change in size: 0 bytes
1245 finished migrating 3 changelog revisions; change in size: 0 bytes
1246 finished migrating 9 total revisions; total change in store size: 0 bytes
1246 finished migrating 9 total revisions; total change in store size: 0 bytes
1247 copying phaseroots
1247 copying phaseroots
1248 copying requires
1248 copying requires
1249 data fully upgraded in a temporary repository
1249 data fully upgraded in a temporary repository
1250 marking source repository as being upgraded; clients will be unable to read from repository
1250 marking source repository as being upgraded; clients will be unable to read from repository
1251 starting in-place swap of repository data
1251 starting in-place swap of repository data
1252 replacing store...
1252 replacing store...
1253 store replacement complete; repository was inconsistent for *s (glob)
1253 store replacement complete; repository was inconsistent for *s (glob)
1254 finalizing requirements file and making repository readable again
1254 finalizing requirements file and making repository readable again
1255 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1255 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
1256 $ hg verify -q
1256 $ hg verify -q
1257
1257
1258 $ cd ..
1258 $ cd ..
1259
1259
1260 store files with special filenames aren't encoded during copy
1260 store files with special filenames aren't encoded during copy
1261
1261
1262 $ hg init store-filenames
1262 $ hg init store-filenames
1263 $ cd store-filenames
1263 $ cd store-filenames
1264 $ touch foo
1264 $ touch foo
1265 $ hg -q commit -A -m initial
1265 $ hg -q commit -A -m initial
1266 $ touch .hg/store/.XX_special_filename
1266 $ touch .hg/store/.XX_special_filename
1267
1267
1268 $ hg debugupgraderepo --run
1268 $ hg debugupgraderepo --run
1269 nothing to do
1269 nothing to do
1270 $ hg debugupgraderepo --run --optimize 're-delta-fulladd'
1270 $ hg debugupgraderepo --run --optimize 're-delta-fulladd'
1271 upgrade will perform the following actions:
1271 upgrade will perform the following actions:
1272
1272
1273 requirements
1273 requirements
1274 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1274 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1275 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1275 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1276
1276
1277 optimisations: re-delta-fulladd
1277 optimisations: re-delta-fulladd
1278
1278
1279 re-delta-fulladd
1279 re-delta-fulladd
1280 each revision will be added as new content to the internal storage; this will likely drastically slow down execution time, but some extensions might need it
1280 each revision will be added as new content to the internal storage; this will likely drastically slow down execution time, but some extensions might need it
1281
1281
1282 processed revlogs:
1282 processed revlogs:
1283 - all-filelogs
1283 - all-filelogs
1284 - changelog
1284 - changelog
1285 - manifest
1285 - manifest
1286
1286
1287 beginning upgrade...
1287 beginning upgrade...
1288 repository locked and read-only
1288 repository locked and read-only
1289 creating temporary repository to stage upgraded data: $TESTTMP/store-filenames/.hg/upgrade.* (glob)
1289 creating temporary repository to stage upgraded data: $TESTTMP/store-filenames/.hg/upgrade.* (glob)
1290 (it is safe to interrupt this process any time before data migration completes)
1290 (it is safe to interrupt this process any time before data migration completes)
1291 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
1291 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
1292 migrating 301 bytes in store; 107 bytes tracked data
1292 migrating 301 bytes in store; 107 bytes tracked data
1293 migrating 1 filelogs containing 1 revisions (64 bytes in store; 0 bytes tracked data)
1293 migrating 1 filelogs containing 1 revisions (64 bytes in store; 0 bytes tracked data)
1294 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
1294 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
1295 migrating 1 manifests containing 1 revisions (110 bytes in store; 45 bytes tracked data)
1295 migrating 1 manifests containing 1 revisions (110 bytes in store; 45 bytes tracked data)
1296 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
1296 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
1297 migrating changelog containing 1 revisions (127 bytes in store; 62 bytes tracked data)
1297 migrating changelog containing 1 revisions (127 bytes in store; 62 bytes tracked data)
1298 finished migrating 1 changelog revisions; change in size: 0 bytes
1298 finished migrating 1 changelog revisions; change in size: 0 bytes
1299 finished migrating 3 total revisions; total change in store size: 0 bytes
1299 finished migrating 3 total revisions; total change in store size: 0 bytes
1300 copying .XX_special_filename
1300 copying .XX_special_filename
1301 copying phaseroots
1301 copying phaseroots
1302 copying requires
1302 copying requires
1303 data fully upgraded in a temporary repository
1303 data fully upgraded in a temporary repository
1304 marking source repository as being upgraded; clients will be unable to read from repository
1304 marking source repository as being upgraded; clients will be unable to read from repository
1305 starting in-place swap of repository data
1305 starting in-place swap of repository data
1306 replaced files will be backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
1306 replaced files will be backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
1307 replacing store...
1307 replacing store...
1308 store replacement complete; repository was inconsistent for *s (glob)
1308 store replacement complete; repository was inconsistent for *s (glob)
1309 finalizing requirements file and making repository readable again
1309 finalizing requirements file and making repository readable again
1310 removing temporary repository $TESTTMP/store-filenames/.hg/upgrade.* (glob)
1310 removing temporary repository $TESTTMP/store-filenames/.hg/upgrade.* (glob)
1311 copy of old repository backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
1311 copy of old repository backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
1312 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
1312 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
1313
1313
1314 fncache is valid after upgrade
1314 fncache is valid after upgrade
1315
1315
1316 $ hg debugrebuildfncache
1316 $ hg debugrebuildfncache
1317 fncache already up to date
1317 fncache already up to date
1318
1318
1319 $ cd ..
1319 $ cd ..
1320
1320
1321 Check upgrading a large file repository
1321 Check upgrading a large file repository
1322 ---------------------------------------
1322 ---------------------------------------
1323
1323
1324 $ hg init largefilesrepo
1324 $ hg init largefilesrepo
1325 $ cat << EOF >> largefilesrepo/.hg/hgrc
1325 $ cat << EOF >> largefilesrepo/.hg/hgrc
1326 > [extensions]
1326 > [extensions]
1327 > largefiles =
1327 > largefiles =
1328 > EOF
1328 > EOF
1329
1329
1330 $ cd largefilesrepo
1330 $ cd largefilesrepo
1331 $ touch foo
1331 $ touch foo
1332 $ hg add --large foo
1332 $ hg add --large foo
1333 $ hg -q commit -m initial
1333 $ hg -q commit -m initial
1334 $ hg debugrequires
1334 $ hg debugrequires
1335 dotencode
1335 dotencode
1336 fncache
1336 fncache
1337 generaldelta
1337 generaldelta
1338 largefiles
1338 largefiles
1339 persistent-nodemap (rust !)
1339 persistent-nodemap (rust !)
1340 revlogv1
1340 revlogv1
1341 share-safe
1341 share-safe
1342 sparserevlog
1342 sparserevlog
1343 store
1343 store
1344
1344
1345 $ hg debugupgraderepo --run
1345 $ hg debugupgraderepo --run
1346 nothing to do
1346 nothing to do
1347 $ hg debugrequires
1347 $ hg debugrequires
1348 dotencode
1348 dotencode
1349 fncache
1349 fncache
1350 generaldelta
1350 generaldelta
1351 largefiles
1351 largefiles
1352 persistent-nodemap (rust !)
1352 persistent-nodemap (rust !)
1353 revlogv1
1353 revlogv1
1354 share-safe
1354 share-safe
1355 sparserevlog
1355 sparserevlog
1356 store
1356 store
1357
1357
1358 $ cat << EOF >> .hg/hgrc
1358 $ cat << EOF >> .hg/hgrc
1359 > [extensions]
1359 > [extensions]
1360 > lfs =
1360 > lfs =
1361 > [lfs]
1361 > [lfs]
1362 > threshold = 10
1362 > threshold = 10
1363 > EOF
1363 > EOF
1364 $ echo '123456789012345' > lfs.bin
1364 $ echo '123456789012345' > lfs.bin
1365 $ hg ci -Am 'lfs.bin'
1365 $ hg ci -Am 'lfs.bin'
1366 adding lfs.bin
1366 adding lfs.bin
1367 $ hg debugrequires | grep lfs
1367 $ hg debugrequires | grep lfs
1368 lfs
1368 lfs
1369 $ find .hg/store/lfs -type f
1369 $ find .hg/store/lfs -type f
1370 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1370 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1371
1371
1372 $ hg debugupgraderepo --run
1372 $ hg debugupgraderepo --run
1373 nothing to do
1373 nothing to do
1374
1374
1375 $ hg debugrequires | grep lfs
1375 $ hg debugrequires | grep lfs
1376 lfs
1376 lfs
1377 $ find .hg/store/lfs -type f
1377 $ find .hg/store/lfs -type f
1378 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1378 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1379 $ hg verify -q
1379 $ hg verify -q
1380 $ hg debugdata lfs.bin 0
1380 $ hg debugdata lfs.bin 0
1381 version https://git-lfs.github.com/spec/v1
1381 version https://git-lfs.github.com/spec/v1
1382 oid sha256:d0beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1382 oid sha256:d0beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1383 size 16
1383 size 16
1384 x-is-binary 0
1384 x-is-binary 0
1385
1385
1386 $ cd ..
1386 $ cd ..
1387
1387
1388 repository config is taken in account
1388 repository config is taken in account
1389 -------------------------------------
1389 -------------------------------------
1390
1390
1391 $ cat << EOF >> $HGRCPATH
1391 $ cat << EOF >> $HGRCPATH
1392 > [format]
1392 > [format]
1393 > maxchainlen = 1
1393 > maxchainlen = 1
1394 > EOF
1394 > EOF
1395
1395
1396 $ hg init localconfig
1396 $ hg init localconfig
1397 $ cd localconfig
1397 $ cd localconfig
1398 $ cat << EOF > file
1398 $ cat << EOF > file
1399 > some content
1399 > some content
1400 > with some length
1400 > with some length
1401 > to make sure we get a delta
1401 > to make sure we get a delta
1402 > after changes
1402 > after changes
1403 > very long
1403 > very long
1404 > very long
1404 > very long
1405 > very long
1405 > very long
1406 > very long
1406 > very long
1407 > very long
1407 > very long
1408 > very long
1408 > very long
1409 > very long
1409 > very long
1410 > very long
1410 > very long
1411 > very long
1411 > very long
1412 > very long
1412 > very long
1413 > very long
1413 > very long
1414 > EOF
1414 > EOF
1415 $ hg -q commit -A -m A
1415 $ hg -q commit -A -m A
1416 $ echo "new line" >> file
1416 $ echo "new line" >> file
1417 $ hg -q commit -m B
1417 $ hg -q commit -m B
1418 $ echo "new line" >> file
1418 $ echo "new line" >> file
1419 $ hg -q commit -m C
1419 $ hg -q commit -m C
1420
1420
1421 $ cat << EOF >> .hg/hgrc
1421 $ cat << EOF >> .hg/hgrc
1422 > [format]
1422 > [format]
1423 > maxchainlen = 9001
1423 > maxchainlen = 9001
1424 > EOF
1424 > EOF
1425 $ hg config format
1425 $ hg config format
1426 format.revlog-compression=$BUNDLE2_COMPRESSIONS$
1426 format.revlog-compression=$BUNDLE2_COMPRESSIONS$
1427 format.maxchainlen=9001
1427 format.maxchainlen=9001
1428 $ hg debugdeltachain file
1428 $ hg debugdeltachain file
1429 rev p1 p2 chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
1429 rev p1 p2 chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
1430 0 -1 -1 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
1430 0 -1 -1 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
1431 1 0 -1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
1431 1 0 -1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
1432 2 1 -1 1 2 0 snap 30 200 107 0.53500 128 21 0.19626 128 128 0.83594 1
1432 2 1 -1 1 2 0 snap 30 200 107 0.53500 128 21 0.19626 128 128 0.83594 1
1433
1433
1434 $ hg debugupgraderepo --run --optimize 're-delta-all'
1434 $ hg debugupgraderepo --run --optimize 're-delta-all'
1435 upgrade will perform the following actions:
1435 upgrade will perform the following actions:
1436
1436
1437 requirements
1437 requirements
1438 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1438 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1439 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1439 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1440
1440
1441 optimisations: re-delta-all
1441 optimisations: re-delta-all
1442
1442
1443 re-delta-all
1443 re-delta-all
1444 deltas within internal storage will be fully recomputed; this will likely drastically slow down execution time
1444 deltas within internal storage will be fully recomputed; this will likely drastically slow down execution time
1445
1445
1446 processed revlogs:
1446 processed revlogs:
1447 - all-filelogs
1447 - all-filelogs
1448 - changelog
1448 - changelog
1449 - manifest
1449 - manifest
1450
1450
1451 beginning upgrade...
1451 beginning upgrade...
1452 repository locked and read-only
1452 repository locked and read-only
1453 creating temporary repository to stage upgraded data: $TESTTMP/localconfig/.hg/upgrade.* (glob)
1453 creating temporary repository to stage upgraded data: $TESTTMP/localconfig/.hg/upgrade.* (glob)
1454 (it is safe to interrupt this process any time before data migration completes)
1454 (it is safe to interrupt this process any time before data migration completes)
1455 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1455 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1456 migrating 1019 bytes in store; 882 bytes tracked data
1456 migrating 1019 bytes in store; 882 bytes tracked data
1457 migrating 1 filelogs containing 3 revisions (320 bytes in store; 573 bytes tracked data)
1457 migrating 1 filelogs containing 3 revisions (320 bytes in store; 573 bytes tracked data)
1458 finished migrating 3 filelog revisions across 1 filelogs; change in size: -9 bytes
1458 finished migrating 3 filelog revisions across 1 filelogs; change in size: -9 bytes
1459 migrating 1 manifests containing 3 revisions (333 bytes in store; 138 bytes tracked data)
1459 migrating 1 manifests containing 3 revisions (333 bytes in store; 138 bytes tracked data)
1460 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1460 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1461 migrating changelog containing 3 revisions (366 bytes in store; 171 bytes tracked data)
1461 migrating changelog containing 3 revisions (366 bytes in store; 171 bytes tracked data)
1462 finished migrating 3 changelog revisions; change in size: 0 bytes
1462 finished migrating 3 changelog revisions; change in size: 0 bytes
1463 finished migrating 9 total revisions; total change in store size: -9 bytes
1463 finished migrating 9 total revisions; total change in store size: -9 bytes
1464 copying phaseroots
1464 copying phaseroots
1465 copying requires
1465 copying requires
1466 data fully upgraded in a temporary repository
1466 data fully upgraded in a temporary repository
1467 marking source repository as being upgraded; clients will be unable to read from repository
1467 marking source repository as being upgraded; clients will be unable to read from repository
1468 starting in-place swap of repository data
1468 starting in-place swap of repository data
1469 replaced files will be backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
1469 replaced files will be backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
1470 replacing store...
1470 replacing store...
1471 store replacement complete; repository was inconsistent for *s (glob)
1471 store replacement complete; repository was inconsistent for *s (glob)
1472 finalizing requirements file and making repository readable again
1472 finalizing requirements file and making repository readable again
1473 removing temporary repository $TESTTMP/localconfig/.hg/upgrade.* (glob)
1473 removing temporary repository $TESTTMP/localconfig/.hg/upgrade.* (glob)
1474 copy of old repository backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
1474 copy of old repository backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
1475 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
1475 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
1476 $ hg debugdeltachain file
1476 $ hg debugdeltachain file
1477 rev p1 p2 chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
1477 rev p1 p2 chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
1478 0 -1 -1 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
1478 0 -1 -1 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
1479 1 0 -1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
1479 1 0 -1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
1480 2 1 -1 1 3 1 p1 21 200 119 0.59500 119 0 0.00000 119 119 1.00000 1
1480 2 1 -1 1 3 1 p1 21 200 119 0.59500 119 0 0.00000 119 119 1.00000 1
1481 $ cd ..
1481 $ cd ..
1482
1482
1483 $ cat << EOF >> $HGRCPATH
1483 $ cat << EOF >> $HGRCPATH
1484 > [format]
1484 > [format]
1485 > maxchainlen = 9001
1485 > maxchainlen = 9001
1486 > EOF
1486 > EOF
1487
1487
1488 Check upgrading a sparse-revlog repository
1488 Check upgrading a sparse-revlog repository
1489 ---------------------------------------
1489 ---------------------------------------
1490
1490
1491 $ hg init sparserevlogrepo --config format.sparse-revlog=no
1491 $ hg init sparserevlogrepo --config format.sparse-revlog=no
1492 $ cd sparserevlogrepo
1492 $ cd sparserevlogrepo
1493 $ touch foo
1493 $ touch foo
1494 $ hg add foo
1494 $ hg add foo
1495 $ hg -q commit -m "foo"
1495 $ hg -q commit -m "foo"
1496 $ hg debugrequires
1496 $ hg debugrequires
1497 dotencode
1497 dotencode
1498 fncache
1498 fncache
1499 generaldelta
1499 generaldelta
1500 persistent-nodemap (rust !)
1500 persistent-nodemap (rust !)
1501 revlogv1
1501 revlogv1
1502 share-safe
1502 share-safe
1503 store
1503 store
1504
1504
1505 Check that we can add the sparse-revlog format requirement
1505 Check that we can add the sparse-revlog format requirement
1506 $ hg --config format.sparse-revlog=yes debugupgraderepo --run --quiet
1506 $ hg --config format.sparse-revlog=yes debugupgraderepo --run --quiet
1507 upgrade will perform the following actions:
1507 upgrade will perform the following actions:
1508
1508
1509 requirements
1509 requirements
1510 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1510 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1511 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1511 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1512 added: sparserevlog
1512 added: sparserevlog
1513
1513
1514 processed revlogs:
1514 processed revlogs:
1515 - all-filelogs
1515 - all-filelogs
1516 - changelog
1516 - changelog
1517 - manifest
1517 - manifest
1518
1518
1519 $ hg debugrequires
1519 $ hg debugrequires
1520 dotencode
1520 dotencode
1521 fncache
1521 fncache
1522 generaldelta
1522 generaldelta
1523 persistent-nodemap (rust !)
1523 persistent-nodemap (rust !)
1524 revlogv1
1524 revlogv1
1525 share-safe
1525 share-safe
1526 sparserevlog
1526 sparserevlog
1527 store
1527 store
1528
1528
1529 Check that we can remove the sparse-revlog format requirement
1529 Check that we can remove the sparse-revlog format requirement
1530 $ hg --config format.sparse-revlog=no debugupgraderepo --run --quiet
1530 $ hg --config format.sparse-revlog=no debugupgraderepo --run --quiet
1531 upgrade will perform the following actions:
1531 upgrade will perform the following actions:
1532
1532
1533 requirements
1533 requirements
1534 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1534 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1535 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1535 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1536 removed: sparserevlog
1536 removed: sparserevlog
1537
1537
1538 processed revlogs:
1538 processed revlogs:
1539 - all-filelogs
1539 - all-filelogs
1540 - changelog
1540 - changelog
1541 - manifest
1541 - manifest
1542
1542
1543 $ hg debugrequires
1543 $ hg debugrequires
1544 dotencode
1544 dotencode
1545 fncache
1545 fncache
1546 generaldelta
1546 generaldelta
1547 persistent-nodemap (rust !)
1547 persistent-nodemap (rust !)
1548 revlogv1
1548 revlogv1
1549 share-safe
1549 share-safe
1550 store
1550 store
1551
1551
1552 #if zstd
1552 #if zstd
1553
1553
1554 Check upgrading to a zstd revlog
1554 Check upgrading to a zstd revlog
1555 --------------------------------
1555 --------------------------------
1556
1556
1557 upgrade
1557 upgrade
1558
1558
1559 $ hg --config format.revlog-compression=zstd debugupgraderepo --run --no-backup --quiet
1559 $ hg --config format.revlog-compression=zstd debugupgraderepo --run --no-backup --quiet
1560 upgrade will perform the following actions:
1560 upgrade will perform the following actions:
1561
1561
1562 requirements
1562 requirements
1563 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1563 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, store (no-rust !)
1564 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1564 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, store (rust !)
1565 added: revlog-compression-zstd, sparserevlog
1565 added: revlog-compression-zstd, sparserevlog
1566
1566
1567 processed revlogs:
1567 processed revlogs:
1568 - all-filelogs
1568 - all-filelogs
1569 - changelog
1569 - changelog
1570 - manifest
1570 - manifest
1571
1571
1572 $ hg debugformat -v
1572 $ hg debugformat -v
1573 format-variant repo config default
1573 format-variant repo config default
1574 fncache: yes yes yes
1574 fncache: yes yes yes
1575 dirstate-v2: no no no
1575 dirstate-v2: no no no
1576 tracked-hint: no no no
1576 tracked-hint: no no no
1577 dotencode: yes yes yes
1577 dotencode: yes yes yes
1578 generaldelta: yes yes yes
1578 generaldelta: yes yes yes
1579 share-safe: yes yes yes
1579 share-safe: yes yes yes
1580 sparserevlog: yes yes yes
1580 sparserevlog: yes yes yes
1581 persistent-nodemap: no no no (no-rust !)
1581 persistent-nodemap: no no no (no-rust !)
1582 persistent-nodemap: yes yes no (rust !)
1582 persistent-nodemap: yes yes no (rust !)
1583 copies-sdc: no no no
1583 copies-sdc: no no no
1584 revlog-v2: no no no
1584 revlog-v2: no no no
1585 changelog-v2: no no no
1585 changelog-v2: no no no
1586 plain-cl-delta: yes yes yes
1586 plain-cl-delta: yes yes yes
1587 compression: zlib zlib zlib (no-zstd !)
1587 compression: zlib zlib zlib (no-zstd !)
1588 compression: zstd zlib zstd (zstd !)
1588 compression: zstd zlib zstd (zstd !)
1589 compression-level: default default default
1589 compression-level: default default default
1590 $ hg debugrequires
1590 $ hg debugrequires
1591 dotencode
1591 dotencode
1592 fncache
1592 fncache
1593 generaldelta
1593 generaldelta
1594 persistent-nodemap (rust !)
1594 persistent-nodemap (rust !)
1595 revlog-compression-zstd
1595 revlog-compression-zstd
1596 revlogv1
1596 revlogv1
1597 share-safe
1597 share-safe
1598 sparserevlog
1598 sparserevlog
1599 store
1599 store
1600
1600
1601 downgrade
1601 downgrade
1602
1602
1603 $ hg debugupgraderepo --run --no-backup --quiet
1603 $ hg debugupgraderepo --run --no-backup --quiet
1604 upgrade will perform the following actions:
1604 upgrade will perform the following actions:
1605
1605
1606 requirements
1606 requirements
1607 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1607 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1608 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1608 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1609 removed: revlog-compression-zstd
1609 removed: revlog-compression-zstd
1610
1610
1611 processed revlogs:
1611 processed revlogs:
1612 - all-filelogs
1612 - all-filelogs
1613 - changelog
1613 - changelog
1614 - manifest
1614 - manifest
1615
1615
1616 $ hg debugformat -v
1616 $ hg debugformat -v
1617 format-variant repo config default
1617 format-variant repo config default
1618 fncache: yes yes yes
1618 fncache: yes yes yes
1619 dirstate-v2: no no no
1619 dirstate-v2: no no no
1620 tracked-hint: no no no
1620 tracked-hint: no no no
1621 dotencode: yes yes yes
1621 dotencode: yes yes yes
1622 generaldelta: yes yes yes
1622 generaldelta: yes yes yes
1623 share-safe: yes yes yes
1623 share-safe: yes yes yes
1624 sparserevlog: yes yes yes
1624 sparserevlog: yes yes yes
1625 persistent-nodemap: no no no (no-rust !)
1625 persistent-nodemap: no no no (no-rust !)
1626 persistent-nodemap: yes yes no (rust !)
1626 persistent-nodemap: yes yes no (rust !)
1627 copies-sdc: no no no
1627 copies-sdc: no no no
1628 revlog-v2: no no no
1628 revlog-v2: no no no
1629 changelog-v2: no no no
1629 changelog-v2: no no no
1630 plain-cl-delta: yes yes yes
1630 plain-cl-delta: yes yes yes
1631 compression: zlib zlib zlib (no-zstd !)
1631 compression: zlib zlib zlib (no-zstd !)
1632 compression: zlib zlib zstd (zstd !)
1632 compression: zlib zlib zstd (zstd !)
1633 compression-level: default default default
1633 compression-level: default default default
1634 $ hg debugrequires
1634 $ hg debugrequires
1635 dotencode
1635 dotencode
1636 fncache
1636 fncache
1637 generaldelta
1637 generaldelta
1638 persistent-nodemap (rust !)
1638 persistent-nodemap (rust !)
1639 revlogv1
1639 revlogv1
1640 share-safe
1640 share-safe
1641 sparserevlog
1641 sparserevlog
1642 store
1642 store
1643
1643
1644 upgrade from hgrc
1644 upgrade from hgrc
1645
1645
1646 $ cat >> .hg/hgrc << EOF
1646 $ cat >> .hg/hgrc << EOF
1647 > [format]
1647 > [format]
1648 > revlog-compression=zstd
1648 > revlog-compression=zstd
1649 > EOF
1649 > EOF
1650 $ hg debugupgraderepo --run --no-backup --quiet
1650 $ hg debugupgraderepo --run --no-backup --quiet
1651 upgrade will perform the following actions:
1651 upgrade will perform the following actions:
1652
1652
1653 requirements
1653 requirements
1654 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1654 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
1655 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1655 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (rust !)
1656 added: revlog-compression-zstd
1656 added: revlog-compression-zstd
1657
1657
1658 processed revlogs:
1658 processed revlogs:
1659 - all-filelogs
1659 - all-filelogs
1660 - changelog
1660 - changelog
1661 - manifest
1661 - manifest
1662
1662
1663 $ hg debugformat -v
1663 $ hg debugformat -v
1664 format-variant repo config default
1664 format-variant repo config default
1665 fncache: yes yes yes
1665 fncache: yes yes yes
1666 dirstate-v2: no no no
1666 dirstate-v2: no no no
1667 tracked-hint: no no no
1667 tracked-hint: no no no
1668 dotencode: yes yes yes
1668 dotencode: yes yes yes
1669 generaldelta: yes yes yes
1669 generaldelta: yes yes yes
1670 share-safe: yes yes yes
1670 share-safe: yes yes yes
1671 sparserevlog: yes yes yes
1671 sparserevlog: yes yes yes
1672 persistent-nodemap: no no no (no-rust !)
1672 persistent-nodemap: no no no (no-rust !)
1673 persistent-nodemap: yes yes no (rust !)
1673 persistent-nodemap: yes yes no (rust !)
1674 copies-sdc: no no no
1674 copies-sdc: no no no
1675 revlog-v2: no no no
1675 revlog-v2: no no no
1676 changelog-v2: no no no
1676 changelog-v2: no no no
1677 plain-cl-delta: yes yes yes
1677 plain-cl-delta: yes yes yes
1678 compression: zlib zlib zlib (no-zstd !)
1678 compression: zlib zlib zlib (no-zstd !)
1679 compression: zstd zstd zstd (zstd !)
1679 compression: zstd zstd zstd (zstd !)
1680 compression-level: default default default
1680 compression-level: default default default
1681 $ hg debugrequires
1681 $ hg debugrequires
1682 dotencode
1682 dotencode
1683 fncache
1683 fncache
1684 generaldelta
1684 generaldelta
1685 persistent-nodemap (rust !)
1685 persistent-nodemap (rust !)
1686 revlog-compression-zstd
1686 revlog-compression-zstd
1687 revlogv1
1687 revlogv1
1688 share-safe
1688 share-safe
1689 sparserevlog
1689 sparserevlog
1690 store
1690 store
1691
1691
1692 #endif
1692 #endif
1693
1693
1694 Check upgrading to a revlog format supporting sidedata
1694 Check upgrading to a revlog format supporting sidedata
1695 ------------------------------------------------------
1695 ------------------------------------------------------
1696
1696
1697 upgrade
1697 upgrade
1698
1698
1699 $ hg debugsidedata -c 0
1699 $ hg debugsidedata -c 0
1700 $ hg --config experimental.revlogv2=enable-unstable-format-and-corrupt-my-data debugupgraderepo --run --no-backup --config "extensions.sidedata=$TESTDIR/testlib/ext-sidedata.py" --quiet
1700 $ hg --config experimental.revlogv2=enable-unstable-format-and-corrupt-my-data debugupgraderepo --run --no-backup --config "extensions.sidedata=$TESTDIR/testlib/ext-sidedata.py" --quiet
1701 upgrade will perform the following actions:
1701 upgrade will perform the following actions:
1702
1702
1703 requirements
1703 requirements
1704 preserved: dotencode, fncache, generaldelta, share-safe, store (no-zstd !)
1704 preserved: dotencode, fncache, generaldelta, share-safe, store (no-zstd !)
1705 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, share-safe, sparserevlog, store (zstd no-rust !)
1705 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, share-safe, sparserevlog, store (zstd no-rust !)
1706 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, share-safe, sparserevlog, store (rust !)
1706 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, share-safe, sparserevlog, store (rust !)
1707 removed: revlogv1
1707 removed: revlogv1
1708 added: exp-revlogv2.2 (zstd !)
1708 added: exp-revlogv2.2 (zstd !)
1709 added: exp-revlogv2.2, sparserevlog (no-zstd !)
1709 added: exp-revlogv2.2, sparserevlog (no-zstd !)
1710
1710
1711 processed revlogs:
1711 processed revlogs:
1712 - all-filelogs
1712 - all-filelogs
1713 - changelog
1713 - changelog
1714 - manifest
1714 - manifest
1715
1715
1716 $ hg debugformat -v
1716 $ hg debugformat -v
1717 format-variant repo config default
1717 format-variant repo config default
1718 fncache: yes yes yes
1718 fncache: yes yes yes
1719 dirstate-v2: no no no
1719 dirstate-v2: no no no
1720 tracked-hint: no no no
1720 tracked-hint: no no no
1721 dotencode: yes yes yes
1721 dotencode: yes yes yes
1722 generaldelta: yes yes yes
1722 generaldelta: yes yes yes
1723 share-safe: yes yes yes
1723 share-safe: yes yes yes
1724 sparserevlog: yes yes yes
1724 sparserevlog: yes yes yes
1725 persistent-nodemap: no no no (no-rust !)
1725 persistent-nodemap: no no no (no-rust !)
1726 persistent-nodemap: yes yes no (rust !)
1726 persistent-nodemap: yes yes no (rust !)
1727 copies-sdc: no no no
1727 copies-sdc: no no no
1728 revlog-v2: yes no no
1728 revlog-v2: yes no no
1729 changelog-v2: no no no
1729 changelog-v2: no no no
1730 plain-cl-delta: yes yes yes
1730 plain-cl-delta: yes yes yes
1731 compression: zlib zlib zlib (no-zstd !)
1731 compression: zlib zlib zlib (no-zstd !)
1732 compression: zstd zstd zstd (zstd !)
1732 compression: zstd zstd zstd (zstd !)
1733 compression-level: default default default
1733 compression-level: default default default
1734 $ hg debugrequires
1734 $ hg debugrequires
1735 dotencode
1735 dotencode
1736 exp-revlogv2.2
1736 exp-revlogv2.2
1737 fncache
1737 fncache
1738 generaldelta
1738 generaldelta
1739 persistent-nodemap (rust !)
1739 persistent-nodemap (rust !)
1740 revlog-compression-zstd (zstd !)
1740 revlog-compression-zstd (zstd !)
1741 share-safe
1741 share-safe
1742 sparserevlog
1742 sparserevlog
1743 store
1743 store
1744 $ hg debugsidedata -c 0
1744 $ hg debugsidedata -c 0
1745 2 sidedata entries
1745 2 sidedata entries
1746 entry-0001 size 4
1746 entry-0001 size 4
1747 entry-0002 size 32
1747 entry-0002 size 32
1748
1748
1749 downgrade
1749 downgrade
1750
1750
1751 $ hg debugupgraderepo --config experimental.revlogv2=no --run --no-backup --quiet
1751 $ hg debugupgraderepo --config experimental.revlogv2=no --run --no-backup --quiet
1752 upgrade will perform the following actions:
1752 upgrade will perform the following actions:
1753
1753
1754 requirements
1754 requirements
1755 preserved: dotencode, fncache, generaldelta, share-safe, sparserevlog, store (no-zstd !)
1755 preserved: dotencode, fncache, generaldelta, share-safe, sparserevlog, store (no-zstd !)
1756 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, share-safe, sparserevlog, store (zstd no-rust !)
1756 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, share-safe, sparserevlog, store (zstd no-rust !)
1757 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, share-safe, sparserevlog, store (rust !)
1757 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, share-safe, sparserevlog, store (rust !)
1758 removed: exp-revlogv2.2
1758 removed: exp-revlogv2.2
1759 added: revlogv1
1759 added: revlogv1
1760
1760
1761 processed revlogs:
1761 processed revlogs:
1762 - all-filelogs
1762 - all-filelogs
1763 - changelog
1763 - changelog
1764 - manifest
1764 - manifest
1765
1765
1766 $ hg debugformat -v
1766 $ hg debugformat -v
1767 format-variant repo config default
1767 format-variant repo config default
1768 fncache: yes yes yes
1768 fncache: yes yes yes
1769 dirstate-v2: no no no
1769 dirstate-v2: no no no
1770 tracked-hint: no no no
1770 tracked-hint: no no no
1771 dotencode: yes yes yes
1771 dotencode: yes yes yes
1772 generaldelta: yes yes yes
1772 generaldelta: yes yes yes
1773 share-safe: yes yes yes
1773 share-safe: yes yes yes
1774 sparserevlog: yes yes yes
1774 sparserevlog: yes yes yes
1775 persistent-nodemap: no no no (no-rust !)
1775 persistent-nodemap: no no no (no-rust !)
1776 persistent-nodemap: yes yes no (rust !)
1776 persistent-nodemap: yes yes no (rust !)
1777 copies-sdc: no no no
1777 copies-sdc: no no no
1778 revlog-v2: no no no
1778 revlog-v2: no no no
1779 changelog-v2: no no no
1779 changelog-v2: no no no
1780 plain-cl-delta: yes yes yes
1780 plain-cl-delta: yes yes yes
1781 compression: zlib zlib zlib (no-zstd !)
1781 compression: zlib zlib zlib (no-zstd !)
1782 compression: zstd zstd zstd (zstd !)
1782 compression: zstd zstd zstd (zstd !)
1783 compression-level: default default default
1783 compression-level: default default default
1784 $ hg debugrequires
1784 $ hg debugrequires
1785 dotencode
1785 dotencode
1786 fncache
1786 fncache
1787 generaldelta
1787 generaldelta
1788 persistent-nodemap (rust !)
1788 persistent-nodemap (rust !)
1789 revlog-compression-zstd (zstd !)
1789 revlog-compression-zstd (zstd !)
1790 revlogv1
1790 revlogv1
1791 share-safe
1791 share-safe
1792 sparserevlog
1792 sparserevlog
1793 store
1793 store
1794 $ hg debugsidedata -c 0
1794 $ hg debugsidedata -c 0
1795
1795
1796 upgrade from hgrc
1796 upgrade from hgrc
1797
1797
1798 $ cat >> .hg/hgrc << EOF
1798 $ cat >> .hg/hgrc << EOF
1799 > [experimental]
1799 > [experimental]
1800 > revlogv2=enable-unstable-format-and-corrupt-my-data
1800 > revlogv2=enable-unstable-format-and-corrupt-my-data
1801 > EOF
1801 > EOF
1802 $ hg debugupgraderepo --run --no-backup --quiet
1802 $ hg debugupgraderepo --run --no-backup --quiet
1803 upgrade will perform the following actions:
1803 upgrade will perform the following actions:
1804
1804
1805 requirements
1805 requirements
1806 preserved: dotencode, fncache, generaldelta, share-safe, sparserevlog, store (no-zstd !)
1806 preserved: dotencode, fncache, generaldelta, share-safe, sparserevlog, store (no-zstd !)
1807 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, share-safe, sparserevlog, store (zstd no-rust !)
1807 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, share-safe, sparserevlog, store (zstd no-rust !)
1808 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, share-safe, sparserevlog, store (rust !)
1808 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, share-safe, sparserevlog, store (rust !)
1809 removed: revlogv1
1809 removed: revlogv1
1810 added: exp-revlogv2.2
1810 added: exp-revlogv2.2
1811
1811
1812 processed revlogs:
1812 processed revlogs:
1813 - all-filelogs
1813 - all-filelogs
1814 - changelog
1814 - changelog
1815 - manifest
1815 - manifest
1816
1816
1817 $ hg debugformat -v
1817 $ hg debugformat -v
1818 format-variant repo config default
1818 format-variant repo config default
1819 fncache: yes yes yes
1819 fncache: yes yes yes
1820 dirstate-v2: no no no
1820 dirstate-v2: no no no
1821 tracked-hint: no no no
1821 tracked-hint: no no no
1822 dotencode: yes yes yes
1822 dotencode: yes yes yes
1823 generaldelta: yes yes yes
1823 generaldelta: yes yes yes
1824 share-safe: yes yes yes
1824 share-safe: yes yes yes
1825 sparserevlog: yes yes yes
1825 sparserevlog: yes yes yes
1826 persistent-nodemap: no no no (no-rust !)
1826 persistent-nodemap: no no no (no-rust !)
1827 persistent-nodemap: yes yes no (rust !)
1827 persistent-nodemap: yes yes no (rust !)
1828 copies-sdc: no no no
1828 copies-sdc: no no no
1829 revlog-v2: yes yes no
1829 revlog-v2: yes yes no
1830 changelog-v2: no no no
1830 changelog-v2: no no no
1831 plain-cl-delta: yes yes yes
1831 plain-cl-delta: yes yes yes
1832 compression: zlib zlib zlib (no-zstd !)
1832 compression: zlib zlib zlib (no-zstd !)
1833 compression: zstd zstd zstd (zstd !)
1833 compression: zstd zstd zstd (zstd !)
1834 compression-level: default default default
1834 compression-level: default default default
1835 $ hg debugrequires
1835 $ hg debugrequires
1836 dotencode
1836 dotencode
1837 exp-revlogv2.2
1837 exp-revlogv2.2
1838 fncache
1838 fncache
1839 generaldelta
1839 generaldelta
1840 persistent-nodemap (rust !)
1840 persistent-nodemap (rust !)
1841 revlog-compression-zstd (zstd !)
1841 revlog-compression-zstd (zstd !)
1842 share-safe
1842 share-safe
1843 sparserevlog
1843 sparserevlog
1844 store
1844 store
1845 $ hg debugsidedata -c 0
1845 $ hg debugsidedata -c 0
1846
1846
1847 Demonstrate that nothing to perform upgrade will still run all the way through
1847 Demonstrate that nothing to perform upgrade will still run all the way through
1848
1848
1849 $ hg debugupgraderepo --run
1849 $ hg debugupgraderepo --run
1850 nothing to do
1850 nothing to do
1851
1851
1852 #if no-rust
1852 #if no-rust
1853
1853
1854 $ cat << EOF >> $HGRCPATH
1854 $ cat << EOF >> $HGRCPATH
1855 > [storage]
1855 > [storage]
1856 > dirstate-v2.slow-path = allow
1856 > dirstate-v2.slow-path = allow
1857 > EOF
1857 > EOF
1858
1858
1859 #endif
1859 #endif
1860
1860
1861 Upgrade to dirstate-v2
1861 Upgrade to dirstate-v2
1862
1862
1863 $ hg debugformat -v --config format.use-dirstate-v2=1 | grep dirstate-v2
1863 $ hg debugformat -v --config format.use-dirstate-v2=1 | grep dirstate-v2
1864 dirstate-v2: no yes no
1864 dirstate-v2: no yes no
1865 $ hg debugupgraderepo --config format.use-dirstate-v2=1 --run
1865 $ hg debugupgraderepo --config format.use-dirstate-v2=1 --run
1866 upgrade will perform the following actions:
1866 upgrade will perform the following actions:
1867
1867
1868 requirements
1868 requirements
1869 preserved: * (glob)
1869 preserved: * (glob)
1870 added: dirstate-v2
1870 added: dirstate-v2
1871
1871
1872 dirstate-v2
1872 dirstate-v2
1873 "hg status" will be faster
1873 "hg status" will be faster
1874
1874
1875 no revlogs to process
1875 no revlogs to process
1876
1876
1877 beginning upgrade...
1877 beginning upgrade...
1878 repository locked and read-only
1878 repository locked and read-only
1879 creating temporary repository to stage upgraded data: $TESTTMP/sparserevlogrepo/.hg/upgrade.* (glob)
1879 creating temporary repository to stage upgraded data: $TESTTMP/sparserevlogrepo/.hg/upgrade.* (glob)
1880 (it is safe to interrupt this process any time before data migration completes)
1880 (it is safe to interrupt this process any time before data migration completes)
1881 upgrading to dirstate-v2 from v1
1881 upgrading to dirstate-v2 from v1
1882 replaced files will be backed up at $TESTTMP/sparserevlogrepo/.hg/upgradebackup.* (glob)
1882 replaced files will be backed up at $TESTTMP/sparserevlogrepo/.hg/upgradebackup.* (glob)
1883 removing temporary repository $TESTTMP/sparserevlogrepo/.hg/upgrade.* (glob)
1883 removing temporary repository $TESTTMP/sparserevlogrepo/.hg/upgrade.* (glob)
1884 $ ls .hg/upgradebackup.*/dirstate
1884 $ ls .hg/upgradebackup.*/dirstate
1885 .hg/upgradebackup.*/dirstate (glob)
1885 .hg/upgradebackup.*/dirstate (glob)
1886 $ hg debugformat -v | grep dirstate-v2
1886 $ hg debugformat -v | grep dirstate-v2
1887 dirstate-v2: yes no no
1887 dirstate-v2: yes no no
1888 $ hg status
1888 $ hg status
1889 $ dd bs=12 count=1 if=.hg/dirstate 2> /dev/null
1889 $ dd bs=12 count=1 if=.hg/dirstate 2> /dev/null
1890 dirstate-v2
1890 dirstate-v2
1891
1891
1892 Downgrade from dirstate-v2
1892 Downgrade from dirstate-v2
1893
1893
1894 $ hg debugupgraderepo --run
1894 $ hg debugupgraderepo --run
1895 upgrade will perform the following actions:
1895 upgrade will perform the following actions:
1896
1896
1897 requirements
1897 requirements
1898 preserved: * (glob)
1898 preserved: * (glob)
1899 removed: dirstate-v2
1899 removed: dirstate-v2
1900
1900
1901 no revlogs to process
1901 no revlogs to process
1902
1902
1903 beginning upgrade...
1903 beginning upgrade...
1904 repository locked and read-only
1904 repository locked and read-only
1905 creating temporary repository to stage upgraded data: $TESTTMP/sparserevlogrepo/.hg/upgrade.* (glob)
1905 creating temporary repository to stage upgraded data: $TESTTMP/sparserevlogrepo/.hg/upgrade.* (glob)
1906 (it is safe to interrupt this process any time before data migration completes)
1906 (it is safe to interrupt this process any time before data migration completes)
1907 downgrading from dirstate-v2 to v1
1907 downgrading from dirstate-v2 to v1
1908 replaced files will be backed up at $TESTTMP/sparserevlogrepo/.hg/upgradebackup.* (glob)
1908 replaced files will be backed up at $TESTTMP/sparserevlogrepo/.hg/upgradebackup.* (glob)
1909 removing temporary repository $TESTTMP/sparserevlogrepo/.hg/upgrade.* (glob)
1909 removing temporary repository $TESTTMP/sparserevlogrepo/.hg/upgrade.* (glob)
1910 $ hg debugformat -v | grep dirstate-v2
1910 $ hg debugformat -v | grep dirstate-v2
1911 dirstate-v2: no no no
1911 dirstate-v2: no no no
1912 $ hg status
1912 $ hg status
1913
1913
1914 $ cd ..
1914 $ cd ..
1915
1915
1916 dirstate-v2: upgrade and downgrade from and empty repository:
1916 dirstate-v2: upgrade and downgrade from and empty repository:
1917 -------------------------------------------------------------
1917 -------------------------------------------------------------
1918
1918
1919 $ hg init --config format.use-dirstate-v2=no dirstate-v2-empty
1919 $ hg init --config format.use-dirstate-v2=no dirstate-v2-empty
1920 $ cd dirstate-v2-empty
1920 $ cd dirstate-v2-empty
1921 $ hg debugformat | grep dirstate-v2
1921 $ hg debugformat | grep dirstate-v2
1922 dirstate-v2: no
1922 dirstate-v2: no
1923
1923
1924 upgrade
1924 upgrade
1925
1925
1926 $ hg debugupgraderepo --run --config format.use-dirstate-v2=yes
1926 $ hg debugupgraderepo --run --config format.use-dirstate-v2=yes
1927 upgrade will perform the following actions:
1927 upgrade will perform the following actions:
1928
1928
1929 requirements
1929 requirements
1930 preserved: * (glob)
1930 preserved: * (glob)
1931 added: dirstate-v2
1931 added: dirstate-v2
1932
1932
1933 dirstate-v2
1933 dirstate-v2
1934 "hg status" will be faster
1934 "hg status" will be faster
1935
1935
1936 no revlogs to process
1936 no revlogs to process
1937
1937
1938 beginning upgrade...
1938 beginning upgrade...
1939 repository locked and read-only
1939 repository locked and read-only
1940 creating temporary repository to stage upgraded data: $TESTTMP/dirstate-v2-empty/.hg/upgrade.* (glob)
1940 creating temporary repository to stage upgraded data: $TESTTMP/dirstate-v2-empty/.hg/upgrade.* (glob)
1941 (it is safe to interrupt this process any time before data migration completes)
1941 (it is safe to interrupt this process any time before data migration completes)
1942 upgrading to dirstate-v2 from v1
1942 upgrading to dirstate-v2 from v1
1943 replaced files will be backed up at $TESTTMP/dirstate-v2-empty/.hg/upgradebackup.* (glob)
1943 replaced files will be backed up at $TESTTMP/dirstate-v2-empty/.hg/upgradebackup.* (glob)
1944 removing temporary repository $TESTTMP/dirstate-v2-empty/.hg/upgrade.* (glob)
1944 removing temporary repository $TESTTMP/dirstate-v2-empty/.hg/upgrade.* (glob)
1945 $ hg debugformat | grep dirstate-v2
1945 $ hg debugformat | grep dirstate-v2
1946 dirstate-v2: yes
1946 dirstate-v2: yes
1947
1947
1948 downgrade
1948 downgrade
1949
1949
1950 $ hg debugupgraderepo --run --config format.use-dirstate-v2=no
1950 $ hg debugupgraderepo --run --config format.use-dirstate-v2=no
1951 upgrade will perform the following actions:
1951 upgrade will perform the following actions:
1952
1952
1953 requirements
1953 requirements
1954 preserved: * (glob)
1954 preserved: * (glob)
1955 removed: dirstate-v2
1955 removed: dirstate-v2
1956
1956
1957 no revlogs to process
1957 no revlogs to process
1958
1958
1959 beginning upgrade...
1959 beginning upgrade...
1960 repository locked and read-only
1960 repository locked and read-only
1961 creating temporary repository to stage upgraded data: $TESTTMP/dirstate-v2-empty/.hg/upgrade.* (glob)
1961 creating temporary repository to stage upgraded data: $TESTTMP/dirstate-v2-empty/.hg/upgrade.* (glob)
1962 (it is safe to interrupt this process any time before data migration completes)
1962 (it is safe to interrupt this process any time before data migration completes)
1963 downgrading from dirstate-v2 to v1
1963 downgrading from dirstate-v2 to v1
1964 replaced files will be backed up at $TESTTMP/dirstate-v2-empty/.hg/upgradebackup.* (glob)
1964 replaced files will be backed up at $TESTTMP/dirstate-v2-empty/.hg/upgradebackup.* (glob)
1965 removing temporary repository $TESTTMP/dirstate-v2-empty/.hg/upgrade.* (glob)
1965 removing temporary repository $TESTTMP/dirstate-v2-empty/.hg/upgrade.* (glob)
1966 $ hg debugformat | grep dirstate-v2
1966 $ hg debugformat | grep dirstate-v2
1967 dirstate-v2: no
1967 dirstate-v2: no
1968
1968
1969 $ cd ..
1969 $ cd ..
1970
1970
1971 Test automatic upgrade/downgrade
1971 Test automatic upgrade/downgrade
1972 ================================
1972 ================================
1973
1973
1974
1974
1975 For dirstate v2
1975 For dirstate v2
1976 ---------------
1976 ---------------
1977
1977
1978 create an initial repository
1978 create an initial repository
1979
1979
1980 $ hg init auto-upgrade \
1980 $ hg init auto-upgrade \
1981 > --config format.use-dirstate-v2=no \
1981 > --config format.use-dirstate-v2=no \
1982 > --config format.use-dirstate-tracked-hint=yes \
1982 > --config format.use-dirstate-tracked-hint=yes \
1983 > --config format.use-share-safe=no
1983 > --config format.use-share-safe=no
1984 $ hg debugbuilddag -R auto-upgrade --new-file .+5
1984 $ hg debugbuilddag -R auto-upgrade --new-file .+5
1985 $ hg -R auto-upgrade update
1985 $ hg -R auto-upgrade update
1986 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1986 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1987 $ hg debugformat -R auto-upgrade | grep dirstate-v2
1987 $ hg debugformat -R auto-upgrade | grep dirstate-v2
1988 dirstate-v2: no
1988 dirstate-v2: no
1989
1989
1990 upgrade it to dirstate-v2 automatically
1990 upgrade it to dirstate-v2 automatically
1991
1991
1992 $ hg status -R auto-upgrade \
1992 $ hg status -R auto-upgrade \
1993 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
1993 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
1994 > --config format.use-dirstate-v2=yes
1994 > --config format.use-dirstate-v2=yes
1995 automatically upgrading repository to the `dirstate-v2` feature
1995 automatically upgrading repository to the `dirstate-v2` feature
1996 (see `hg help config.format.use-dirstate-v2` for details)
1996 (see `hg help config.format.use-dirstate-v2` for details)
1997 $ hg debugformat -R auto-upgrade | grep dirstate-v2
1997 $ hg debugformat -R auto-upgrade | grep dirstate-v2
1998 dirstate-v2: yes
1998 dirstate-v2: yes
1999
1999
2000 downgrade it from dirstate-v2 automatically
2000 downgrade it from dirstate-v2 automatically
2001
2001
2002 $ hg status -R auto-upgrade \
2002 $ hg status -R auto-upgrade \
2003 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
2003 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
2004 > --config format.use-dirstate-v2=no
2004 > --config format.use-dirstate-v2=no
2005 automatically downgrading repository from the `dirstate-v2` feature
2005 automatically downgrading repository from the `dirstate-v2` feature
2006 (see `hg help config.format.use-dirstate-v2` for details)
2006 (see `hg help config.format.use-dirstate-v2` for details)
2007 $ hg debugformat -R auto-upgrade | grep dirstate-v2
2007 $ hg debugformat -R auto-upgrade | grep dirstate-v2
2008 dirstate-v2: no
2008 dirstate-v2: no
2009
2009
2010
2010
2011 For multiple change at the same time
2011 For multiple change at the same time
2012 ------------------------------------
2012 ------------------------------------
2013
2013
2014 $ hg debugformat -R auto-upgrade | egrep '(dirstate-v2|tracked|share-safe)'
2014 $ hg debugformat -R auto-upgrade | egrep '(dirstate-v2|tracked|share-safe)'
2015 dirstate-v2: no
2015 dirstate-v2: no
2016 tracked-hint: yes
2016 tracked-hint: yes
2017 share-safe: no
2017 share-safe: no
2018
2018
2019 $ hg status -R auto-upgrade \
2019 $ hg status -R auto-upgrade \
2020 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
2020 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
2021 > --config format.use-dirstate-v2=yes \
2021 > --config format.use-dirstate-v2=yes \
2022 > --config format.use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories=yes \
2022 > --config format.use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories=yes \
2023 > --config format.use-dirstate-tracked-hint=no\
2023 > --config format.use-dirstate-tracked-hint=no\
2024 > --config format.use-share-safe.automatic-upgrade-of-mismatching-repositories=yes \
2024 > --config format.use-share-safe.automatic-upgrade-of-mismatching-repositories=yes \
2025 > --config format.use-share-safe=yes
2025 > --config format.use-share-safe=yes
2026 automatically upgrading repository to the `dirstate-v2` feature
2026 automatically upgrading repository to the `dirstate-v2` feature
2027 (see `hg help config.format.use-dirstate-v2` for details)
2027 (see `hg help config.format.use-dirstate-v2` for details)
2028 automatically upgrading repository to the `share-safe` feature
2028 automatically upgrading repository to the `share-safe` feature
2029 (see `hg help config.format.use-share-safe` for details)
2029 (see `hg help config.format.use-share-safe` for details)
2030 automatically downgrading repository from the `tracked-hint` feature
2030 automatically downgrading repository from the `tracked-hint` feature
2031 (see `hg help config.format.use-dirstate-tracked-hint` for details)
2031 (see `hg help config.format.use-dirstate-tracked-hint` for details)
2032 $ hg debugformat -R auto-upgrade | egrep '(dirstate-v2|tracked|share-safe)'
2032 $ hg debugformat -R auto-upgrade | egrep '(dirstate-v2|tracked|share-safe)'
2033 dirstate-v2: yes
2033 dirstate-v2: yes
2034 tracked-hint: no
2034 tracked-hint: no
2035 share-safe: yes
2035 share-safe: yes
2036
2036
2037 Quiet upgrade and downgrade
2037 Quiet upgrade and downgrade
2038 ---------------------------
2038 ---------------------------
2039
2039
2040
2040
2041 $ hg debugformat -R auto-upgrade | egrep '(dirstate-v2|tracked|share-safe)'
2041 $ hg debugformat -R auto-upgrade | egrep '(dirstate-v2|tracked|share-safe)'
2042 dirstate-v2: yes
2042 dirstate-v2: yes
2043 tracked-hint: no
2043 tracked-hint: no
2044 share-safe: yes
2044 share-safe: yes
2045 $ hg status -R auto-upgrade \
2045 $ hg status -R auto-upgrade \
2046 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
2046 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
2047 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet=yes \
2047 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet=yes \
2048 > --config format.use-dirstate-v2=no \
2048 > --config format.use-dirstate-v2=no \
2049 > --config format.use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories=yes \
2049 > --config format.use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories=yes \
2050 > --config format.use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet=yes \
2050 > --config format.use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet=yes \
2051 > --config format.use-dirstate-tracked-hint=yes \
2051 > --config format.use-dirstate-tracked-hint=yes \
2052 > --config format.use-share-safe.automatic-upgrade-of-mismatching-repositories=yes \
2052 > --config format.use-share-safe.automatic-upgrade-of-mismatching-repositories=yes \
2053 > --config format.use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet=yes \
2053 > --config format.use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet=yes \
2054 > --config format.use-share-safe=no
2054 > --config format.use-share-safe=no
2055
2055
2056 $ hg debugformat -R auto-upgrade | egrep '(dirstate-v2|tracked|share-safe)'
2056 $ hg debugformat -R auto-upgrade | egrep '(dirstate-v2|tracked|share-safe)'
2057 dirstate-v2: no
2057 dirstate-v2: no
2058 tracked-hint: yes
2058 tracked-hint: yes
2059 share-safe: no
2059 share-safe: no
2060
2060
2061 $ hg status -R auto-upgrade \
2061 $ hg status -R auto-upgrade \
2062 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
2062 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
2063 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet=yes \
2063 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet=yes \
2064 > --config format.use-dirstate-v2=yes \
2064 > --config format.use-dirstate-v2=yes \
2065 > --config format.use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories=yes \
2065 > --config format.use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories=yes \
2066 > --config format.use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet=yes \
2066 > --config format.use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet=yes \
2067 > --config format.use-dirstate-tracked-hint=no\
2067 > --config format.use-dirstate-tracked-hint=no\
2068 > --config format.use-share-safe.automatic-upgrade-of-mismatching-repositories=yes \
2068 > --config format.use-share-safe.automatic-upgrade-of-mismatching-repositories=yes \
2069 > --config format.use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet=yes \
2069 > --config format.use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet=yes \
2070 > --config format.use-share-safe=yes
2070 > --config format.use-share-safe=yes
2071 $ hg debugformat -R auto-upgrade | egrep '(dirstate-v2|tracked|share-safe)'
2071 $ hg debugformat -R auto-upgrade | egrep '(dirstate-v2|tracked|share-safe)'
2072 dirstate-v2: yes
2072 dirstate-v2: yes
2073 tracked-hint: no
2073 tracked-hint: no
2074 share-safe: yes
2074 share-safe: yes
2075
2075
2076 Attempting Auto-upgrade on a read-only repository
2076 Attempting Auto-upgrade on a read-only repository
2077 -------------------------------------------------
2077 -------------------------------------------------
2078
2078
2079 $ chmod -R a-w auto-upgrade
2079 $ chmod -R a-w auto-upgrade
2080
2080
2081 $ hg status -R auto-upgrade \
2081 $ hg status -R auto-upgrade \
2082 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
2082 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
2083 > --config format.use-dirstate-v2=no
2083 > --config format.use-dirstate-v2=no
2084 $ hg debugformat -R auto-upgrade | grep dirstate-v2
2084 $ hg debugformat -R auto-upgrade | grep dirstate-v2
2085 dirstate-v2: yes
2085 dirstate-v2: yes
2086
2086
2087 $ chmod -R u+w auto-upgrade
2087 $ chmod -R u+w auto-upgrade
2088
2088
2089 Attempting Auto-upgrade on a locked repository
2089 Attempting Auto-upgrade on a locked repository
2090 ----------------------------------------------
2090 ----------------------------------------------
2091
2091
2092 $ hg -R auto-upgrade debuglock --set-lock --quiet &
2092 $ hg -R auto-upgrade debuglock --set-lock --quiet &
2093 $ echo $! >> $DAEMON_PIDS
2093 $ echo $! >> $DAEMON_PIDS
2094 $ $RUNTESTDIR/testlib/wait-on-file 10 auto-upgrade/.hg/store/lock
2094 $ $RUNTESTDIR/testlib/wait-on-file 10 auto-upgrade/.hg/store/lock
2095 $ hg status -R auto-upgrade \
2095 $ hg status -R auto-upgrade \
2096 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
2096 > --config format.use-dirstate-v2.automatic-upgrade-of-mismatching-repositories=yes \
2097 > --config format.use-dirstate-v2=no
2097 > --config format.use-dirstate-v2=no
2098 $ hg debugformat -R auto-upgrade | grep dirstate-v2
2098 $ hg debugformat -R auto-upgrade | grep dirstate-v2
2099 dirstate-v2: yes
2099 dirstate-v2: yes
2100
2100
2101 $ killdaemons.py
2101 $ killdaemons.py
General Comments 0
You need to be logged in to leave comments. Login now