mercurial/changelog.py
changeset 42442 a1f87294471f
parent 42426 602469a91550
child 42443 027f1567f97f
equal deleted inserted replaced
42441:b9ff059fd194 42442:a1f87294471f
    78         _string_escape('%s:%s' % (k, pycompat.bytestr(d[k])))
    78         _string_escape('%s:%s' % (k, pycompat.bytestr(d[k])))
    79         for k in sorted(d)
    79         for k in sorted(d)
    80     ]
    80     ]
    81     return "\0".join(items)
    81     return "\0".join(items)
    82 
    82 
    83 def encodecopies(copies):
    83 def encodecopies(files, copies):
    84     items = [
    84     items = []
    85         '%s\0%s' % (k, copies[k])
    85     for i, dst in enumerate(files):
    86         for k in sorted(copies)
    86         if dst in copies:
    87     ]
    87             items.append('%d\0%s' % (i, copies[dst]))
       
    88     if len(items) != len(copies):
       
    89         raise error.ProgrammingError('some copy targets missing from file list')
    88     return "\n".join(items)
    90     return "\n".join(items)
    89 
    91 
    90 def decodecopies(data):
    92 def decodecopies(files, data):
    91     try:
    93     try:
    92         copies = {}
    94         copies = {}
    93         for l in data.split('\n'):
    95         for l in data.split('\n'):
    94             k, v = l.split('\0')
    96             strindex, src = l.split('\0')
    95             copies[k] = v
    97             i = int(strindex)
       
    98             dst = files[i]
       
    99             copies[dst] = src
    96         return copies
   100         return copies
    97     except ValueError:
   101     except (ValueError, IndexError):
    98         # Perhaps someone had chosen the same key name (e.g. "p1copies") and
   102         # Perhaps someone had chosen the same key name (e.g. "p1copies") and
    99         # used different syntax for the value.
   103         # used different syntax for the value.
   100         return None
   104         return None
   101 
   105 
   102 def encodefileindices(files, subset):
   106 def encodefileindices(files, subset):
   334         return rawindices and decodefileindices(self.files, rawindices)
   338         return rawindices and decodefileindices(self.files, rawindices)
   335 
   339 
   336     @property
   340     @property
   337     def p1copies(self):
   341     def p1copies(self):
   338         rawcopies = self.extra.get('p1copies')
   342         rawcopies = self.extra.get('p1copies')
   339         return rawcopies and decodecopies(rawcopies)
   343         return rawcopies and decodecopies(self.files, rawcopies)
   340 
   344 
   341     @property
   345     @property
   342     def p2copies(self):
   346     def p2copies(self):
   343         rawcopies = self.extra.get('p2copies')
   347         rawcopies = self.extra.get('p2copies')
   344         return rawcopies and decodecopies(rawcopies)
   348         return rawcopies and decodecopies(self.files, rawcopies)
   345 
   349 
   346     @property
   350     @property
   347     def description(self):
   351     def description(self):
   348         return encoding.tolocal(self._text[self._offsets[3] + 2:])
   352         return encoding.tolocal(self._text[self._offsets[3] + 2:])
   349 
   353 
   629                 raise error.StorageError(_('the name \'%s\' is reserved')
   633                 raise error.StorageError(_('the name \'%s\' is reserved')
   630                                          % branch)
   634                                          % branch)
   631         extrasentries = p1copies, p2copies, filesadded, filesremoved
   635         extrasentries = p1copies, p2copies, filesadded, filesremoved
   632         if extra is None and any(x is not None for x in extrasentries):
   636         if extra is None and any(x is not None for x in extrasentries):
   633             extra = {}
   637             extra = {}
       
   638         sortedfiles = sorted(files)
   634         if p1copies is not None:
   639         if p1copies is not None:
   635             extra['p1copies'] = encodecopies(p1copies)
   640             extra['p1copies'] = encodecopies(sortedfiles, p1copies)
   636         if p2copies is not None:
   641         if p2copies is not None:
   637             extra['p2copies'] = encodecopies(p2copies)
   642             extra['p2copies'] = encodecopies(sortedfiles, p2copies)
   638         sortedfiles = sorted(files)
       
   639         if filesadded is not None:
   643         if filesadded is not None:
   640             extra['filesadded'] = encodefileindices(sortedfiles, filesadded)
   644             extra['filesadded'] = encodefileindices(sortedfiles, filesadded)
   641         if filesremoved is not None:
   645         if filesremoved is not None:
   642             extra['filesremoved'] = encodefileindices(sortedfiles, filesremoved)
   646             extra['filesremoved'] = encodefileindices(sortedfiles, filesremoved)
   643 
   647