equal
deleted
inserted
replaced
64 O: the node of the "other" part of the merge (hexified version) |
64 O: the node of the "other" part of the merge (hexified version) |
65 F: a file to be merged entry |
65 F: a file to be merged entry |
66 C: a change/delete or delete/change conflict |
66 C: a change/delete or delete/change conflict |
67 D: a file that the external merge driver will merge internally |
67 D: a file that the external merge driver will merge internally |
68 (experimental) |
68 (experimental) |
|
69 P: a path conflict (file vs directory) |
69 m: the external merge driver defined for this merge plus its run state |
70 m: the external merge driver defined for this merge plus its run state |
70 (experimental) |
71 (experimental) |
71 f: a (filename, dictionary) tuple of optional values for a given file |
72 f: a (filename, dictionary) tuple of optional values for a given file |
72 X: unsupported mandatory record type (used in tests) |
73 X: unsupported mandatory record type (used in tests) |
73 x: unsupported advisory record type (used in tests) |
74 x: unsupported advisory record type (used in tests) |
77 u: driver-resolved files unmarked -- needs to be run next time we're about |
78 u: driver-resolved files unmarked -- needs to be run next time we're about |
78 to resolve or commit |
79 to resolve or commit |
79 m: driver-resolved files marked -- only needs to be run before commit |
80 m: driver-resolved files marked -- only needs to be run before commit |
80 s: success/skipped -- does not need to be run any more |
81 s: success/skipped -- does not need to be run any more |
81 |
82 |
|
83 Merge record states (stored in self._state, indexed by filename): |
|
84 u: unresolved conflict |
|
85 r: resolved conflict |
|
86 pu: unresolved path conflict (file conflicts with directory) |
|
87 pr: resolved path conflict |
|
88 d: driver-resolved conflict |
|
89 |
|
90 The resolve command transitions between 'u' and 'r' for conflicts and |
|
91 'pu' and 'pr' for path conflicts. |
82 ''' |
92 ''' |
83 statepathv1 = 'merge/state' |
93 statepathv1 = 'merge/state' |
84 statepathv2 = 'merge/state2' |
94 statepathv2 = 'merge/state2' |
85 |
95 |
86 @staticmethod |
96 @staticmethod |
156 # the merge driver should be idempotent, so just rerun it |
166 # the merge driver should be idempotent, so just rerun it |
157 mdstate = 'u' |
167 mdstate = 'u' |
158 |
168 |
159 self._readmergedriver = bits[0] |
169 self._readmergedriver = bits[0] |
160 self._mdstate = mdstate |
170 self._mdstate = mdstate |
161 elif rtype in 'FDC': |
171 elif rtype in 'FDCP': |
162 bits = record.split('\0') |
172 bits = record.split('\0') |
163 self._state[bits[0]] = bits[1:] |
173 self._state[bits[0]] = bits[1:] |
164 elif rtype == 'f': |
174 elif rtype == 'f': |
165 filename, rawextras = record.split('\0', 1) |
175 filename, rawextras = record.split('\0', 1) |
166 extraparts = rawextras.split('\0') |
176 extraparts = rawextras.split('\0') |
352 records.append(('m', '\0'.join([ |
362 records.append(('m', '\0'.join([ |
353 self.mergedriver, self._mdstate]))) |
363 self.mergedriver, self._mdstate]))) |
354 for d, v in self._state.iteritems(): |
364 for d, v in self._state.iteritems(): |
355 if v[0] == 'd': |
365 if v[0] == 'd': |
356 records.append(('D', '\0'.join([d] + v))) |
366 records.append(('D', '\0'.join([d] + v))) |
|
367 elif v[0] in ('pu', 'pr'): |
|
368 records.append(('P', '\0'.join([d] + v))) |
357 # v[1] == local ('cd'), v[6] == other ('dc') -- not supported by |
369 # v[1] == local ('cd'), v[6] == other ('dc') -- not supported by |
358 # older versions of Mercurial |
370 # older versions of Mercurial |
359 elif v[1] == nullhex or v[6] == nullhex: |
371 elif v[1] == nullhex or v[6] == nullhex: |
360 records.append(('C', '\0'.join([d] + v))) |
372 records.append(('C', '\0'.join([d] + v))) |
361 else: |
373 else: |
420 fco.path(), hex(fco.filenode()), |
432 fco.path(), hex(fco.filenode()), |
421 fcl.flags()] |
433 fcl.flags()] |
422 self._stateextras[fd] = {'ancestorlinknode': hex(fca.node())} |
434 self._stateextras[fd] = {'ancestorlinknode': hex(fca.node())} |
423 self._dirty = True |
435 self._dirty = True |
424 |
436 |
|
437 def addpath(self, path, frename, forigin): |
|
438 """add a new conflicting path to the merge state |
|
439 path: the path that conflicts |
|
440 frename: the filename the conflicting file was renamed to |
|
441 forigin: origin of the file ('l' or 'r' for local/remote) |
|
442 """ |
|
443 self._state[path] = ['pu', frename, forigin] |
|
444 self._dirty = True |
|
445 |
425 def __contains__(self, dfile): |
446 def __contains__(self, dfile): |
426 return dfile in self._state |
447 return dfile in self._state |
427 |
448 |
428 def __getitem__(self, dfile): |
449 def __getitem__(self, dfile): |
429 return self._state[dfile][0] |
450 return self._state[dfile][0] |
443 |
464 |
444 def unresolved(self): |
465 def unresolved(self): |
445 """Obtain the paths of unresolved files.""" |
466 """Obtain the paths of unresolved files.""" |
446 |
467 |
447 for f, entry in self._state.iteritems(): |
468 for f, entry in self._state.iteritems(): |
448 if entry[0] == 'u': |
469 if entry[0] in ('u', 'pu'): |
449 yield f |
470 yield f |
450 |
471 |
451 def driverresolved(self): |
472 def driverresolved(self): |
452 """Obtain the paths of driver-resolved files.""" |
473 """Obtain the paths of driver-resolved files.""" |
453 |
474 |