Show More
@@ -1613,18 +1613,30 b' class workingctx(committablectx):' | |||||
1613 | def _checklookup(self, files): |
|
1613 | def _checklookup(self, files): | |
1614 | # check for any possibly clean files |
|
1614 | # check for any possibly clean files | |
1615 | if not files: |
|
1615 | if not files: | |
1616 | return [], [] |
|
1616 | return [], [], [] | |
1617 |
|
1617 | |||
1618 | modified = [] |
|
1618 | modified = [] | |
|
1619 | deleted = [] | |||
1619 | fixup = [] |
|
1620 | fixup = [] | |
1620 | pctx = self._parents[0] |
|
1621 | pctx = self._parents[0] | |
1621 | # do a full compare of any files that might have changed |
|
1622 | # do a full compare of any files that might have changed | |
1622 | for f in sorted(files): |
|
1623 | for f in sorted(files): | |
1623 | if (f not in pctx or self.flags(f) != pctx.flags(f) |
|
1624 | try: | |
1624 | or pctx[f].cmp(self[f])): |
|
1625 | # This will return True for a file that got replaced by a | |
1625 | modified.append(f) |
|
1626 | # directory in the interim, but fixing that is pretty hard. | |
1626 | else: |
|
1627 | if (f not in pctx or self.flags(f) != pctx.flags(f) | |
1627 | fixup.append(f) |
|
1628 | or pctx[f].cmp(self[f])): | |
|
1629 | modified.append(f) | |||
|
1630 | else: | |||
|
1631 | fixup.append(f) | |||
|
1632 | except (IOError, OSError): | |||
|
1633 | # A file become inaccessible in between? Mark it as deleted, | |||
|
1634 | # matching dirstate behavior (issue5584). | |||
|
1635 | # The dirstate has more complex behavior around whether a | |||
|
1636 | # missing file matches a directory, etc, but we don't need to | |||
|
1637 | # bother with that: if f has made it to this point, we're sure | |||
|
1638 | # it's in the dirstate. | |||
|
1639 | deleted.append(f) | |||
1628 |
|
1640 | |||
1629 | # update dirstate for files that are actually clean |
|
1641 | # update dirstate for files that are actually clean | |
1630 | if fixup: |
|
1642 | if fixup: | |
@@ -1644,7 +1656,7 b' class workingctx(committablectx):' | |||||
1644 | self._repo.dirstate.write(self._repo.currenttransaction()) |
|
1656 | self._repo.dirstate.write(self._repo.currenttransaction()) | |
1645 | except error.LockError: |
|
1657 | except error.LockError: | |
1646 | pass |
|
1658 | pass | |
1647 | return modified, fixup |
|
1659 | return modified, deleted, fixup | |
1648 |
|
1660 | |||
1649 | def _dirstatestatus(self, match=None, ignored=False, clean=False, |
|
1661 | def _dirstatestatus(self, match=None, ignored=False, clean=False, | |
1650 | unknown=False): |
|
1662 | unknown=False): | |
@@ -1659,8 +1671,9 b' class workingctx(committablectx):' | |||||
1659 |
|
1671 | |||
1660 | # check for any possibly clean files |
|
1672 | # check for any possibly clean files | |
1661 | if cmp: |
|
1673 | if cmp: | |
1662 | modified2, fixup = self._checklookup(cmp) |
|
1674 | modified2, deleted2, fixup = self._checklookup(cmp) | |
1663 | s.modified.extend(modified2) |
|
1675 | s.modified.extend(modified2) | |
|
1676 | s.deleted.extend(deleted2) | |||
1664 |
|
1677 | |||
1665 | # update dirstate for files that are actually clean |
|
1678 | # update dirstate for files that are actually clean | |
1666 | if fixup and listclean: |
|
1679 | if fixup and listclean: |
@@ -1,4 +1,5 b'' | |||||
1 | $ hg init |
|
1 | $ hg init repo | |
|
2 | $ cd repo | |||
2 | $ echo a > a |
|
3 | $ echo a > a | |
3 | $ hg add a |
|
4 | $ hg add a | |
4 | $ hg commit -m test |
|
5 | $ hg commit -m test | |
@@ -31,3 +32,62 b' Do we ever miss a sub-second change?:' | |||||
31 | M a |
|
32 | M a | |
32 | M a |
|
33 | M a | |
33 |
|
34 | |||
|
35 | $ echo test > b | |||
|
36 | $ mkdir dir1 | |||
|
37 | $ echo test > dir1/c | |||
|
38 | $ echo test > d | |||
|
39 | ||||
|
40 | $ echo test > e | |||
|
41 | #if execbit | |||
|
42 | A directory will typically have the execute bit -- make sure it doesn't get | |||
|
43 | confused with a file with the exec bit set | |||
|
44 | $ chmod +x e | |||
|
45 | #endif | |||
|
46 | ||||
|
47 | $ hg add b dir1 d e | |||
|
48 | adding dir1/c | |||
|
49 | $ hg commit -m test2 | |||
|
50 | ||||
|
51 | $ cat >> $TESTTMP/dirstaterace.py << EOF | |||
|
52 | > from mercurial import ( | |||
|
53 | > context, | |||
|
54 | > extensions, | |||
|
55 | > ) | |||
|
56 | > def extsetup(): | |||
|
57 | > extensions.wrapfunction(context.workingctx, '_checklookup', overridechecklookup) | |||
|
58 | > def overridechecklookup(orig, self, files): | |||
|
59 | > # make an update that changes the dirstate from underneath | |||
|
60 | > self._repo.ui.system(self._repo.ui.config('dirstaterace', 'command'), cwd=self._repo.root) | |||
|
61 | > return orig(self, files) | |||
|
62 | > EOF | |||
|
63 | ||||
|
64 | $ hg debugrebuilddirstate | |||
|
65 | $ hg debugdirstate | |||
|
66 | n 0 -1 unset a | |||
|
67 | n 0 -1 unset b | |||
|
68 | n 0 -1 unset d | |||
|
69 | n 0 -1 unset dir1/c | |||
|
70 | n 0 -1 unset e | |||
|
71 | ||||
|
72 | XXX Note that this returns M for files that got replaced by directories. This is | |||
|
73 | definitely a bug, but the fix for that is hard and the next status run is fine | |||
|
74 | anyway. | |||
|
75 | ||||
|
76 | $ hg status --config extensions.dirstaterace=$TESTTMP/dirstaterace.py \ | |||
|
77 | > --config dirstaterace.command='rm b && rm -r dir1 && rm d && mkdir d && rm e && mkdir e' | |||
|
78 | M d | |||
|
79 | M e | |||
|
80 | ! b | |||
|
81 | ! dir1/c | |||
|
82 | $ hg debugdirstate | |||
|
83 | n 644 2 * a (glob) | |||
|
84 | n 0 -1 unset b | |||
|
85 | n 0 -1 unset d | |||
|
86 | n 0 -1 unset dir1/c | |||
|
87 | n 0 -1 unset e | |||
|
88 | ||||
|
89 | $ hg status | |||
|
90 | ! b | |||
|
91 | ! d | |||
|
92 | ! dir1/c | |||
|
93 | ! e |
General Comments 0
You need to be logged in to leave comments.
Login now