mercurial/context.py
changeset 47012 d55b71393907
parent 46843 728d89f6f9b1
child 47191 b338d831d18c
equal deleted inserted replaced
46992:5fa019ceb499 47012:d55b71393907
    12 import os
    12 import os
    13 import stat
    13 import stat
    14 
    14 
    15 from .i18n import _
    15 from .i18n import _
    16 from .node import (
    16 from .node import (
    17     addednodeid,
       
    18     hex,
    17     hex,
    19     modifiednodeid,
       
    20     nullid,
       
    21     nullrev,
    18     nullrev,
    22     short,
    19     short,
    23     wdirfilenodeids,
       
    24     wdirhex,
       
    25 )
    20 )
    26 from .pycompat import (
    21 from .pycompat import (
    27     getattr,
    22     getattr,
    28     open,
    23     open,
    29 )
    24 )
   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()
  2092             pl.append((path, filenode(pc, path), fl))
  2098             pl.append((path, filenode(pc, path), fl))
  2093 
  2099 
  2094         return [
  2100         return [
  2095             self._parentfilectx(p, fileid=n, filelog=l)
  2101             self._parentfilectx(p, fileid=n, filelog=l)
  2096             for p, n, l in pl
  2102             for p, n, l in pl
  2097             if n != nullid
  2103             if n != self._repo.nodeconstants.nullid
  2098         ]
  2104         ]
  2099 
  2105 
  2100     def children(self):
  2106     def children(self):
  2101         return []
  2107         return []
  2102 
  2108 
  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