9 import urllib |
9 import urllib |
10 import peer, changegroup, subrepo, pushkey, obsolete, repoview |
10 import peer, changegroup, subrepo, pushkey, obsolete, repoview |
11 import changelog, dirstate, filelog, manifest, context, bookmarks, phases |
11 import changelog, dirstate, filelog, manifest, context, bookmarks, phases |
12 import lock as lockmod |
12 import lock as lockmod |
13 import transaction, store, encoding, exchange, bundle2 |
13 import transaction, store, encoding, exchange, bundle2 |
14 import scmutil, util, extensions, hook, error, revset |
14 import scmutil, util, extensions, hook, error, revset, cmdutil |
15 import match as matchmod |
15 import match as matchmod |
16 import merge as mergemod |
16 import merge as mergemod |
17 import tags as tagsmod |
17 import tags as tagsmod |
18 from lock import release |
18 from lock import release |
19 import weakref, errno, os, time, inspect, random |
19 import weakref, errno, os, time, inspect, random |
1082 return False |
1082 return False |
1083 finally: |
1083 finally: |
1084 lock.release() |
1084 lock.release() |
1085 |
1085 |
1086 def rollback(self, dryrun=False, force=False): |
1086 def rollback(self, dryrun=False, force=False): |
1087 wlock = lock = None |
1087 wlock = lock = dsguard = None |
1088 try: |
1088 try: |
1089 wlock = self.wlock() |
1089 wlock = self.wlock() |
1090 lock = self.lock() |
1090 lock = self.lock() |
1091 if self.svfs.exists("undo"): |
1091 if self.svfs.exists("undo"): |
1092 return self._rollback(dryrun, force) |
1092 dsguard = cmdutil.dirstateguard(self, 'rollback') |
|
1093 |
|
1094 return self._rollback(dryrun, force, dsguard) |
1093 else: |
1095 else: |
1094 self.ui.warn(_("no rollback information available\n")) |
1096 self.ui.warn(_("no rollback information available\n")) |
1095 return 1 |
1097 return 1 |
1096 finally: |
1098 finally: |
1097 release(lock, wlock) |
1099 release(dsguard, lock, wlock) |
1098 |
1100 |
1099 @unfilteredmethod # Until we get smarter cache management |
1101 @unfilteredmethod # Until we get smarter cache management |
1100 def _rollback(self, dryrun, force): |
1102 def _rollback(self, dryrun, force, dsguard): |
1101 ui = self.ui |
1103 ui = self.ui |
1102 try: |
1104 try: |
1103 args = self.vfs.read('undo.desc').splitlines() |
1105 args = self.vfs.read('undo.desc').splitlines() |
1104 (oldlen, desc, detail) = (int(args[0]), args[1], None) |
1106 (oldlen, desc, detail) = (int(args[0]), args[1], None) |
1105 if len(args) >= 3: |
1107 if len(args) >= 3: |
1138 self.invalidate() |
1140 self.invalidate() |
1139 |
1141 |
1140 parentgone = (parents[0] not in self.changelog.nodemap or |
1142 parentgone = (parents[0] not in self.changelog.nodemap or |
1141 parents[1] not in self.changelog.nodemap) |
1143 parents[1] not in self.changelog.nodemap) |
1142 if parentgone: |
1144 if parentgone: |
|
1145 # prevent dirstateguard from overwriting already restored one |
|
1146 dsguard.close() |
|
1147 |
1143 self.vfs.rename('undo.dirstate', 'dirstate') |
1148 self.vfs.rename('undo.dirstate', 'dirstate') |
1144 try: |
1149 try: |
1145 branch = self.vfs.read('undo.branch') |
1150 branch = self.vfs.read('undo.branch') |
1146 self.dirstate.setbranch(encoding.tolocal(branch)) |
1151 self.dirstate.setbranch(encoding.tolocal(branch)) |
1147 except IOError: |
1152 except IOError: |