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