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 self._map[f] = dirstatetuple(state, mode, size, mtime) |
|
419 if state != 'n' or mtime == -1: |
418 if state != 'n' or mtime == -1: |
420 self._map.nonnormalset.add(f) |
419 self._map.nonnormalset.add(f) |
421 if size == -2: |
420 if size == -2: |
422 self._map.otherparentset.add(f) |
421 self._map.otherparentset.add(f) |
|
422 self._map.addfile(f, state, mode, size, mtime) |
423 |
423 |
424 def normal(self, f): |
424 def normal(self, f): |
425 '''Mark a file normal and clean.''' |
425 '''Mark a file normal and clean.''' |
426 s = os.lstat(self._join(f)) |
426 s = os.lstat(self._join(f)) |
427 mtime = s.st_mtime |
427 mtime = s.st_mtime |
488 if entry[0] == 'm': # merge |
488 if entry[0] == 'm': # merge |
489 size = -1 |
489 size = -1 |
490 elif entry[0] == 'n' and entry[2] == -2: # other parent |
490 elif entry[0] == 'n' and entry[2] == -2: # other parent |
491 size = -2 |
491 size = -2 |
492 self._map.otherparentset.add(f) |
492 self._map.otherparentset.add(f) |
493 self._map[f] = dirstatetuple('r', 0, size, 0) |
|
494 self._map.nonnormalset.add(f) |
493 self._map.nonnormalset.add(f) |
|
494 self._map.removefile(f, size) |
495 if size == 0: |
495 if size == 0: |
496 self._map.copymap.pop(f, None) |
496 self._map.copymap.pop(f, None) |
497 |
497 |
498 def merge(self, f): |
498 def merge(self, f): |
499 '''Mark a file merged.''' |
499 '''Mark a file merged.''' |
501 return self.normallookup(f) |
501 return self.normallookup(f) |
502 return self.otherparent(f) |
502 return self.otherparent(f) |
503 |
503 |
504 def drop(self, f): |
504 def drop(self, f): |
505 '''Drop a file from the dirstate''' |
505 '''Drop a file from the dirstate''' |
506 if f in self._map: |
506 if self._map.dropfile(f): |
507 self._dirty = True |
507 self._dirty = True |
508 self._droppath(f) |
508 self._droppath(f) |
509 del self._map[f] |
|
510 if f in self._map.nonnormalset: |
509 if f in self._map.nonnormalset: |
511 self._map.nonnormalset.remove(f) |
510 self._map.nonnormalset.remove(f) |
512 self._map.copymap.pop(f, None) |
511 self._map.copymap.pop(f, None) |
513 |
512 |
514 def _discoverpath(self, path, normed, ignoremissing, exists, storemap): |
513 def _discoverpath(self, path, normed, ignoremissing, exists, storemap): |
634 now = _getfsnow(self._opener) |
633 now = _getfsnow(self._opener) |
635 dmap = self._map |
634 dmap = self._map |
636 for f in self._updatedfiles: |
635 for f in self._updatedfiles: |
637 e = dmap.get(f) |
636 e = dmap.get(f) |
638 if e is not None and e[0] == 'n' and e[3] == now: |
637 if e is not None and e[0] == 'n' and e[3] == now: |
639 dmap[f] = dirstatetuple(e[0], e[1], e[2], -1) |
638 dmap.addfile(f, e[0], e[1], e[2], -1) |
640 self._map.nonnormalset.add(f) |
639 self._map.nonnormalset.add(f) |
641 |
640 |
642 # emulate that all 'dirstate.normal' results are written out |
641 # emulate that all 'dirstate.normal' results are written out |
643 self._lastnormaltime = 0 |
642 self._lastnormaltime = 0 |
644 self._updatedfiles.clear() |
643 self._updatedfiles.clear() |
1205 - `parents` is a pair containing the parents of the working copy. The |
1204 - `parents` is a pair containing the parents of the working copy. The |
1206 parents are updated by calling `setparents`. |
1205 parents are updated by calling `setparents`. |
1207 |
1206 |
1208 - the state map maps filenames to tuples of (state, mode, size, mtime), |
1207 - the state map maps filenames to tuples of (state, mode, size, mtime), |
1209 where state is a single character representing 'normal', 'added', |
1208 where state is a single character representing 'normal', 'added', |
1210 'removed', or 'merged'. It is accessed by treating the dirstate as a |
1209 'removed', or 'merged'. It is read by treating the dirstate as a |
1211 dict. |
1210 dict. File state is updated by calling the `addfile`, `removefile` and |
|
1211 `dropfile` methods. |
1212 |
1212 |
1213 - `copymap` maps destination filenames to their source filename. |
1213 - `copymap` maps destination filenames to their source filename. |
1214 |
1214 |
1215 The dirstate also provides the following views onto the state: |
1215 The dirstate also provides the following views onto the state: |
1216 |
1216 |
1280 return self._map.get(key, default) |
1280 return self._map.get(key, default) |
1281 |
1281 |
1282 def __contains__(self, key): |
1282 def __contains__(self, key): |
1283 return key in self._map |
1283 return key in self._map |
1284 |
1284 |
1285 def __setitem__(self, key, value): |
|
1286 self._map[key] = value |
|
1287 |
|
1288 def __getitem__(self, key): |
1285 def __getitem__(self, key): |
1289 return self._map[key] |
1286 return self._map[key] |
1290 |
|
1291 def __delitem__(self, key): |
|
1292 del self._map[key] |
|
1293 |
1287 |
1294 def keys(self): |
1288 def keys(self): |
1295 return self._map.keys() |
1289 return self._map.keys() |
1296 |
1290 |
1297 def preload(self): |
1291 def preload(self): |
1298 """Loads the underlying data, if it's not already loaded""" |
1292 """Loads the underlying data, if it's not already loaded""" |
1299 self._map |
1293 self._map |
|
1294 |
|
1295 def addfile(self, f, state, mode, size, mtime): |
|
1296 """Add a tracked file to the dirstate.""" |
|
1297 self._map[f] = dirstatetuple(state, mode, size, mtime) |
|
1298 |
|
1299 def removefile(self, f, size): |
|
1300 """ |
|
1301 Mark a file as removed in the dirstate. |
|
1302 |
|
1303 The `size` parameter is used to store sentinel values that indicate |
|
1304 the file's previous state. In the future, we should refactor this |
|
1305 to be more explicit about what that state is. |
|
1306 """ |
|
1307 self._map[f] = dirstatetuple('r', 0, size, 0) |
|
1308 |
|
1309 def dropfile(self, f): |
|
1310 """ |
|
1311 Remove a file from the dirstate. Returns True if the file was |
|
1312 previously recorded. |
|
1313 """ |
|
1314 return self._map.pop(f, None) is not None |
1300 |
1315 |
1301 def nonnormalentries(self): |
1316 def nonnormalentries(self): |
1302 '''Compute the nonnormal dirstate entries from the dmap''' |
1317 '''Compute the nonnormal dirstate entries from the dmap''' |
1303 try: |
1318 try: |
1304 return parsers.nonnormalotherparententries(self._map) |
1319 return parsers.nonnormalotherparententries(self._map) |
1425 self.setparents(*p) |
1440 self.setparents(*p) |
1426 |
1441 |
1427 # Avoid excess attribute lookups by fast pathing certain checks |
1442 # Avoid excess attribute lookups by fast pathing certain checks |
1428 self.__contains__ = self._map.__contains__ |
1443 self.__contains__ = self._map.__contains__ |
1429 self.__getitem__ = self._map.__getitem__ |
1444 self.__getitem__ = self._map.__getitem__ |
1430 self.__setitem__ = self._map.__setitem__ |
|
1431 self.__delitem__ = self._map.__delitem__ |
|
1432 self.get = self._map.get |
1445 self.get = self._map.get |
1433 |
1446 |
1434 def write(self, st, now): |
1447 def write(self, st, now): |
1435 st.write(parsers.pack_dirstate(self._map, self.copymap, |
1448 st.write(parsers.pack_dirstate(self._map, self.copymap, |
1436 self.parents(), now)) |
1449 self.parents(), now)) |