mercurial/dirstate.py
changeset 47482 cb29484eaade
parent 47481 612f5f36fcf6
child 47483 4ac418b4a6af
equal deleted inserted replaced
47481:612f5f36fcf6 47482:cb29484eaade
    44 propertycache = util.propertycache
    44 propertycache = util.propertycache
    45 filecache = scmutil.filecache
    45 filecache = scmutil.filecache
    46 _rangemask = 0x7FFFFFFF
    46 _rangemask = 0x7FFFFFFF
    47 
    47 
    48 dirstatetuple = parsers.dirstatetuple
    48 dirstatetuple = parsers.dirstatetuple
       
    49 
       
    50 
       
    51 # a special value used internally for `size` if the file come from the other parent
       
    52 FROM_P2 = -2
    49 
    53 
    50 
    54 
    51 class repocache(filecache):
    55 class repocache(filecache):
    52     """filecache for files in .hg/"""
    56     """filecache for files in .hg/"""
    53 
    57 
   369                     source = self._map.copymap.get(f)
   373                     source = self._map.copymap.get(f)
   370                     if source:
   374                     if source:
   371                         copies[f] = source
   375                         copies[f] = source
   372                     self.normallookup(f)
   376                     self.normallookup(f)
   373                 # Also fix up otherparent markers
   377                 # Also fix up otherparent markers
   374                 elif s[0] == b'n' and s[2] == -2:
   378                 elif s[0] == b'n' and s[2] == FROM_P2:
   375                     source = self._map.copymap.get(f)
   379                     source = self._map.copymap.get(f)
   376                     if source:
   380                     if source:
   377                         copies[f] = source
   381                         copies[f] = source
   378                     self.add(f)
   382                     self.add(f)
   379         return copies
   383         return copies
   482             # if there is a merge going on and the file was either
   486             # if there is a merge going on and the file was either
   483             # in state 'm' (-1) or coming from other parent (-2) before
   487             # in state 'm' (-1) or coming from other parent (-2) before
   484             # being removed, restore that state.
   488             # being removed, restore that state.
   485             entry = self._map.get(f)
   489             entry = self._map.get(f)
   486             if entry is not None:
   490             if entry is not None:
   487                 if entry[0] == b'r' and entry[2] in (-1, -2):
   491                 if entry[0] == b'r' and entry[2] in (-1, FROM_P2):
   488                     source = self._map.copymap.get(f)
   492                     source = self._map.copymap.get(f)
   489                     if entry[2] == -1:
   493                     if entry[2] == -1:
   490                         self.merge(f)
   494                         self.merge(f)
   491                     elif entry[2] == -2:
   495                     elif entry[2] == FROM_P2:
   492                         self.otherparent(f)
   496                         self.otherparent(f)
   493                     if source:
   497                     if source:
   494                         self.copy(source, f)
   498                         self.copy(source, f)
   495                     return
   499                     return
   496                 if entry[0] == b'm' or entry[0] == b'n' and entry[2] == -2:
   500                 if entry[0] == b'm' or entry[0] == b'n' and entry[2] == FROM_P2:
   497                     return
   501                     return
   498         self._addpath(f, b'n', 0, -1, -1)
   502         self._addpath(f, b'n', 0, -1, -1)
   499         self._map.copymap.pop(f, None)
   503         self._map.copymap.pop(f, None)
   500 
   504 
   501     def otherparent(self, f):
   505     def otherparent(self, f):
   503         if self._pl[1] == self._nodeconstants.nullid:
   507         if self._pl[1] == self._nodeconstants.nullid:
   504             msg = _(b"setting %r to other parent only allowed in merges") % f
   508             msg = _(b"setting %r to other parent only allowed in merges") % f
   505             raise error.Abort(msg)
   509             raise error.Abort(msg)
   506         if f in self and self[f] == b'n':
   510         if f in self and self[f] == b'n':
   507             # merge-like
   511             # merge-like
   508             self._addpath(f, b'm', 0, -2, -1)
   512             self._addpath(f, b'm', 0, FROM_P2, -1)
   509         else:
   513         else:
   510             # add-like
   514             # add-like
   511             self._addpath(f, b'n', 0, -2, -1)
   515             self._addpath(f, b'n', 0, FROM_P2, -1)
   512         self._map.copymap.pop(f, None)
   516         self._map.copymap.pop(f, None)
   513 
   517 
   514     def add(self, f):
   518     def add(self, f):
   515         '''Mark a file added.'''
   519         '''Mark a file added.'''
   516         self._addpath(f, b'a', 0, -1, -1)
   520         self._addpath(f, b'a', 0, -1, -1)
   525             entry = self._map.get(f)
   529             entry = self._map.get(f)
   526             if entry is not None:
   530             if entry is not None:
   527                 # backup the previous state
   531                 # backup the previous state
   528                 if entry[0] == b'm':  # merge
   532                 if entry[0] == b'm':  # merge
   529                     size = -1
   533                     size = -1
   530                 elif entry[0] == b'n' and entry[2] == -2:  # other parent
   534                 elif entry[0] == b'n' and entry[2] == FROM_P2:  # other parent
   531                     size = -2
   535                     size = FROM_P2
   532                     self._map.otherparentset.add(f)
   536                     self._map.otherparentset.add(f)
   533         self._updatedfiles.add(f)
   537         self._updatedfiles.add(f)
   534         self._map.removefile(f, oldstate, size)
   538         self._map.removefile(f, oldstate, size)
   535         if size == 0:
   539         if size == 0:
   536             self._map.copymap.pop(f, None)
   540             self._map.copymap.pop(f, None)
  1300                     size >= 0
  1304                     size >= 0
  1301                     and (
  1305                     and (
  1302                         (size != st.st_size and size != st.st_size & _rangemask)
  1306                         (size != st.st_size and size != st.st_size & _rangemask)
  1303                         or ((mode ^ st.st_mode) & 0o100 and checkexec)
  1307                         or ((mode ^ st.st_mode) & 0o100 and checkexec)
  1304                     )
  1308                     )
  1305                     or size == -2  # other parent
  1309                     or size == FROM_P2  # other parent
  1306                     or fn in copymap
  1310                     or fn in copymap
  1307                 ):
  1311                 ):
  1308                     if stat.S_ISLNK(st.st_mode) and size != st.st_size:
  1312                     if stat.S_ISLNK(st.st_mode) and size != st.st_size:
  1309                         # issue6456: Size returned may be longer due to
  1313                         # issue6456: Size returned may be longer due to
  1310                         # encryption on EXT-4 fscrypt, undecided.
  1314                         # encryption on EXT-4 fscrypt, undecided.
  1530         if oldstate == b"?" and "_alldirs" in self.__dict__:
  1534         if oldstate == b"?" and "_alldirs" in self.__dict__:
  1531             self._alldirs.addpath(f)
  1535             self._alldirs.addpath(f)
  1532         self._map[f] = dirstatetuple(state, mode, size, mtime)
  1536         self._map[f] = dirstatetuple(state, mode, size, mtime)
  1533         if state != b'n' or mtime == -1:
  1537         if state != b'n' or mtime == -1:
  1534             self.nonnormalset.add(f)
  1538             self.nonnormalset.add(f)
  1535         if size == -2:
  1539         if size == FROM_P2:
  1536             self.otherparentset.add(f)
  1540             self.otherparentset.add(f)
  1537 
  1541 
  1538     def removefile(self, f, oldstate, size):
  1542     def removefile(self, f, oldstate, size):
  1539         """
  1543         """
  1540         Mark a file as removed in the dirstate.
  1544         Mark a file as removed in the dirstate.
  1585             nonnorm = set()
  1589             nonnorm = set()
  1586             otherparent = set()
  1590             otherparent = set()
  1587             for fname, e in pycompat.iteritems(self._map):
  1591             for fname, e in pycompat.iteritems(self._map):
  1588                 if e[0] != b'n' or e[3] == -1:
  1592                 if e[0] != b'n' or e[3] == -1:
  1589                     nonnorm.add(fname)
  1593                     nonnorm.add(fname)
  1590                 if e[0] == b'n' and e[2] == -2:
  1594                 if e[0] == b'n' and e[2] == FROM_P2:
  1591                     otherparent.add(fname)
  1595                     otherparent.add(fname)
  1592             return nonnorm, otherparent
  1596             return nonnorm, otherparent
  1593 
  1597 
  1594     @propertycache
  1598     @propertycache
  1595     def filefoldmap(self):
  1599     def filefoldmap(self):