138 added.append(fn) |
133 added.append(fn) |
139 elif node2 is None: |
134 elif node2 is None: |
140 removed.append(fn) |
135 removed.append(fn) |
141 elif flag1 != flag2: |
136 elif flag1 != flag2: |
142 modified.append(fn) |
137 modified.append(fn) |
143 elif node2 not in wdirfilenodeids: |
138 elif node2 not in self._repo.nodeconstants.wdirfilenodeids: |
144 # When comparing files between two commits, we save time by |
139 # When comparing files between two commits, we save time by |
145 # not comparing the file contents when the nodeids differ. |
140 # not comparing the file contents when the nodeids differ. |
146 # Note that this means we incorrectly report a reverted change |
141 # Note that this means we incorrectly report a reverted change |
147 # to a file as a modification. |
142 # to a file as a modification. |
148 modified.append(fn) |
143 modified.append(fn) |
735 n2 = c2._node |
730 n2 = c2._node |
736 if n2 is None: |
731 if n2 is None: |
737 n2 = c2._parents[0]._node |
732 n2 = c2._parents[0]._node |
738 cahs = self._repo.changelog.commonancestorsheads(self._node, n2) |
733 cahs = self._repo.changelog.commonancestorsheads(self._node, n2) |
739 if not cahs: |
734 if not cahs: |
740 anc = nullid |
735 anc = self._repo.nodeconstants.nullid |
741 elif len(cahs) == 1: |
736 elif len(cahs) == 1: |
742 anc = cahs[0] |
737 anc = cahs[0] |
743 else: |
738 else: |
744 # experimental config: merge.preferancestor |
739 # experimental config: merge.preferancestor |
745 for r in self._repo.ui.configlist(b'merge', b'preferancestor'): |
740 for r in self._repo.ui.configlist(b'merge', b'preferancestor'): |
1130 |
1125 |
1131 def parents(self): |
1126 def parents(self): |
1132 _path = self._path |
1127 _path = self._path |
1133 fl = self._filelog |
1128 fl = self._filelog |
1134 parents = self._filelog.parents(self._filenode) |
1129 parents = self._filelog.parents(self._filenode) |
1135 pl = [(_path, node, fl) for node in parents if node != nullid] |
1130 pl = [ |
|
1131 (_path, node, fl) |
|
1132 for node in parents |
|
1133 if node != self._repo.nodeconstants.nullid |
|
1134 ] |
1136 |
1135 |
1137 r = fl.renamed(self._filenode) |
1136 r = fl.renamed(self._filenode) |
1138 if r: |
1137 if r: |
1139 # - In the simple rename case, both parent are nullid, pl is empty. |
1138 # - In the simple rename case, both parent are nullid, pl is empty. |
1140 # - In case of merge, only one of the parent is null id and should |
1139 # - In case of merge, only one of the parent is null id and should |
1554 |
1553 |
1555 def __contains__(self, key): |
1554 def __contains__(self, key): |
1556 return self._repo.dirstate[key] not in b"?r" |
1555 return self._repo.dirstate[key] not in b"?r" |
1557 |
1556 |
1558 def hex(self): |
1557 def hex(self): |
1559 return wdirhex |
1558 return self._repo.nodeconstants.wdirhex |
1560 |
1559 |
1561 @propertycache |
1560 @propertycache |
1562 def _parents(self): |
1561 def _parents(self): |
1563 p = self._repo.dirstate.parents() |
1562 p = self._repo.dirstate.parents() |
1564 if p[1] == nullid: |
1563 if p[1] == self._repo.nodeconstants.nullid: |
1565 p = p[:-1] |
1564 p = p[:-1] |
1566 # use unfiltered repo to delay/avoid loading obsmarkers |
1565 # use unfiltered repo to delay/avoid loading obsmarkers |
1567 unfi = self._repo.unfiltered() |
1566 unfi = self._repo.unfiltered() |
1568 return [ |
1567 return [ |
1569 changectx( |
1568 changectx( |
1570 self._repo, unfi.changelog.rev(n), n, maybe_filtered=False |
1569 self._repo, unfi.changelog.rev(n), n, maybe_filtered=False |
1571 ) |
1570 ) |
1572 for n in p |
1571 for n in p |
1573 ] |
1572 ] |
1574 |
1573 |
1575 def setparents(self, p1node, p2node=nullid): |
1574 def setparents(self, p1node, p2node=None): |
|
1575 if p2node is None: |
|
1576 p2node = self._repo.nodeconstants.nullid |
1576 dirstate = self._repo.dirstate |
1577 dirstate = self._repo.dirstate |
1577 with dirstate.parentchange(): |
1578 with dirstate.parentchange(): |
1578 copies = dirstate.setparents(p1node, p2node) |
1579 copies = dirstate.setparents(p1node, p2node) |
1579 pctx = self._repo[p1node] |
1580 pctx = self._repo[p1node] |
1580 if copies: |
1581 if copies: |
1582 # requires access to parents manifests. Preserve them |
1583 # requires access to parents manifests. Preserve them |
1583 # only for entries added to first parent. |
1584 # only for entries added to first parent. |
1584 for f in copies: |
1585 for f in copies: |
1585 if f not in pctx and copies[f] in pctx: |
1586 if f not in pctx and copies[f] in pctx: |
1586 dirstate.copy(copies[f], f) |
1587 dirstate.copy(copies[f], f) |
1587 if p2node == nullid: |
1588 if p2node == self._repo.nodeconstants.nullid: |
1588 for f, s in sorted(dirstate.copies().items()): |
1589 for f, s in sorted(dirstate.copies().items()): |
1589 if f not in pctx and s not in pctx: |
1590 if f not in pctx and s not in pctx: |
1590 dirstate.copy(None, f) |
1591 dirstate.copy(None, f) |
1591 |
1592 |
1592 def _fileinfo(self, path): |
1593 def _fileinfo(self, path): |
1942 |
1943 |
1943 man = parents[0].manifest().copy() |
1944 man = parents[0].manifest().copy() |
1944 |
1945 |
1945 ff = self._flagfunc |
1946 ff = self._flagfunc |
1946 for i, l in ( |
1947 for i, l in ( |
1947 (addednodeid, status.added), |
1948 (self._repo.nodeconstants.addednodeid, status.added), |
1948 (modifiednodeid, status.modified), |
1949 (self._repo.nodeconstants.modifiednodeid, status.modified), |
1949 ): |
1950 ): |
1950 for f in l: |
1951 for f in l: |
1951 man[f] = i |
1952 man[f] = i |
1952 try: |
1953 try: |
1953 man.setflag(f, ff(f)) |
1954 man.setflag(f, ff(f)) |
2068 |
2069 |
2069 def renamed(self): |
2070 def renamed(self): |
2070 path = self.copysource() |
2071 path = self.copysource() |
2071 if not path: |
2072 if not path: |
2072 return None |
2073 return None |
2073 return path, self._changectx._parents[0]._manifest.get(path, nullid) |
2074 return ( |
|
2075 path, |
|
2076 self._changectx._parents[0]._manifest.get( |
|
2077 path, self._repo.nodeconstants.nullid |
|
2078 ), |
|
2079 ) |
2074 |
2080 |
2075 def parents(self): |
2081 def parents(self): |
2076 '''return parent filectxs, following copies if necessary''' |
2082 '''return parent filectxs, following copies if necessary''' |
2077 |
2083 |
2078 def filenode(ctx, path): |
2084 def filenode(ctx, path): |
2079 return ctx._manifest.get(path, nullid) |
2085 return ctx._manifest.get(path, self._repo.nodeconstants.nullid) |
2080 |
2086 |
2081 path = self._path |
2087 path = self._path |
2082 fl = self._filelog |
2088 fl = self._filelog |
2083 pcl = self._changectx._parents |
2089 pcl = self._changectx._parents |
2084 renamed = self.renamed() |
2090 renamed = self.renamed() |
2220 # Drop old manifest cache as it is now out of date. |
2226 # Drop old manifest cache as it is now out of date. |
2221 # This is necessary when, e.g., rebasing several nodes with one |
2227 # This is necessary when, e.g., rebasing several nodes with one |
2222 # ``overlayworkingctx`` (e.g. with --collapse). |
2228 # ``overlayworkingctx`` (e.g. with --collapse). |
2223 util.clearcachedproperty(self, b'_manifest') |
2229 util.clearcachedproperty(self, b'_manifest') |
2224 |
2230 |
2225 def setparents(self, p1node, p2node=nullid): |
2231 def setparents(self, p1node, p2node=None): |
|
2232 if p2node is None: |
|
2233 p2node = self._repo.nodeconstants.nullid |
2226 assert p1node == self._wrappedctx.node() |
2234 assert p1node == self._wrappedctx.node() |
2227 self._parents = [self._wrappedctx, self._repo.unfiltered()[p2node]] |
2235 self._parents = [self._wrappedctx, self._repo.unfiltered()[p2node]] |
2228 |
2236 |
2229 def data(self, path): |
2237 def data(self, path): |
2230 if self.isdirty(path): |
2238 if self.isdirty(path): |
2246 parents = self.parents() |
2254 parents = self.parents() |
2247 man = parents[0].manifest().copy() |
2255 man = parents[0].manifest().copy() |
2248 |
2256 |
2249 flag = self._flagfunc |
2257 flag = self._flagfunc |
2250 for path in self.added(): |
2258 for path in self.added(): |
2251 man[path] = addednodeid |
2259 man[path] = self._repo.nodeconstants.addednodeid |
2252 man.setflag(path, flag(path)) |
2260 man.setflag(path, flag(path)) |
2253 for path in self.modified(): |
2261 for path in self.modified(): |
2254 man[path] = modifiednodeid |
2262 man[path] = self._repo.nodeconstants.modifiednodeid |
2255 man.setflag(path, flag(path)) |
2263 man.setflag(path, flag(path)) |
2256 for path in self.removed(): |
2264 for path in self.removed(): |
2257 del man[path] |
2265 del man[path] |
2258 return man |
2266 return man |
2259 |
2267 |
2825 super(memctx, self).__init__( |
2833 super(memctx, self).__init__( |
2826 repo, text, user, date, extra, branch=branch |
2834 repo, text, user, date, extra, branch=branch |
2827 ) |
2835 ) |
2828 self._rev = None |
2836 self._rev = None |
2829 self._node = None |
2837 self._node = None |
2830 parents = [(p or nullid) for p in parents] |
2838 parents = [(p or self._repo.nodeconstants.nullid) for p in parents] |
2831 p1, p2 = parents |
2839 p1, p2 = parents |
2832 self._parents = [self._repo[p] for p in (p1, p2)] |
2840 self._parents = [self._repo[p] for p in (p1, p2)] |
2833 files = sorted(set(files)) |
2841 files = sorted(set(files)) |
2834 self._files = files |
2842 self._files = files |
2835 self.substate = {} |
2843 self.substate = {} |
2864 # keep this simple for now; just worry about p1 |
2872 # keep this simple for now; just worry about p1 |
2865 pctx = self._parents[0] |
2873 pctx = self._parents[0] |
2866 man = pctx.manifest().copy() |
2874 man = pctx.manifest().copy() |
2867 |
2875 |
2868 for f in self._status.modified: |
2876 for f in self._status.modified: |
2869 man[f] = modifiednodeid |
2877 man[f] = self._repo.nodeconstants.modifiednodeid |
2870 |
2878 |
2871 for f in self._status.added: |
2879 for f in self._status.added: |
2872 man[f] = addednodeid |
2880 man[f] = self._repo.nodeconstants.addednodeid |
2873 |
2881 |
2874 for f in self._status.removed: |
2882 for f in self._status.removed: |
2875 if f in man: |
2883 if f in man: |
2876 del man[f] |
2884 del man[f] |
2877 |
2885 |
3004 p1, p2 = self._parents = parents |
3012 p1, p2 = self._parents = parents |
3005 |
3013 |
3006 # sanity check to ensure that the reused manifest parents are |
3014 # sanity check to ensure that the reused manifest parents are |
3007 # manifests of our commit parents |
3015 # manifests of our commit parents |
3008 mp1, mp2 = self.manifestctx().parents |
3016 mp1, mp2 = self.manifestctx().parents |
3009 if p1 != nullid and p1.manifestnode() != mp1: |
3017 if p1 != self._repo.nodeconstants.nullid and p1.manifestnode() != mp1: |
3010 raise RuntimeError( |
3018 raise RuntimeError( |
3011 r"can't reuse the manifest: its p1 " |
3019 r"can't reuse the manifest: its p1 " |
3012 r"doesn't match the new ctx p1" |
3020 r"doesn't match the new ctx p1" |
3013 ) |
3021 ) |
3014 if p2 != nullid and p2.manifestnode() != mp2: |
3022 if p2 != self._repo.nodeconstants.nullid and p2.manifestnode() != mp2: |
3015 raise RuntimeError( |
3023 raise RuntimeError( |
3016 r"can't reuse the manifest: " |
3024 r"can't reuse the manifest: " |
3017 r"its p2 doesn't match the new ctx p2" |
3025 r"its p2 doesn't match the new ctx p2" |
3018 ) |
3026 ) |
3019 |
3027 |