narrowmerge.py
77 lines
| 2.9 KiB
| text/x-python
|
PythonLexer
Augie Fackler
|
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, | ||||
) | ||||
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) | ||||
Martin von Zweigbergk
|
r36490 | narrowmatch = repo.narrowmatch() | ||
if narrowmatch.always(): | ||||
Augie Fackler
|
r36096 | return actions, diverge, renamedelete | ||
nooptypes = set(['k']) # TODO: handle with nonconflicttypes | ||||
nonconflicttypes = set('a am c cm f g r e'.split()) | ||||
Augie Fackler
|
r36183 | # We mutate the items in the dict during iteration, so iterate | ||
# over a copy. | ||||
for f, action in list(actions.items()): | ||||
Augie Fackler
|
r36096 | 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): | ||||
Martin von Zweigbergk
|
r36490 | narrowmatch = repo.narrowmatch() | ||
if not narrowmatch.always(): | ||||
Augie Fackler
|
r36096 | 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) | ||||
Martin von Zweigbergk
|
r36490 | narrowmatch = repo.narrowmatch() | ||
if narrowmatch.always(): | ||||
Augie Fackler
|
r36096 | return u1, u2 | ||
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) | ||||