comparison mercurial/merge.py @ 37111:aa5199c7aa42

merge: use constants for merge record state Named constants are easier to read than short string values. Differential Revision: https://phab.mercurial-scm.org/D2700
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 05 Mar 2018 14:21:57 -0500
parents 1b158ca37ea4
children 43ffd9070da1
comparison
equal deleted inserted replaced
37110:1b158ca37ea4 37111:aa5199c7aa42
62 RECORD_UNSUPPORTED_ADVISORY = b'x' 62 RECORD_UNSUPPORTED_ADVISORY = b'x'
63 63
64 MERGE_DRIVER_STATE_UNMARKED = b'u' 64 MERGE_DRIVER_STATE_UNMARKED = b'u'
65 MERGE_DRIVER_STATE_MARKED = b'm' 65 MERGE_DRIVER_STATE_MARKED = b'm'
66 MERGE_DRIVER_STATE_SUCCESS = b's' 66 MERGE_DRIVER_STATE_SUCCESS = b's'
67
68 MERGE_RECORD_UNRESOLVED = b'u'
69 MERGE_RECORD_RESOLVED = b'r'
70 MERGE_RECORD_UNRESOLVED_PATH = b'pu'
71 MERGE_RECORD_RESOLVED_PATH = b'pr'
72 MERGE_RECORD_DRIVER_RESOLVED = b'd'
67 73
68 class mergestate(object): 74 class mergestate(object):
69 '''track 3-way merge state of individual files 75 '''track 3-way merge state of individual files
70 76
71 The merge state is stored on disk when needed. Two files are used: one with 77 The merge state is stored on disk when needed. Two files are used: one with
389 # is written as the contents of the record. The record type depends on 395 # is written as the contents of the record. The record type depends on
390 # the type of state that is stored, and capital-letter records are used 396 # the type of state that is stored, and capital-letter records are used
391 # to prevent older versions of Mercurial that do not support the feature 397 # to prevent older versions of Mercurial that do not support the feature
392 # from loading them. 398 # from loading them.
393 for filename, v in self._state.iteritems(): 399 for filename, v in self._state.iteritems():
394 if v[0] == 'd': 400 if v[0] == MERGE_RECORD_DRIVER_RESOLVED:
395 # Driver-resolved merge. These are stored in 'D' records. 401 # Driver-resolved merge. These are stored in 'D' records.
396 records.append((RECORD_MERGE_DRIVER_MERGE, 402 records.append((RECORD_MERGE_DRIVER_MERGE,
397 '\0'.join([filename] + v))) 403 '\0'.join([filename] + v)))
398 elif v[0] in ('pu', 'pr'): 404 elif v[0] in (MERGE_RECORD_UNRESOLVED_PATH,
405 MERGE_RECORD_RESOLVED_PATH):
399 # Path conflicts. These are stored in 'P' records. The current 406 # Path conflicts. These are stored in 'P' records. The current
400 # resolution state ('pu' or 'pr') is stored within the record. 407 # resolution state ('pu' or 'pr') is stored within the record.
401 records.append((RECORD_PATH_CONFLICT, 408 records.append((RECORD_PATH_CONFLICT,
402 '\0'.join([filename] + v))) 409 '\0'.join([filename] + v)))
403 elif v[1] == nullhex or v[6] == nullhex: 410 elif v[1] == nullhex or v[6] == nullhex:
465 if fcl.isabsent(): 472 if fcl.isabsent():
466 hash = nullhex 473 hash = nullhex
467 else: 474 else:
468 hash = hex(hashlib.sha1(fcl.path()).digest()) 475 hash = hex(hashlib.sha1(fcl.path()).digest())
469 self._repo.vfs.write('merge/' + hash, fcl.data()) 476 self._repo.vfs.write('merge/' + hash, fcl.data())
470 self._state[fd] = ['u', hash, fcl.path(), 477 self._state[fd] = [MERGE_RECORD_UNRESOLVED, hash, fcl.path(),
471 fca.path(), hex(fca.filenode()), 478 fca.path(), hex(fca.filenode()),
472 fco.path(), hex(fco.filenode()), 479 fco.path(), hex(fco.filenode()),
473 fcl.flags()] 480 fcl.flags()]
474 self._stateextras[fd] = {'ancestorlinknode': hex(fca.node())} 481 self._stateextras[fd] = {'ancestorlinknode': hex(fca.node())}
475 self._dirty = True 482 self._dirty = True
478 """add a new conflicting path to the merge state 485 """add a new conflicting path to the merge state
479 path: the path that conflicts 486 path: the path that conflicts
480 frename: the filename the conflicting file was renamed to 487 frename: the filename the conflicting file was renamed to
481 forigin: origin of the file ('l' or 'r' for local/remote) 488 forigin: origin of the file ('l' or 'r' for local/remote)
482 """ 489 """
483 self._state[path] = ['pu', frename, forigin] 490 self._state[path] = [MERGE_RECORD_UNRESOLVED_PATH, frename, forigin]
484 self._dirty = True 491 self._dirty = True
485 492
486 def __contains__(self, dfile): 493 def __contains__(self, dfile):
487 return dfile in self._state 494 return dfile in self._state
488 495
504 511
505 def unresolved(self): 512 def unresolved(self):
506 """Obtain the paths of unresolved files.""" 513 """Obtain the paths of unresolved files."""
507 514
508 for f, entry in self._state.iteritems(): 515 for f, entry in self._state.iteritems():
509 if entry[0] in ('u', 'pu'): 516 if entry[0] in (MERGE_RECORD_UNRESOLVED,
517 MERGE_RECORD_UNRESOLVED_PATH):
510 yield f 518 yield f
511 519
512 def driverresolved(self): 520 def driverresolved(self):
513 """Obtain the paths of driver-resolved files.""" 521 """Obtain the paths of driver-resolved files."""
514 522
515 for f, entry in self._state.items(): 523 for f, entry in self._state.items():
516 if entry[0] == 'd': 524 if entry[0] == MERGE_RECORD_DRIVER_RESOLVED:
517 yield f 525 yield f
518 526
519 def extras(self, filename): 527 def extras(self, filename):
520 return self._stateextras.setdefault(filename, {}) 528 return self._stateextras.setdefault(filename, {})
521 529
522 def _resolve(self, preresolve, dfile, wctx): 530 def _resolve(self, preresolve, dfile, wctx):
523 """rerun merge process for file path `dfile`""" 531 """rerun merge process for file path `dfile`"""
524 if self[dfile] in 'rd': 532 if self[dfile] in (MERGE_RECORD_RESOLVED,
533 MERGE_RECORD_DRIVER_RESOLVED):
525 return True, 0 534 return True, 0
526 stateentry = self._state[dfile] 535 stateentry = self._state[dfile]
527 state, hash, lfile, afile, anode, ofile, onode, flags = stateentry 536 state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
528 octx = self._repo[self._other] 537 octx = self._repo[self._other]
529 extras = self.extras(dfile) 538 extras = self.extras(dfile)
569 # no real conflict 578 # no real conflict
570 del self._state[dfile] 579 del self._state[dfile]
571 self._stateextras.pop(dfile, None) 580 self._stateextras.pop(dfile, None)
572 self._dirty = True 581 self._dirty = True
573 elif not r: 582 elif not r:
574 self.mark(dfile, 'r') 583 self.mark(dfile, MERGE_RECORD_RESOLVED)
575 584
576 if complete: 585 if complete:
577 action = None 586 action = None
578 if deleted: 587 if deleted:
579 if fcd.isabsent(): 588 if fcd.isabsent():