narrowmerge.py
76 lines
| 2.9 KiB
| text/x-python
|
PythonLexer
|
r36096 | # narrowmerge.py - extensions to mercurial merge module to support narrow clones | ||
# | ||||
# Copyright 2017 Google, Inc. | ||||
# | ||||
# This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | ||||
from __future__ import absolute_import | ||||
from mercurial.i18n import _ | ||||
from mercurial import ( | ||||
copies, | ||||
error, | ||||
extensions, | ||||
merge, | ||||
util, | ||||
) | ||||
def setup(): | ||||
def _manifestmerge(orig, repo, wctx, p2, pa, branchmerge, *args, **kwargs): | ||||
"""Filter updates to only lay out files that match the narrow spec.""" | ||||
actions, diverge, renamedelete = orig( | ||||
repo, wctx, p2, pa, branchmerge, *args, **kwargs) | ||||
if not util.safehasattr(repo, 'narrowmatch'): | ||||
return actions, diverge, renamedelete | ||||
nooptypes = set(['k']) # TODO: handle with nonconflicttypes | ||||
nonconflicttypes = set('a am c cm f g r e'.split()) | ||||
narrowmatch = repo.narrowmatch() | ||||
for f, action in actions.items(): | ||||
if narrowmatch(f): | ||||
pass | ||||
elif not branchmerge: | ||||
del actions[f] # just updating, ignore changes outside clone | ||||
elif action[0] in nooptypes: | ||||
del actions[f] # merge does not affect file | ||||
elif action[0] in nonconflicttypes: | ||||
raise error.Abort(_('merge affects file \'%s\' outside narrow, ' | ||||
'which is not yet supported') % f, | ||||
hint=_('merging in the other direction ' | ||||
'may work')) | ||||
else: | ||||
raise error.Abort(_('conflict in file \'%s\' is outside ' | ||||
'narrow clone') % f) | ||||
return actions, diverge, renamedelete | ||||
extensions.wrapfunction(merge, 'manifestmerge', _manifestmerge) | ||||
def _checkcollision(orig, repo, wmf, actions): | ||||
if util.safehasattr(repo, 'narrowmatch'): | ||||
narrowmatch = repo.narrowmatch() | ||||
wmf = wmf.matches(narrowmatch) | ||||
if actions: | ||||
narrowactions = {} | ||||
for m, actionsfortype in actions.iteritems(): | ||||
narrowactions[m] = [] | ||||
for (f, args, msg) in actionsfortype: | ||||
if narrowmatch(f): | ||||
narrowactions[m].append((f, args, msg)) | ||||
actions = narrowactions | ||||
return orig(repo, wmf, actions) | ||||
extensions.wrapfunction(merge, '_checkcollision', _checkcollision) | ||||
def _computenonoverlap(orig, repo, *args, **kwargs): | ||||
u1, u2 = orig(repo, *args, **kwargs) | ||||
if not util.safehasattr(repo, 'narrowmatch'): | ||||
return u1, u2 | ||||
narrowmatch = repo.narrowmatch() | ||||
u1 = [f for f in u1 if narrowmatch(f)] | ||||
u2 = [f for f in u2 if narrowmatch(f)] | ||||
return u1, u2 | ||||
extensions.wrapfunction(copies, '_computenonoverlap', _computenonoverlap) | ||||