11 import changelog, dirstate, filelog, manifest, context, weakref |
11 import changelog, dirstate, filelog, manifest, context, weakref |
12 import lock, transaction, stat, errno, ui, store, encoding |
12 import lock, transaction, stat, errno, ui, store, encoding |
13 import os, time, util, extensions, hook, inspect, error |
13 import os, time, util, extensions, hook, inspect, error |
14 import match as match_ |
14 import match as match_ |
15 import merge as merge_ |
15 import merge as merge_ |
|
16 |
|
17 from lock import release |
16 |
18 |
17 class localrepository(repo.repository): |
19 class localrepository(repo.repository): |
18 capabilities = util.set(('lookup', 'changegroupsubset')) |
20 capabilities = util.set(('lookup', 'changegroupsubset')) |
19 supported = ('revlogv1', 'store', 'fncache') |
21 supported = ('revlogv1', 'store', 'fncache') |
20 |
22 |
618 self.store.createmode) |
620 self.store.createmode) |
619 self._transref = weakref.ref(tr) |
621 self._transref = weakref.ref(tr) |
620 return tr |
622 return tr |
621 |
623 |
622 def recover(self): |
624 def recover(self): |
623 l = self.lock() |
625 lock = self.lock() |
624 try: |
626 try: |
625 if os.path.exists(self.sjoin("journal")): |
627 if os.path.exists(self.sjoin("journal")): |
626 self.ui.status(_("rolling back interrupted transaction\n")) |
628 self.ui.status(_("rolling back interrupted transaction\n")) |
627 transaction.rollback(self.sopener, self.sjoin("journal")) |
629 transaction.rollback(self.sopener, self.sjoin("journal")) |
628 self.invalidate() |
630 self.invalidate() |
629 return True |
631 return True |
630 else: |
632 else: |
631 self.ui.warn(_("no interrupted transaction available\n")) |
633 self.ui.warn(_("no interrupted transaction available\n")) |
632 return False |
634 return False |
633 finally: |
635 finally: |
634 del l |
636 lock.release() |
635 |
637 |
636 def rollback(self): |
638 def rollback(self): |
637 wlock = lock = None |
639 wlock = lock = None |
638 try: |
640 try: |
639 wlock = self.wlock() |
641 wlock = self.wlock() |
849 lock = self.lock() |
851 lock = self.lock() |
850 return self._commitctx(ctx, force=True, force_editor=False, |
852 return self._commitctx(ctx, force=True, force_editor=False, |
851 empty_ok=True, use_dirstate=False, |
853 empty_ok=True, use_dirstate=False, |
852 update_dirstate=False) |
854 update_dirstate=False) |
853 finally: |
855 finally: |
854 del lock, wlock |
856 release(lock, wlock) |
855 |
857 |
856 def _commitctx(self, wctx, force=False, force_editor=False, empty_ok=False, |
858 def _commitctx(self, wctx, force=False, force_editor=False, empty_ok=False, |
857 use_dirstate=True, update_dirstate=True): |
859 use_dirstate=True, update_dirstate=True): |
858 tr = None |
860 tr = None |
859 valid = 0 # don't save the dirstate if this isn't set |
861 valid = 0 # don't save the dirstate if this isn't set |
1136 self.dirstate.normallookup(f) |
1138 self.dirstate.normallookup(f) |
1137 else: |
1139 else: |
1138 self.dirstate.add(f) |
1140 self.dirstate.add(f) |
1139 return rejected |
1141 return rejected |
1140 finally: |
1142 finally: |
1141 del wlock |
1143 wlock.release() |
1142 |
1144 |
1143 def forget(self, list): |
1145 def forget(self, list): |
1144 wlock = self.wlock() |
1146 wlock = self.wlock() |
1145 try: |
1147 try: |
1146 for f in list: |
1148 for f in list: |
1147 if self.dirstate[f] != 'a': |
1149 if self.dirstate[f] != 'a': |
1148 self.ui.warn(_("%s not added!\n") % f) |
1150 self.ui.warn(_("%s not added!\n") % f) |
1149 else: |
1151 else: |
1150 self.dirstate.forget(f) |
1152 self.dirstate.forget(f) |
1151 finally: |
1153 finally: |
1152 del wlock |
1154 wlock.release() |
1153 |
1155 |
1154 def remove(self, list, unlink=False): |
1156 def remove(self, list, unlink=False): |
1155 wlock = None |
1157 wlock = None |
1156 try: |
1158 try: |
1157 if unlink: |
1159 if unlink: |
1170 elif f not in self.dirstate: |
1172 elif f not in self.dirstate: |
1171 self.ui.warn(_("%s not tracked!\n") % f) |
1173 self.ui.warn(_("%s not tracked!\n") % f) |
1172 else: |
1174 else: |
1173 self.dirstate.remove(f) |
1175 self.dirstate.remove(f) |
1174 finally: |
1176 finally: |
1175 del wlock |
1177 release(wlock) |
1176 |
1178 |
1177 def undelete(self, list): |
1179 def undelete(self, list): |
1178 wlock = None |
1180 manifests = [self.manifest.read(self.changelog.read(p)[0]) |
1179 try: |
1181 for p in self.dirstate.parents() if p != nullid] |
1180 manifests = [self.manifest.read(self.changelog.read(p)[0]) |
1182 wlock = self.wlock() |
1181 for p in self.dirstate.parents() if p != nullid] |
1183 try: |
1182 wlock = self.wlock() |
|
1183 for f in list: |
1184 for f in list: |
1184 if self.dirstate[f] != 'r': |
1185 if self.dirstate[f] != 'r': |
1185 self.ui.warn(_("%s not removed!\n") % f) |
1186 self.ui.warn(_("%s not removed!\n") % f) |
1186 else: |
1187 else: |
1187 m = f in manifests[0] and manifests[0] or manifests[1] |
1188 m = f in manifests[0] and manifests[0] or manifests[1] |
1188 t = self.file(f).read(m[f]) |
1189 t = self.file(f).read(m[f]) |
1189 self.wwrite(f, t, m.flags(f)) |
1190 self.wwrite(f, t, m.flags(f)) |
1190 self.dirstate.normal(f) |
1191 self.dirstate.normal(f) |
1191 finally: |
1192 finally: |
1192 del wlock |
1193 wlock.release() |
1193 |
1194 |
1194 def copy(self, source, dest): |
1195 def copy(self, source, dest): |
1195 wlock = None |
1196 p = self.wjoin(dest) |
1196 try: |
1197 if not (os.path.exists(p) or os.path.islink(p)): |
1197 p = self.wjoin(dest) |
1198 self.ui.warn(_("%s does not exist!\n") % dest) |
1198 if not (os.path.exists(p) or os.path.islink(p)): |
1199 elif not (os.path.isfile(p) or os.path.islink(p)): |
1199 self.ui.warn(_("%s does not exist!\n") % dest) |
1200 self.ui.warn(_("copy failed: %s is not a file or a " |
1200 elif not (os.path.isfile(p) or os.path.islink(p)): |
1201 "symbolic link\n") % dest) |
1201 self.ui.warn(_("copy failed: %s is not a file or a " |
1202 else: |
1202 "symbolic link\n") % dest) |
1203 wlock = self.wlock() |
1203 else: |
1204 try: |
1204 wlock = self.wlock() |
|
1205 if self.dirstate[dest] in '?r': |
1205 if self.dirstate[dest] in '?r': |
1206 self.dirstate.add(dest) |
1206 self.dirstate.add(dest) |
1207 self.dirstate.copy(source, dest) |
1207 self.dirstate.copy(source, dest) |
1208 finally: |
1208 finally: |
1209 del wlock |
1209 wlock.release() |
1210 |
1210 |
1211 def heads(self, start=None, closed=True): |
1211 def heads(self, start=None, closed=True): |
1212 heads = self.changelog.heads(start) |
1212 heads = self.changelog.heads(start) |
1213 def display(head): |
1213 def display(head): |
1214 if closed: |
1214 if closed: |
1498 if not remote.capable('changegroupsubset'): |
1498 if not remote.capable('changegroupsubset'): |
1499 raise util.Abort(_("Partial pull cannot be done because other repository doesn't support changegroupsubset.")) |
1499 raise util.Abort(_("Partial pull cannot be done because other repository doesn't support changegroupsubset.")) |
1500 cg = remote.changegroupsubset(fetch, heads, 'pull') |
1500 cg = remote.changegroupsubset(fetch, heads, 'pull') |
1501 return self.addchangegroup(cg, 'pull', remote.url()) |
1501 return self.addchangegroup(cg, 'pull', remote.url()) |
1502 finally: |
1502 finally: |
1503 del lock |
1503 lock.release() |
1504 |
1504 |
1505 def push(self, remote, force=False, revs=None): |
1505 def push(self, remote, force=False, revs=None): |
1506 # there are two ways to push to remote repo: |
1506 # there are two ways to push to remote repo: |
1507 # |
1507 # |
1508 # addchangegroup assumes local user can lock remote |
1508 # addchangegroup assumes local user can lock remote |
1579 if ret[0] is not None: |
1579 if ret[0] is not None: |
1580 cg, remote_heads = ret |
1580 cg, remote_heads = ret |
1581 return remote.addchangegroup(cg, 'push', self.url()) |
1581 return remote.addchangegroup(cg, 'push', self.url()) |
1582 return ret[1] |
1582 return ret[1] |
1583 finally: |
1583 finally: |
1584 del lock |
1584 lock.release() |
1585 |
1585 |
1586 def push_unbundle(self, remote, force, revs): |
1586 def push_unbundle(self, remote, force, revs): |
1587 # local repo finds heads on server, finds out what revs it |
1587 # local repo finds heads on server, finds out what revs it |
1588 # must push. once revs transferred, if server finds it has |
1588 # must push. once revs transferred, if server finds it has |
1589 # different heads (someone else won commit/push race), server |
1589 # different heads (someone else won commit/push race), server |