##// END OF EJS Templates
narrowmerge: iterate over a copy of dict items so we can mutate the dict...
Augie Fackler -
r36183:53fe5a1a default
parent child Browse files
Show More
@@ -1,76 +1,78 b''
1 1 # narrowmerge.py - extensions to mercurial merge module to support narrow clones
2 2 #
3 3 # Copyright 2017 Google, Inc.
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 from mercurial.i18n import _
11 11 from mercurial import (
12 12 copies,
13 13 error,
14 14 extensions,
15 15 merge,
16 16 util,
17 17 )
18 18
19 19 def setup():
20 20 def _manifestmerge(orig, repo, wctx, p2, pa, branchmerge, *args, **kwargs):
21 21 """Filter updates to only lay out files that match the narrow spec."""
22 22 actions, diverge, renamedelete = orig(
23 23 repo, wctx, p2, pa, branchmerge, *args, **kwargs)
24 24
25 25 if not util.safehasattr(repo, 'narrowmatch'):
26 26 return actions, diverge, renamedelete
27 27
28 28 nooptypes = set(['k']) # TODO: handle with nonconflicttypes
29 29 nonconflicttypes = set('a am c cm f g r e'.split())
30 30 narrowmatch = repo.narrowmatch()
31 for f, action in actions.items():
31 # We mutate the items in the dict during iteration, so iterate
32 # over a copy.
33 for f, action in list(actions.items()):
32 34 if narrowmatch(f):
33 35 pass
34 36 elif not branchmerge:
35 37 del actions[f] # just updating, ignore changes outside clone
36 38 elif action[0] in nooptypes:
37 39 del actions[f] # merge does not affect file
38 40 elif action[0] in nonconflicttypes:
39 41 raise error.Abort(_('merge affects file \'%s\' outside narrow, '
40 42 'which is not yet supported') % f,
41 43 hint=_('merging in the other direction '
42 44 'may work'))
43 45 else:
44 46 raise error.Abort(_('conflict in file \'%s\' is outside '
45 47 'narrow clone') % f)
46 48
47 49 return actions, diverge, renamedelete
48 50
49 51 extensions.wrapfunction(merge, 'manifestmerge', _manifestmerge)
50 52
51 53 def _checkcollision(orig, repo, wmf, actions):
52 54 if util.safehasattr(repo, 'narrowmatch'):
53 55 narrowmatch = repo.narrowmatch()
54 56 wmf = wmf.matches(narrowmatch)
55 57 if actions:
56 58 narrowactions = {}
57 59 for m, actionsfortype in actions.iteritems():
58 60 narrowactions[m] = []
59 61 for (f, args, msg) in actionsfortype:
60 62 if narrowmatch(f):
61 63 narrowactions[m].append((f, args, msg))
62 64 actions = narrowactions
63 65 return orig(repo, wmf, actions)
64 66
65 67 extensions.wrapfunction(merge, '_checkcollision', _checkcollision)
66 68
67 69 def _computenonoverlap(orig, repo, *args, **kwargs):
68 70 u1, u2 = orig(repo, *args, **kwargs)
69 71 if not util.safehasattr(repo, 'narrowmatch'):
70 72 return u1, u2
71 73
72 74 narrowmatch = repo.narrowmatch()
73 75 u1 = [f for f in u1 if narrowmatch(f)]
74 76 u2 = [f for f in u2 if narrowmatch(f)]
75 77 return u1, u2
76 78 extensions.wrapfunction(copies, '_computenonoverlap', _computenonoverlap)
General Comments 0
You need to be logged in to leave comments. Login now