comparison mercurial/merge.py @ 41155:8c222bec97da

merge: make local file storage in the .hg/merge directory extensible This is similar to remotefilelog's 'getlocalkey' method, which must be overridden by systems which rely on full path names for access control purposes. Differential Revision: https://phab.mercurial-scm.org/D5534
author Daniel Ploch <dploch@google.com>
date Tue, 08 Jan 2019 14:19:51 -0800
parents 6faaf3a1c6ec
children 876494fd967d
comparison
equal deleted inserted replaced
41154:f18f665b1424 41155:8c222bec97da
476 key, data = RECORD_OVERRIDE, '%s%s' % (key, data) 476 key, data = RECORD_OVERRIDE, '%s%s' % (key, data)
477 format = '>sI%is' % len(data) 477 format = '>sI%is' % len(data)
478 f.write(_pack(format, key, len(data), data)) 478 f.write(_pack(format, key, len(data), data))
479 f.close() 479 f.close()
480 480
481 @staticmethod
482 def getlocalkey(path):
483 """hash the path of a local file context for storage in the .hg/merge
484 directory."""
485
486 return hex(hashlib.sha1(path).digest())
487
481 def add(self, fcl, fco, fca, fd): 488 def add(self, fcl, fco, fca, fd):
482 """add a new (potentially?) conflicting file the merge state 489 """add a new (potentially?) conflicting file the merge state
483 fcl: file context for local, 490 fcl: file context for local,
484 fco: file context for remote, 491 fco: file context for remote,
485 fca: file context for ancestors, 492 fca: file context for ancestors,
486 fd: file path of the resulting merge. 493 fd: file path of the resulting merge.
487 494
488 note: also write the local version to the `.hg/merge` directory. 495 note: also write the local version to the `.hg/merge` directory.
489 """ 496 """
490 if fcl.isabsent(): 497 if fcl.isabsent():
491 hash = nullhex 498 localkey = nullhex
492 else: 499 else:
493 hash = hex(hashlib.sha1(fcl.path()).digest()) 500 localkey = mergestate.getlocalkey(fcl.path())
494 self._repo.vfs.write('merge/' + hash, fcl.data()) 501 self._repo.vfs.write('merge/' + localkey, fcl.data())
495 self._state[fd] = [MERGE_RECORD_UNRESOLVED, hash, fcl.path(), 502 self._state[fd] = [MERGE_RECORD_UNRESOLVED, localkey, fcl.path(),
496 fca.path(), hex(fca.filenode()), 503 fca.path(), hex(fca.filenode()),
497 fco.path(), hex(fco.filenode()), 504 fco.path(), hex(fco.filenode()),
498 fcl.flags()] 505 fcl.flags()]
499 self._stateextras[fd] = {'ancestorlinknode': hex(fca.node())} 506 self._stateextras[fd] = {'ancestorlinknode': hex(fca.node())}
500 self._dirty = True 507 self._dirty = True
549 """rerun merge process for file path `dfile`""" 556 """rerun merge process for file path `dfile`"""
550 if self[dfile] in (MERGE_RECORD_RESOLVED, 557 if self[dfile] in (MERGE_RECORD_RESOLVED,
551 MERGE_RECORD_DRIVER_RESOLVED): 558 MERGE_RECORD_DRIVER_RESOLVED):
552 return True, 0 559 return True, 0
553 stateentry = self._state[dfile] 560 stateentry = self._state[dfile]
554 state, hash, lfile, afile, anode, ofile, onode, flags = stateentry 561 state, localkey, lfile, afile, anode, ofile, onode, flags = stateentry
555 octx = self._repo[self._other] 562 octx = self._repo[self._other]
556 extras = self.extras(dfile) 563 extras = self.extras(dfile)
557 anccommitnode = extras.get('ancestorlinknode') 564 anccommitnode = extras.get('ancestorlinknode')
558 if anccommitnode: 565 if anccommitnode:
559 actx = self._repo[anccommitnode] 566 actx = self._repo[anccommitnode]
560 else: 567 else:
561 actx = None 568 actx = None
562 fcd = self._filectxorabsent(hash, wctx, dfile) 569 fcd = self._filectxorabsent(localkey, wctx, dfile)
563 fco = self._filectxorabsent(onode, octx, ofile) 570 fco = self._filectxorabsent(onode, octx, ofile)
564 # TODO: move this to filectxorabsent 571 # TODO: move this to filectxorabsent
565 fca = self._repo.filectx(afile, fileid=anode, changectx=actx) 572 fca = self._repo.filectx(afile, fileid=anode, changectx=actx)
566 # "premerge" x flags 573 # "premerge" x flags
567 flo = fco.flags() 574 flo = fco.flags()
575 % afile) 582 % afile)
576 elif flags == fla: 583 elif flags == fla:
577 flags = flo 584 flags = flo
578 if preresolve: 585 if preresolve:
579 # restore local 586 # restore local
580 if hash != nullhex: 587 if localkey != nullhex:
581 f = self._repo.vfs('merge/' + hash) 588 f = self._repo.vfs('merge/' + localkey)
582 wctx[dfile].write(f.read(), flags) 589 wctx[dfile].write(f.read(), flags)
583 f.close() 590 f.close()
584 else: 591 else:
585 wctx[dfile].remove(ignoremissing=True) 592 wctx[dfile].remove(ignoremissing=True)
586 complete, r, deleted = filemerge.premerge(self._repo, wctx, 593 complete, r, deleted = filemerge.premerge(self._repo, wctx,