Show More
@@ -18,9 +18,9 import errno, os, shutil | |||||
18 |
|
18 | |||
19 | def _droponode(data): |
|
19 | def _droponode(data): | |
20 | # used for compatibility for v1 |
|
20 | # used for compatibility for v1 | |
21 |
bits = data.split( |
|
21 | bits = data.split('\0') | |
22 | bits = bits[:-2] + bits[-1:] |
|
22 | bits = bits[:-2] + bits[-1:] | |
23 |
return |
|
23 | return '\0'.join(bits) | |
24 |
|
24 | |||
25 | class mergestate(object): |
|
25 | class mergestate(object): | |
26 | '''track 3-way merge state of individual files |
|
26 | '''track 3-way merge state of individual files | |
@@ -45,8 +45,8 class mergestate(object): | |||||
45 | O: the node of the "other" part of the merge (hexified version) |
|
45 | O: the node of the "other" part of the merge (hexified version) | |
46 | F: a file to be merged entry |
|
46 | F: a file to be merged entry | |
47 | ''' |
|
47 | ''' | |
48 |
statepathv1 = |
|
48 | statepathv1 = 'merge/state' | |
49 |
statepathv2 = |
|
49 | statepathv2 = 'merge/state2' | |
50 |
|
50 | |||
51 | def __init__(self, repo): |
|
51 | def __init__(self, repo): | |
52 | self._repo = repo |
|
52 | self._repo = repo | |
@@ -60,7 +60,7 class mergestate(object): | |||||
60 | if node: |
|
60 | if node: | |
61 | self._local = node |
|
61 | self._local = node | |
62 | self._other = other |
|
62 | self._other = other | |
63 |
shutil.rmtree(self._repo.join( |
|
63 | shutil.rmtree(self._repo.join('merge'), True) | |
64 | self._dirty = False |
|
64 | self._dirty = False | |
65 |
|
65 | |||
66 | def _read(self): |
|
66 | def _read(self): | |
@@ -78,8 +78,8 class mergestate(object): | |||||
78 | self._local = bin(record) |
|
78 | self._local = bin(record) | |
79 | elif rtype == 'O': |
|
79 | elif rtype == 'O': | |
80 | self._other = bin(record) |
|
80 | self._other = bin(record) | |
81 |
elif rtype == |
|
81 | elif rtype == 'F': | |
82 |
bits = record.split( |
|
82 | bits = record.split('\0') | |
83 | self._state[bits[0]] = bits[1:] |
|
83 | self._state[bits[0]] = bits[1:] | |
84 | elif not rtype.islower(): |
|
84 | elif not rtype.islower(): | |
85 | raise util.Abort(_('unsupported merge state record: %s') |
|
85 | raise util.Abort(_('unsupported merge state record: %s') | |
@@ -121,9 +121,9 class mergestate(object): | |||||
121 | # if mctx was wrong `mctx[bits[-2]]` may fails. |
|
121 | # if mctx was wrong `mctx[bits[-2]]` may fails. | |
122 | for idx, r in enumerate(v1records): |
|
122 | for idx, r in enumerate(v1records): | |
123 | if r[0] == 'F': |
|
123 | if r[0] == 'F': | |
124 |
bits = r[1].split( |
|
124 | bits = r[1].split('\0') | |
125 | bits.insert(-2, '') |
|
125 | bits.insert(-2, '') | |
126 |
v1records[idx] = (r[0], |
|
126 | v1records[idx] = (r[0], '\0'.join(bits)) | |
127 | return v1records |
|
127 | return v1records | |
128 | else: |
|
128 | else: | |
129 | return v2records |
|
129 | return v2records | |
@@ -191,10 +191,10 class mergestate(object): | |||||
191 | """Write current state on disk (if necessary)""" |
|
191 | """Write current state on disk (if necessary)""" | |
192 | if self._dirty: |
|
192 | if self._dirty: | |
193 | records = [] |
|
193 | records = [] | |
194 |
records.append(( |
|
194 | records.append(('L', hex(self._local))) | |
195 |
records.append(( |
|
195 | records.append(('O', hex(self._other))) | |
196 | for d, v in self._state.iteritems(): |
|
196 | for d, v in self._state.iteritems(): | |
197 |
records.append(( |
|
197 | records.append(('F', '\0'.join([d] + v))) | |
198 | self._writerecords(records) |
|
198 | self._writerecords(records) | |
199 | self._dirty = False |
|
199 | self._dirty = False | |
200 |
|
200 | |||
@@ -205,22 +205,22 class mergestate(object): | |||||
205 |
|
205 | |||
206 | def _writerecordsv1(self, records): |
|
206 | def _writerecordsv1(self, records): | |
207 | """Write current state on disk in a version 1 file""" |
|
207 | """Write current state on disk in a version 1 file""" | |
208 |
f = self._repo.opener(self.statepathv1, |
|
208 | f = self._repo.opener(self.statepathv1, 'w') | |
209 | irecords = iter(records) |
|
209 | irecords = iter(records) | |
210 | lrecords = irecords.next() |
|
210 | lrecords = irecords.next() | |
211 | assert lrecords[0] == 'L' |
|
211 | assert lrecords[0] == 'L' | |
212 |
f.write(hex(self._local) + |
|
212 | f.write(hex(self._local) + '\n') | |
213 | for rtype, data in irecords: |
|
213 | for rtype, data in irecords: | |
214 |
if rtype == |
|
214 | if rtype == 'F': | |
215 |
f.write( |
|
215 | f.write('%s\n' % _droponode(data)) | |
216 | f.close() |
|
216 | f.close() | |
217 |
|
217 | |||
218 | def _writerecordsv2(self, records): |
|
218 | def _writerecordsv2(self, records): | |
219 | """Write current state on disk in a version 2 file""" |
|
219 | """Write current state on disk in a version 2 file""" | |
220 |
f = self._repo.opener(self.statepathv2, |
|
220 | f = self._repo.opener(self.statepathv2, 'w') | |
221 | for key, data in records: |
|
221 | for key, data in records: | |
222 | assert len(key) == 1 |
|
222 | assert len(key) == 1 | |
223 |
format = |
|
223 | format = '>sI%is' % len(data) | |
224 | f.write(_pack(format, key, len(data), data)) |
|
224 | f.write(_pack(format, key, len(data), data)) | |
225 | f.close() |
|
225 | f.close() | |
226 |
|
226 | |||
@@ -234,7 +234,7 class mergestate(object): | |||||
234 | note: also write the local version to the `.hg/merge` directory. |
|
234 | note: also write the local version to the `.hg/merge` directory. | |
235 | """ |
|
235 | """ | |
236 | hash = util.sha1(fcl.path()).hexdigest() |
|
236 | hash = util.sha1(fcl.path()).hexdigest() | |
237 |
self._repo.opener.write( |
|
237 | self._repo.opener.write('merge/' + hash, fcl.data()) | |
238 | self._state[fd] = ['u', hash, fcl.path(), |
|
238 | self._state[fd] = ['u', hash, fcl.path(), | |
239 | fca.path(), hex(fca.filenode()), |
|
239 | fca.path(), hex(fca.filenode()), | |
240 | fco.path(), hex(fco.filenode()), |
|
240 | fco.path(), hex(fco.filenode()), | |
@@ -284,7 +284,7 class mergestate(object): | |||||
284 | elif flags == fla: |
|
284 | elif flags == fla: | |
285 | flags = flo |
|
285 | flags = flo | |
286 | # restore local |
|
286 | # restore local | |
287 |
f = self._repo.opener( |
|
287 | f = self._repo.opener('merge/' + hash) | |
288 | self._repo.wwrite(dfile, f.read(), flags) |
|
288 | self._repo.wwrite(dfile, f.read(), flags) | |
289 | f.close() |
|
289 | f.close() | |
290 | r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca, |
|
290 | r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca, | |
@@ -405,7 +405,7 def manifestmerge(repo, wctx, p2, pa, br | |||||
405 | # check whether sub state is modified |
|
405 | # check whether sub state is modified | |
406 | for s in sorted(wctx.substate): |
|
406 | for s in sorted(wctx.substate): | |
407 | if wctx.sub(s).dirty(): |
|
407 | if wctx.sub(s).dirty(): | |
408 |
m1['.hgsubstate'] += |
|
408 | m1['.hgsubstate'] += '+' | |
409 | break |
|
409 | break | |
410 |
|
410 | |||
411 | aborts = [] |
|
411 | aborts = [] | |
@@ -454,7 +454,7 def manifestmerge(repo, wctx, p2, pa, br | |||||
454 | actions['r'].append((f, None, "remote delete")) |
|
454 | actions['r'].append((f, None, "remote delete")) | |
455 | else: |
|
455 | else: | |
456 | actions['cd'].append((f, None, "prompt changed/deleted")) |
|
456 | actions['cd'].append((f, None, "prompt changed/deleted")) | |
457 |
elif n1[20:] == |
|
457 | elif n1[20:] == 'a': # added, no remote | |
458 | actions['f'].append((f, None, "remote deleted")) |
|
458 | actions['f'].append((f, None, "remote deleted")) | |
459 | else: |
|
459 | else: | |
460 | actions['r'].append((f, None, "other deleted")) |
|
460 | actions['r'].append((f, None, "other deleted")) | |
@@ -492,13 +492,13 def manifestmerge(repo, wctx, p2, pa, br | |||||
492 | actions['m'].append((f, (f, f, f, False, pa.node()), |
|
492 | actions['m'].append((f, (f, f, f, False, pa.node()), | |
493 | "remote differs from untracked local")) |
|
493 | "remote differs from untracked local")) | |
494 | elif not force and different: |
|
494 | elif not force and different: | |
495 |
aborts.append((f, |
|
495 | aborts.append((f, 'ud')) | |
496 | else: |
|
496 | else: | |
497 | actions['g'].append((f, (fl2,), "remote created")) |
|
497 | actions['g'].append((f, (fl2,), "remote created")) | |
498 | elif n2 and n2 != ma[f]: |
|
498 | elif n2 and n2 != ma[f]: | |
499 | different = _checkunknownfile(repo, wctx, p2, f) |
|
499 | different = _checkunknownfile(repo, wctx, p2, f) | |
500 | if not force and different: |
|
500 | if not force and different: | |
501 |
aborts.append((f, |
|
501 | aborts.append((f, 'ud')) | |
502 | else: |
|
502 | else: | |
503 | if acceptremote: |
|
503 | if acceptremote: | |
504 | actions['g'].append((f, (fl2,), "remote recreating")) |
|
504 | actions['g'].append((f, (fl2,), "remote recreating")) | |
@@ -506,7 +506,7 def manifestmerge(repo, wctx, p2, pa, br | |||||
506 | actions['dc'].append((f, (fl2,), "prompt deleted/changed")) |
|
506 | actions['dc'].append((f, (fl2,), "prompt deleted/changed")) | |
507 |
|
507 | |||
508 | for f, m in sorted(aborts): |
|
508 | for f, m in sorted(aborts): | |
509 |
if m == |
|
509 | if m == 'ud': | |
510 | repo.ui.warn(_("%s: untracked file differs\n") % f) |
|
510 | repo.ui.warn(_("%s: untracked file differs\n") % f) | |
511 | else: assert False, m |
|
511 | else: assert False, m | |
512 | if aborts: |
|
512 | if aborts: | |
@@ -785,14 +785,14 def calculateupdates(repo, wctx, mctx, a | |||||
785 | actions[m].append(l[0]) |
|
785 | actions[m].append(l[0]) | |
786 | continue |
|
786 | continue | |
787 | # If keep is an option, just do it. |
|
787 | # If keep is an option, just do it. | |
788 |
if |
|
788 | if 'k' in bids: | |
789 | repo.ui.note(" %s: picking 'keep' action\n" % f) |
|
789 | repo.ui.note(" %s: picking 'keep' action\n" % f) | |
790 |
actions['k'].append(bids[ |
|
790 | actions['k'].append(bids['k'][0]) | |
791 | continue |
|
791 | continue | |
792 | # If there are gets and they all agree [how could they not?], do it. |
|
792 | # If there are gets and they all agree [how could they not?], do it. | |
793 |
if |
|
793 | if 'g' in bids: | |
794 |
ga0 = bids[ |
|
794 | ga0 = bids['g'][0] | |
795 |
if util.all(a == ga0 for a in bids[ |
|
795 | if util.all(a == ga0 for a in bids['g'][1:]): | |
796 | repo.ui.note(" %s: picking 'get' action\n" % f) |
|
796 | repo.ui.note(" %s: picking 'get' action\n" % f) | |
797 | actions['g'].append(ga0) |
|
797 | actions['g'].append(ga0) | |
798 | continue |
|
798 | continue | |
@@ -980,8 +980,8 def update(repo, node, branchmerge, forc | |||||
980 | try: |
|
980 | try: | |
981 | node = repo.branchtip(wc.branch()) |
|
981 | node = repo.branchtip(wc.branch()) | |
982 | except errormod.RepoLookupError: |
|
982 | except errormod.RepoLookupError: | |
983 |
if wc.branch() == |
|
983 | if wc.branch() == 'default': # no default branch! | |
984 |
node = repo.lookup( |
|
984 | node = repo.lookup('tip') # update to tip | |
985 | else: |
|
985 | else: | |
986 | raise util.Abort(_("branch %s not found") % wc.branch()) |
|
986 | raise util.Abort(_("branch %s not found") % wc.branch()) | |
987 |
|
987 | |||
@@ -1009,14 +1009,14 def update(repo, node, branchmerge, forc | |||||
1009 |
|
1009 | |||
1010 | # get the max revision for the given successors set, |
|
1010 | # get the max revision for the given successors set, | |
1011 | # i.e. the 'tip' of a set |
|
1011 | # i.e. the 'tip' of a set | |
1012 |
node = repo.revs( |
|
1012 | node = repo.revs('max(%ln)', successors).first() | |
1013 | pas = [p1] |
|
1013 | pas = [p1] | |
1014 |
|
1014 | |||
1015 | overwrite = force and not branchmerge |
|
1015 | overwrite = force and not branchmerge | |
1016 |
|
1016 | |||
1017 | p2 = repo[node] |
|
1017 | p2 = repo[node] | |
1018 | if pas[0] is None: |
|
1018 | if pas[0] is None: | |
1019 |
if repo.ui.config( |
|
1019 | if repo.ui.config('merge', 'preferancestor', '*') == '*': | |
1020 | cahs = repo.changelog.commonancestorsheads(p1.node(), p2.node()) |
|
1020 | cahs = repo.changelog.commonancestorsheads(p1.node(), p2.node()) | |
1021 | pas = [repo[anc] for anc in (sorted(cahs) or [nullid])] |
|
1021 | pas = [repo[anc] for anc in (sorted(cahs) or [nullid])] | |
1022 | else: |
|
1022 | else: | |
@@ -1084,7 +1084,7 def update(repo, node, branchmerge, forc | |||||
1084 | pas = [wc.p1()] |
|
1084 | pas = [wc.p1()] | |
1085 | elif not branchmerge and not wc.dirty(missing=True): |
|
1085 | elif not branchmerge and not wc.dirty(missing=True): | |
1086 | pass |
|
1086 | pass | |
1087 |
elif pas[0] and repo.ui.configbool( |
|
1087 | elif pas[0] and repo.ui.configbool('merge', 'followcopies', True): | |
1088 | followcopies = True |
|
1088 | followcopies = True | |
1089 |
|
1089 | |||
1090 | ### calculate phase |
|
1090 | ### calculate phase |
General Comments 0
You need to be logged in to leave comments.
Login now