comparison mercurial/merge.py @ 20591:02c60e380fd0 stable

merge: record the "other" node in merge state We need to record the merge we were merging with. This solve multiple bug with resolve when dropping the second parent after a merge. This happen a lot when doing special merge (overriding the ancestor). Backout, shelve, rebase, etc. can takes advantage of it. This changeset just add the information in the merge state. We'll use it in the resolve process in a later changeset.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Tue, 25 Feb 2014 18:42:11 -0800
parents 2b7d54e929b4
children 303cbfe3dcc8
comparison
equal deleted inserted replaced
20590:2b7d54e929b4 20591:02c60e380fd0
34 should abort if they are unknown. lower case record can be safely ignored. 34 should abort if they are unknown. lower case record can be safely ignored.
35 35
36 Currently known record: 36 Currently known record:
37 37
38 L: the node of the "local" part of the merge (hexified version) 38 L: the node of the "local" part of the merge (hexified version)
39 O: the node of the "other" part of the merge (hexified version)
39 F: a file to be merged entry 40 F: a file to be merged entry
40 ''' 41 '''
41 statepathv1 = "merge/state" 42 statepathv1 = "merge/state"
42 statepathv2 = "merge/state2" 43 statepathv2 = "merge/state2"
43 def __init__(self, repo): 44 def __init__(self, repo):
44 self._repo = repo 45 self._repo = repo
45 self._dirty = False 46 self._dirty = False
46 self._read() 47 self._read()
47 def reset(self, node=None): 48 def reset(self, node=None, other=None):
48 self._state = {} 49 self._state = {}
49 if node: 50 if node:
50 self._local = node 51 self._local = node
52 self._other = other
51 shutil.rmtree(self._repo.join("merge"), True) 53 shutil.rmtree(self._repo.join("merge"), True)
52 self._dirty = False 54 self._dirty = False
53 def _read(self): 55 def _read(self):
54 self._state = {} 56 self._state = {}
55 records = self._readrecords() 57 records = self._readrecords()
56 for rtype, record in records: 58 for rtype, record in records:
57 if rtype == 'L': 59 if rtype == 'L':
58 self._local = bin(record) 60 self._local = bin(record)
61 elif rtype == 'O':
62 self._other = bin(record)
59 elif rtype == "F": 63 elif rtype == "F":
60 bits = record.split("\0") 64 bits = record.split("\0")
61 self._state[bits[0]] = bits[1:] 65 self._state[bits[0]] = bits[1:]
62 elif not rtype.islower(): 66 elif not rtype.islower():
63 raise util.Abort(_('unsupported merge state record:' 67 raise util.Abort(_('unsupported merge state record:'
109 return records 113 return records
110 def commit(self): 114 def commit(self):
111 if self._dirty: 115 if self._dirty:
112 records = [] 116 records = []
113 records.append(("L", hex(self._local))) 117 records.append(("L", hex(self._local)))
118 records.append(("O", hex(self._other)))
114 for d, v in self._state.iteritems(): 119 for d, v in self._state.iteritems():
115 records.append(("F", "\0".join([d] + v))) 120 records.append(("F", "\0".join([d] + v)))
116 self._writerecords(records) 121 self._writerecords(records)
117 self._dirty = False 122 self._dirty = False
118 def _writerecords(self, records): 123 def _writerecords(self, records):
527 describes how many files were affected by the update. 532 describes how many files were affected by the update.
528 """ 533 """
529 534
530 updated, merged, removed, unresolved = 0, 0, 0, 0 535 updated, merged, removed, unresolved = 0, 0, 0, 0
531 ms = mergestate(repo) 536 ms = mergestate(repo)
532 ms.reset(wctx.p1().node()) 537 ms.reset(wctx.p1().node(), mctx.node())
533 moves = [] 538 moves = []
534 actions.sort(key=actionkey) 539 actions.sort(key=actionkey)
535 540
536 # prescan for merges 541 # prescan for merges
537 for a in actions: 542 for a in actions: