Mercurial > public > mercurial-scm > hg
comparison mercurial/merge.py @ 28009:4a25e91fa55d
merge: add state extras merge state data
In future commits we will want to store more data related to each file in the
merge state. This patch adds an optional record for storing a dictionary of
extras for each file.
author | Durham Goode <durham@fb.com> |
---|---|
date | Fri, 05 Feb 2016 10:15:28 -0800 |
parents | 6bce6d925e45 |
children | 8abd9f785030 |
comparison
equal
deleted
inserted
replaced
28008:86c4cbdaffee | 28009:4a25e91fa55d |
---|---|
63 C: a change/delete or delete/change conflict | 63 C: a change/delete or delete/change conflict |
64 D: a file that the external merge driver will merge internally | 64 D: a file that the external merge driver will merge internally |
65 (experimental) | 65 (experimental) |
66 m: the external merge driver defined for this merge plus its run state | 66 m: the external merge driver defined for this merge plus its run state |
67 (experimental) | 67 (experimental) |
68 f: a (filename, dictonary) tuple of optional values for a given file | |
68 X: unsupported mandatory record type (used in tests) | 69 X: unsupported mandatory record type (used in tests) |
69 x: unsupported advisory record type (used in tests) | 70 x: unsupported advisory record type (used in tests) |
70 | 71 |
71 Merge driver run states (experimental): | 72 Merge driver run states (experimental): |
72 u: driver-resolved files unmarked -- needs to be run next time we're about | 73 u: driver-resolved files unmarked -- needs to be run next time we're about |
100 self._repo = repo | 101 self._repo = repo |
101 self._dirty = False | 102 self._dirty = False |
102 | 103 |
103 def reset(self, node=None, other=None): | 104 def reset(self, node=None, other=None): |
104 self._state = {} | 105 self._state = {} |
106 self._stateextras = {} | |
105 self._local = None | 107 self._local = None |
106 self._other = None | 108 self._other = None |
107 for var in ('localctx', 'otherctx'): | 109 for var in ('localctx', 'otherctx'): |
108 if var in vars(self): | 110 if var in vars(self): |
109 delattr(self, var) | 111 delattr(self, var) |
124 | 126 |
125 This function process "record" entry produced by the de-serialization | 127 This function process "record" entry produced by the de-serialization |
126 of on disk file. | 128 of on disk file. |
127 """ | 129 """ |
128 self._state = {} | 130 self._state = {} |
131 self._stateextras = {} | |
129 self._local = None | 132 self._local = None |
130 self._other = None | 133 self._other = None |
131 for var in ('localctx', 'otherctx'): | 134 for var in ('localctx', 'otherctx'): |
132 if var in vars(self): | 135 if var in vars(self): |
133 delattr(self, var) | 136 delattr(self, var) |
150 self._readmergedriver = bits[0] | 153 self._readmergedriver = bits[0] |
151 self._mdstate = mdstate | 154 self._mdstate = mdstate |
152 elif rtype in 'FDC': | 155 elif rtype in 'FDC': |
153 bits = record.split('\0') | 156 bits = record.split('\0') |
154 self._state[bits[0]] = bits[1:] | 157 self._state[bits[0]] = bits[1:] |
158 elif rtype == 'f': | |
159 filename, rawextras = record.split('\0', 1) | |
160 extraparts = rawextras.split('\0') | |
161 extras = {} | |
162 i = 0 | |
163 while i < len(extraparts): | |
164 extras[extraparts[i]] = extraparts[i + 1] | |
165 i += 2 | |
166 | |
167 self._stateextras[filename] = extras | |
155 elif not rtype.islower(): | 168 elif not rtype.islower(): |
156 unsupported.add(rtype) | 169 unsupported.add(rtype) |
157 self._results = {} | 170 self._results = {} |
158 self._dirty = False | 171 self._dirty = False |
159 | 172 |
334 # older versions of Mercurial | 347 # older versions of Mercurial |
335 elif v[1] == nullhex or v[6] == nullhex: | 348 elif v[1] == nullhex or v[6] == nullhex: |
336 records.append(('C', '\0'.join([d] + v))) | 349 records.append(('C', '\0'.join([d] + v))) |
337 else: | 350 else: |
338 records.append(('F', '\0'.join([d] + v))) | 351 records.append(('F', '\0'.join([d] + v))) |
352 for filename, extras in sorted(self._stateextras.iteritems()): | |
353 rawextras = '\0'.join('%s\0%s' % (k, v) for k, v in | |
354 extras.iteritems()) | |
355 records.append(('f', '%s\0%s' % (filename, rawextras))) | |
339 return records | 356 return records |
340 | 357 |
341 def _writerecords(self, records): | 358 def _writerecords(self, records): |
342 """Write current state on disk (both v1 and v2)""" | 359 """Write current state on disk (both v1 and v2)""" |
343 self._writerecordsv1(records) | 360 self._writerecordsv1(records) |
420 """Obtain the paths of driver-resolved files.""" | 437 """Obtain the paths of driver-resolved files.""" |
421 | 438 |
422 for f, entry in self._state.items(): | 439 for f, entry in self._state.items(): |
423 if entry[0] == 'd': | 440 if entry[0] == 'd': |
424 yield f | 441 yield f |
442 | |
443 def extras(self, filename): | |
444 return self._stateextras.setdefault(filename, {}) | |
425 | 445 |
426 def _resolve(self, preresolve, dfile, wctx, labels=None): | 446 def _resolve(self, preresolve, dfile, wctx, labels=None): |
427 """rerun merge process for file path `dfile`""" | 447 """rerun merge process for file path `dfile`""" |
428 if self[dfile] in 'rd': | 448 if self[dfile] in 'rd': |
429 return True, 0 | 449 return True, 0 |
460 lfile, fcd, fco, fca, | 480 lfile, fcd, fco, fca, |
461 labels=labels) | 481 labels=labels) |
462 if r is None: | 482 if r is None: |
463 # no real conflict | 483 # no real conflict |
464 del self._state[dfile] | 484 del self._state[dfile] |
485 self._stateextras.pop(dfile, None) | |
465 self._dirty = True | 486 self._dirty = True |
466 elif not r: | 487 elif not r: |
467 self.mark(dfile, 'r') | 488 self.mark(dfile, 'r') |
468 | 489 |
469 if complete: | 490 if complete: |