413 _('file %r in dirstate clashes with %r') % (d, f)) |
413 _('file %r in dirstate clashes with %r') % (d, f)) |
414 if oldstate in "?r" and "dirs" in self._map.__dict__: |
414 if oldstate in "?r" and "dirs" in self._map.__dict__: |
415 self._map.dirs.addpath(f) |
415 self._map.dirs.addpath(f) |
416 self._dirty = True |
416 self._dirty = True |
417 self._updatedfiles.add(f) |
417 self._updatedfiles.add(f) |
418 if state != 'n' or mtime == -1: |
|
419 self._map.nonnormalset.add(f) |
|
420 if size == -2: |
|
421 self._map.otherparentset.add(f) |
|
422 self._map.addfile(f, state, mode, size, mtime) |
418 self._map.addfile(f, state, mode, size, mtime) |
423 |
419 |
424 def normal(self, f): |
420 def normal(self, f): |
425 '''Mark a file normal and clean.''' |
421 '''Mark a file normal and clean.''' |
426 s = os.lstat(self._join(f)) |
422 s = os.lstat(self._join(f)) |
488 if entry[0] == 'm': # merge |
484 if entry[0] == 'm': # merge |
489 size = -1 |
485 size = -1 |
490 elif entry[0] == 'n' and entry[2] == -2: # other parent |
486 elif entry[0] == 'n' and entry[2] == -2: # other parent |
491 size = -2 |
487 size = -2 |
492 self._map.otherparentset.add(f) |
488 self._map.otherparentset.add(f) |
493 self._map.nonnormalset.add(f) |
|
494 self._map.removefile(f, size) |
489 self._map.removefile(f, size) |
495 if size == 0: |
490 if size == 0: |
496 self._map.copymap.pop(f, None) |
491 self._map.copymap.pop(f, None) |
497 |
492 |
498 def merge(self, f): |
493 def merge(self, f): |
504 def drop(self, f): |
499 def drop(self, f): |
505 '''Drop a file from the dirstate''' |
500 '''Drop a file from the dirstate''' |
506 if self._map.dropfile(f): |
501 if self._map.dropfile(f): |
507 self._dirty = True |
502 self._dirty = True |
508 self._droppath(f) |
503 self._droppath(f) |
509 if f in self._map.nonnormalset: |
|
510 self._map.nonnormalset.remove(f) |
|
511 self._map.copymap.pop(f, None) |
504 self._map.copymap.pop(f, None) |
512 |
505 |
513 def _discoverpath(self, path, normed, ignoremissing, exists, storemap): |
506 def _discoverpath(self, path, normed, ignoremissing, exists, storemap): |
514 if exists is None: |
507 if exists is None: |
515 exists = os.path.lexists(os.path.join(self._root, path)) |
508 exists = os.path.lexists(os.path.join(self._root, path)) |
629 # See also the wiki page below for detail: |
622 # See also the wiki page below for detail: |
630 # https://www.mercurial-scm.org/wiki/DirstateTransactionPlan |
623 # https://www.mercurial-scm.org/wiki/DirstateTransactionPlan |
631 |
624 |
632 # emulate dropping timestamp in 'parsers.pack_dirstate' |
625 # emulate dropping timestamp in 'parsers.pack_dirstate' |
633 now = _getfsnow(self._opener) |
626 now = _getfsnow(self._opener) |
634 dmap = self._map |
627 self._map.clearambiguoustimes(self._updatedfiles, now) |
635 for f in self._updatedfiles: |
|
636 e = dmap.get(f) |
|
637 if e is not None and e[0] == 'n' and e[3] == now: |
|
638 dmap.addfile(f, e[0], e[1], e[2], -1) |
|
639 self._map.nonnormalset.add(f) |
|
640 |
628 |
641 # emulate that all 'dirstate.normal' results are written out |
629 # emulate that all 'dirstate.normal' results are written out |
642 self._lastnormaltime = 0 |
630 self._lastnormaltime = 0 |
643 self._updatedfiles.clear() |
631 self._updatedfiles.clear() |
644 |
632 |
1227 form that they appear as in the dirstate. |
1215 form that they appear as in the dirstate. |
1228 |
1216 |
1229 - `dirfoldmap` is a dict mapping normalized directory names to the |
1217 - `dirfoldmap` is a dict mapping normalized directory names to the |
1230 denormalized form that they appear as in the dirstate. |
1218 denormalized form that they appear as in the dirstate. |
1231 |
1219 |
1232 Once instantiated, the nonnormalset, otherparentset, dirs, filefoldmap and |
1220 Once instantiated, the dirs, filefoldmap and dirfoldmap views must be |
1233 dirfoldmap views must be maintained by the caller. |
1221 maintained by the caller. |
1234 """ |
1222 """ |
1235 |
1223 |
1236 def __init__(self, ui, opener, root): |
1224 def __init__(self, ui, opener, root): |
1237 self._ui = ui |
1225 self._ui = ui |
1238 self._opener = opener |
1226 self._opener = opener |
1293 self._map |
1281 self._map |
1294 |
1282 |
1295 def addfile(self, f, state, mode, size, mtime): |
1283 def addfile(self, f, state, mode, size, mtime): |
1296 """Add a tracked file to the dirstate.""" |
1284 """Add a tracked file to the dirstate.""" |
1297 self._map[f] = dirstatetuple(state, mode, size, mtime) |
1285 self._map[f] = dirstatetuple(state, mode, size, mtime) |
|
1286 if state != 'n' or mtime == -1: |
|
1287 self.nonnormalset.add(f) |
|
1288 if size == -2: |
|
1289 self.otherparentset.add(f) |
1298 |
1290 |
1299 def removefile(self, f, size): |
1291 def removefile(self, f, size): |
1300 """ |
1292 """ |
1301 Mark a file as removed in the dirstate. |
1293 Mark a file as removed in the dirstate. |
1302 |
1294 |
1303 The `size` parameter is used to store sentinel values that indicate |
1295 The `size` parameter is used to store sentinel values that indicate |
1304 the file's previous state. In the future, we should refactor this |
1296 the file's previous state. In the future, we should refactor this |
1305 to be more explicit about what that state is. |
1297 to be more explicit about what that state is. |
1306 """ |
1298 """ |
1307 self._map[f] = dirstatetuple('r', 0, size, 0) |
1299 self._map[f] = dirstatetuple('r', 0, size, 0) |
|
1300 self.nonnormalset.add(f) |
1308 |
1301 |
1309 def dropfile(self, f): |
1302 def dropfile(self, f): |
1310 """ |
1303 """ |
1311 Remove a file from the dirstate. Returns True if the file was |
1304 Remove a file from the dirstate. Returns True if the file was |
1312 previously recorded. |
1305 previously recorded. |
1313 """ |
1306 """ |
1314 return self._map.pop(f, None) is not None |
1307 exists = self._map.pop(f, None) is not None |
|
1308 self.nonnormalset.discard(f) |
|
1309 return exists |
|
1310 |
|
1311 def clearambiguoustimes(self, files, now): |
|
1312 for f in files: |
|
1313 e = self.get(f) |
|
1314 if e is not None and e[0] == 'n' and e[3] == now: |
|
1315 self._map[f] = dirstatetuple(e[0], e[1], e[2], -1) |
|
1316 self.nonnormalset.add(f) |
1315 |
1317 |
1316 def nonnormalentries(self): |
1318 def nonnormalentries(self): |
1317 '''Compute the nonnormal dirstate entries from the dmap''' |
1319 '''Compute the nonnormal dirstate entries from the dmap''' |
1318 try: |
1320 try: |
1319 return parsers.nonnormalotherparententries(self._map) |
1321 return parsers.nonnormalotherparententries(self._map) |