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