Show More
@@ -1098,7 +1098,8 b' class localrepository(object):' | |||||
1098 | aftertrans(renames), |
|
1098 | aftertrans(renames), | |
1099 | self.store.createmode, |
|
1099 | self.store.createmode, | |
1100 | validator=validate, |
|
1100 | validator=validate, | |
1101 |
releasefn=releasefn |
|
1101 | releasefn=releasefn, | |
|
1102 | checkambigfiles=_cachedfiles) | |||
1102 | tr.changes['revs'] = set() |
|
1103 | tr.changes['revs'] = set() | |
1103 | tr.changes['obsmarkers'] = set() |
|
1104 | tr.changes['obsmarkers'] = set() | |
1104 |
|
1105 | |||
@@ -1164,7 +1165,8 b' class localrepository(object):' | |||||
1164 | vfsmap = {'': self.svfs, |
|
1165 | vfsmap = {'': self.svfs, | |
1165 | 'plain': self.vfs,} |
|
1166 | 'plain': self.vfs,} | |
1166 | transaction.rollback(self.svfs, vfsmap, "journal", |
|
1167 | transaction.rollback(self.svfs, vfsmap, "journal", | |
1167 |
self.ui.warn |
|
1168 | self.ui.warn, | |
|
1169 | checkambigfiles=_cachedfiles) | |||
1168 | self.invalidate() |
|
1170 | self.invalidate() | |
1169 | return True |
|
1171 | return True | |
1170 | else: |
|
1172 | else: | |
@@ -1220,7 +1222,8 b' class localrepository(object):' | |||||
1220 | parents = self.dirstate.parents() |
|
1222 | parents = self.dirstate.parents() | |
1221 | self.destroying() |
|
1223 | self.destroying() | |
1222 | vfsmap = {'plain': self.vfs, '': self.svfs} |
|
1224 | vfsmap = {'plain': self.vfs, '': self.svfs} | |
1223 |
transaction.rollback(self.svfs, vfsmap, 'undo', ui.warn |
|
1225 | transaction.rollback(self.svfs, vfsmap, 'undo', ui.warn, | |
|
1226 | checkambigfiles=_cachedfiles) | |||
1224 | if self.vfs.exists('undo.bookmarks'): |
|
1227 | if self.vfs.exists('undo.bookmarks'): | |
1225 | self.vfs.rename('undo.bookmarks', 'bookmarks', checkambig=True) |
|
1228 | self.vfs.rename('undo.bookmarks', 'bookmarks', checkambig=True) | |
1226 | if self.svfs.exists('undo.phaseroots'): |
|
1229 | if self.svfs.exists('undo.phaseroots'): |
@@ -44,11 +44,12 b' def active(func):' | |||||
44 | return _active |
|
44 | return _active | |
45 |
|
45 | |||
46 | def _playback(journal, report, opener, vfsmap, entries, backupentries, |
|
46 | def _playback(journal, report, opener, vfsmap, entries, backupentries, | |
47 | unlink=True): |
|
47 | unlink=True, checkambigfiles=None): | |
48 | for f, o, _ignore in entries: |
|
48 | for f, o, _ignore in entries: | |
49 | if o or not unlink: |
|
49 | if o or not unlink: | |
|
50 | checkambig = checkambigfiles and (f, '') in checkambigfiles | |||
50 | try: |
|
51 | try: | |
51 |
fp = opener(f, 'a', checkambig= |
|
52 | fp = opener(f, 'a', checkambig=checkambig) | |
52 | fp.truncate(o) |
|
53 | fp.truncate(o) | |
53 | fp.close() |
|
54 | fp.close() | |
54 | except IOError: |
|
55 | except IOError: | |
@@ -101,7 +102,8 b' def _playback(journal, report, opener, v' | |||||
101 |
|
102 | |||
102 | class transaction(object): |
|
103 | class transaction(object): | |
103 | def __init__(self, report, opener, vfsmap, journalname, undoname=None, |
|
104 | def __init__(self, report, opener, vfsmap, journalname, undoname=None, | |
104 |
after=None, createmode=None, validator=None, releasefn=None |
|
105 | after=None, createmode=None, validator=None, releasefn=None, | |
|
106 | checkambigfiles=None): | |||
105 | """Begin a new transaction |
|
107 | """Begin a new transaction | |
106 |
|
108 | |||
107 | Begins a new transaction that allows rolling back writes in the event of |
|
109 | Begins a new transaction that allows rolling back writes in the event of | |
@@ -110,6 +112,10 b' class transaction(object):' | |||||
110 | * `after`: called after the transaction has been committed |
|
112 | * `after`: called after the transaction has been committed | |
111 | * `createmode`: the mode of the journal file that will be created |
|
113 | * `createmode`: the mode of the journal file that will be created | |
112 | * `releasefn`: called after releasing (with transaction and result) |
|
114 | * `releasefn`: called after releasing (with transaction and result) | |
|
115 | ||||
|
116 | `checkambigfiles` is a set of (path, vfs-location) tuples, | |||
|
117 | which determine whether file stat ambiguity should be avoided | |||
|
118 | for corresponded files. | |||
113 | """ |
|
119 | """ | |
114 | self.count = 1 |
|
120 | self.count = 1 | |
115 | self.usages = 1 |
|
121 | self.usages = 1 | |
@@ -137,6 +143,10 b' class transaction(object):' | |||||
137 | releasefn = lambda tr, success: None |
|
143 | releasefn = lambda tr, success: None | |
138 | self.releasefn = releasefn |
|
144 | self.releasefn = releasefn | |
139 |
|
145 | |||
|
146 | self.checkambigfiles = set() | |||
|
147 | if checkambigfiles: | |||
|
148 | self.checkambigfiles.update(checkambigfiles) | |||
|
149 | ||||
140 | # A dict dedicated to precisely tracking the changes introduced in the |
|
150 | # A dict dedicated to precisely tracking the changes introduced in the | |
141 | # transaction. |
|
151 | # transaction. | |
142 | self.changes = {} |
|
152 | self.changes = {} | |
@@ -564,7 +574,8 b' class transaction(object):' | |||||
564 | # Prevent double usage and help clear cycles. |
|
574 | # Prevent double usage and help clear cycles. | |
565 | self._abortcallback = None |
|
575 | self._abortcallback = None | |
566 | _playback(self.journal, self.report, self.opener, self._vfsmap, |
|
576 | _playback(self.journal, self.report, self.opener, self._vfsmap, | |
567 |
self.entries, self._backupentries, False |
|
577 | self.entries, self._backupentries, False, | |
|
578 | checkambigfiles=self.checkambigfiles) | |||
568 | self.report(_("rollback completed\n")) |
|
579 | self.report(_("rollback completed\n")) | |
569 | except BaseException: |
|
580 | except BaseException: | |
570 | self.report(_("rollback failed - please run hg recover\n")) |
|
581 | self.report(_("rollback failed - please run hg recover\n")) | |
@@ -573,7 +584,7 b' class transaction(object):' | |||||
573 | self.releasefn(self, False) # notify failure of transaction |
|
584 | self.releasefn(self, False) # notify failure of transaction | |
574 | self.releasefn = None # Help prevent cycles. |
|
585 | self.releasefn = None # Help prevent cycles. | |
575 |
|
586 | |||
576 | def rollback(opener, vfsmap, file, report): |
|
587 | def rollback(opener, vfsmap, file, report, checkambigfiles=None): | |
577 | """Rolls back the transaction contained in the given file |
|
588 | """Rolls back the transaction contained in the given file | |
578 |
|
589 | |||
579 | Reads the entries in the specified file, and the corresponding |
|
590 | Reads the entries in the specified file, and the corresponding | |
@@ -584,6 +595,10 b' def rollback(opener, vfsmap, file, repor' | |||||
584 | file\0offset pairs, delimited by newlines. The corresponding |
|
595 | file\0offset pairs, delimited by newlines. The corresponding | |
585 | '*.backupfiles' file should contain a list of file\0backupfile |
|
596 | '*.backupfiles' file should contain a list of file\0backupfile | |
586 | pairs, delimited by \0. |
|
597 | pairs, delimited by \0. | |
|
598 | ||||
|
599 | `checkambigfiles` is a set of (path, vfs-location) tuples, | |||
|
600 | which determine whether file stat ambiguity should be avoided at | |||
|
601 | restoring corresponded files. | |||
587 | """ |
|
602 | """ | |
588 | entries = [] |
|
603 | entries = [] | |
589 | backupentries = [] |
|
604 | backupentries = [] | |
@@ -615,4 +630,5 b' def rollback(opener, vfsmap, file, repor' | |||||
615 | report(_("journal was created by a different version of " |
|
630 | report(_("journal was created by a different version of " | |
616 | "Mercurial\n")) |
|
631 | "Mercurial\n")) | |
617 |
|
632 | |||
618 |
_playback(file, report, opener, vfsmap, entries, backupentries |
|
633 | _playback(file, report, opener, vfsmap, entries, backupentries, | |
|
634 | checkambigfiles=checkambigfiles) |
@@ -39,8 +39,9 b' test qpush on empty series' | |||||
39 | > from mercurial import extensions, transaction |
|
39 | > from mercurial import extensions, transaction | |
40 | > def wrapplayback(orig, |
|
40 | > def wrapplayback(orig, | |
41 | > journal, report, opener, vfsmap, entries, backupentries, |
|
41 | > journal, report, opener, vfsmap, entries, backupentries, | |
42 | > unlink=True): |
|
42 | > unlink=True, checkambigfiles=None): | |
43 |
> orig(journal, report, opener, vfsmap, entries, backupentries, unlink |
|
43 | > orig(journal, report, opener, vfsmap, entries, backupentries, unlink, | |
|
44 | > checkambigfiles) | |||
44 | > # Touching files truncated at "transaction.abort" causes |
|
45 | > # Touching files truncated at "transaction.abort" causes | |
45 | > # forcible re-loading invalidated filecache properties |
|
46 | > # forcible re-loading invalidated filecache properties | |
46 | > # (including repo.changelog) |
|
47 | > # (including repo.changelog) |
General Comments 0
You need to be logged in to leave comments.
Login now