Show More
@@ -134,7 +134,13 b' def _prepare_files(tr, ctx, error=False,' | |||||
134 | for s in salvaged: |
|
134 | for s in salvaged: | |
135 | files.mark_salvaged(s) |
|
135 | files.mark_salvaged(s) | |
136 |
|
136 | |||
137 | if ctx.manifestnode(): |
|
137 | narrow_files = {} | |
|
138 | if not ctx.repo().narrowmatch().always(): | |||
|
139 | for f, e in ms.allextras().items(): | |||
|
140 | action = e.get(b'outside-narrow-merge-action') | |||
|
141 | if action is not None: | |||
|
142 | narrow_files[f] = action | |||
|
143 | if ctx.manifestnode() and not narrow_files: | |||
138 | # reuse an existing manifest revision |
|
144 | # reuse an existing manifest revision | |
139 | repo.ui.debug(b'reusing known manifest\n') |
|
145 | repo.ui.debug(b'reusing known manifest\n') | |
140 | mn = ctx.manifestnode() |
|
146 | mn = ctx.manifestnode() | |
@@ -142,11 +148,11 b' def _prepare_files(tr, ctx, error=False,' | |||||
142 | if writechangesetcopy: |
|
148 | if writechangesetcopy: | |
143 | files.update_added(ctx.filesadded()) |
|
149 | files.update_added(ctx.filesadded()) | |
144 | files.update_removed(ctx.filesremoved()) |
|
150 | files.update_removed(ctx.filesremoved()) | |
145 | elif not ctx.files(): |
|
151 | elif not ctx.files() and not narrow_files: | |
146 | repo.ui.debug(b'reusing manifest from p1 (no file change)\n') |
|
152 | repo.ui.debug(b'reusing manifest from p1 (no file change)\n') | |
147 | mn = p1.manifestnode() |
|
153 | mn = p1.manifestnode() | |
148 | else: |
|
154 | else: | |
149 | mn = _process_files(tr, ctx, ms, files, error=error) |
|
155 | mn = _process_files(tr, ctx, ms, files, narrow_files, error=error) | |
150 |
|
156 | |||
151 | if origctx and origctx.manifestnode() == mn: |
|
157 | if origctx and origctx.manifestnode() == mn: | |
152 | origfiles = origctx.files() |
|
158 | origfiles = origctx.files() | |
@@ -177,7 +183,7 b' def _get_salvaged(repo, ms, ctx):' | |||||
177 | return salvaged |
|
183 | return salvaged | |
178 |
|
184 | |||
179 |
|
185 | |||
180 | def _process_files(tr, ctx, ms, files, error=False): |
|
186 | def _process_files(tr, ctx, ms, files, narrow_files=None, error=False): | |
181 | repo = ctx.repo() |
|
187 | repo = ctx.repo() | |
182 | p1 = ctx.p1() |
|
188 | p1 = ctx.p1() | |
183 | p2 = ctx.p2() |
|
189 | p2 = ctx.p2() | |
@@ -198,8 +204,24 b' def _process_files(tr, ctx, ms, files, e' | |||||
198 | linkrev = len(repo) |
|
204 | linkrev = len(repo) | |
199 | repo.ui.note(_(b"committing files:\n")) |
|
205 | repo.ui.note(_(b"committing files:\n")) | |
200 | uipathfn = scmutil.getuipathfn(repo) |
|
206 | uipathfn = scmutil.getuipathfn(repo) | |
201 |
|
|
207 | all_files = ctx.modified() + ctx.added() | |
|
208 | all_files.extend(narrow_files.keys()) | |||
|
209 | all_files.sort() | |||
|
210 | for f in all_files: | |||
202 | repo.ui.note(uipathfn(f) + b"\n") |
|
211 | repo.ui.note(uipathfn(f) + b"\n") | |
|
212 | if f in narrow_files: | |||
|
213 | narrow_action = narrow_files.get(f) | |||
|
214 | if narrow_action == mergestate.CHANGE_MODIFIED: | |||
|
215 | files.mark_touched(f) | |||
|
216 | added.append(f) | |||
|
217 | m[f] = m2[f] | |||
|
218 | flags = m2ctx.find(f)[1] or b'' | |||
|
219 | m.setflag(f, flags) | |||
|
220 | else: | |||
|
221 | msg = _(b"corrupted mergestate, unknown narrow action: %b") | |||
|
222 | hint = _(b"restart the merge") | |||
|
223 | raise error.Abort(msg, hint=hint) | |||
|
224 | continue | |||
203 | try: |
|
225 | try: | |
204 | fctx = ctx[f] |
|
226 | fctx = ctx[f] | |
205 | if fctx is None: |
|
227 | if fctx is None: | |
@@ -239,7 +261,17 b' def _process_files(tr, ctx, ms, files, e' | |||||
239 | if not rf(f): |
|
261 | if not rf(f): | |
240 | files.mark_removed(f) |
|
262 | files.mark_removed(f) | |
241 |
|
263 | |||
242 | mn = _commit_manifest(tr, linkrev, ctx, mctx, m, files.touched, added, drop) |
|
264 | mn = _commit_manifest( | |
|
265 | tr, | |||
|
266 | linkrev, | |||
|
267 | ctx, | |||
|
268 | mctx, | |||
|
269 | m, | |||
|
270 | files.touched, | |||
|
271 | added, | |||
|
272 | drop, | |||
|
273 | bool(narrow_files), | |||
|
274 | ) | |||
243 |
|
275 | |||
244 | return mn |
|
276 | return mn | |
245 |
|
277 | |||
@@ -409,7 +441,17 b' def _filecommit(' | |||||
409 | return fnode, touched |
|
441 | return fnode, touched | |
410 |
|
442 | |||
411 |
|
443 | |||
412 | def _commit_manifest(tr, linkrev, ctx, mctx, manifest, files, added, drop): |
|
444 | def _commit_manifest( | |
|
445 | tr, | |||
|
446 | linkrev, | |||
|
447 | ctx, | |||
|
448 | mctx, | |||
|
449 | manifest, | |||
|
450 | files, | |||
|
451 | added, | |||
|
452 | drop, | |||
|
453 | has_some_narrow_action=False, | |||
|
454 | ): | |||
413 | """make a new manifest entry (or reuse a new one) |
|
455 | """make a new manifest entry (or reuse a new one) | |
414 |
|
456 | |||
415 | given an initialised manifest context and precomputed list of |
|
457 | given an initialised manifest context and precomputed list of | |
@@ -451,6 +493,10 b' def _commit_manifest(tr, linkrev, ctx, m' | |||||
451 | # at this point is merges, and we already error out in the |
|
493 | # at this point is merges, and we already error out in the | |
452 | # case where the merge has files outside of the narrowspec, |
|
494 | # case where the merge has files outside of the narrowspec, | |
453 | # so this is safe. |
|
495 | # so this is safe. | |
|
496 | if has_some_narrow_action: | |||
|
497 | match = None | |||
|
498 | else: | |||
|
499 | match = repo.narrowmatch() | |||
454 | mn = mctx.write( |
|
500 | mn = mctx.write( | |
455 | tr, |
|
501 | tr, | |
456 | linkrev, |
|
502 | linkrev, | |
@@ -458,7 +504,7 b' def _commit_manifest(tr, linkrev, ctx, m' | |||||
458 | p2.manifestnode(), |
|
504 | p2.manifestnode(), | |
459 | added, |
|
505 | added, | |
460 | drop, |
|
506 | drop, | |
461 |
match= |
|
507 | match=match, | |
462 | ) |
|
508 | ) | |
463 | else: |
|
509 | else: | |
464 | repo.ui.debug( |
|
510 | repo.ui.debug( |
@@ -518,13 +518,23 b' def _filternarrowactions(narrowmatch, br' | |||||
518 | mresult.removefile(f) # just updating, ignore changes outside clone |
|
518 | mresult.removefile(f) # just updating, ignore changes outside clone | |
519 | elif action[0].no_op: |
|
519 | elif action[0].no_op: | |
520 | mresult.removefile(f) # merge does not affect file |
|
520 | mresult.removefile(f) # merge does not affect file | |
521 |
elif action[0].narrow_safe: |
|
521 | elif action[0].narrow_safe: | |
522 |
|
|
522 | if ( | |
523 | b'merge affects file \'%s\' outside narrow, ' |
|
523 | not f.endswith(b'/') | |
524 | b'which is not yet supported' |
|
524 | and action[0].changes == mergestatemod.CHANGE_MODIFIED | |
525 | ) |
|
525 | ): | |
526 | hint = _(b'merging in the other direction may work') |
|
526 | mresult.removefile(f) # merge won't affect on-disk files | |
527 | raise error.Abort(msg % f, hint=hint) |
|
527 | ||
|
528 | mresult.addcommitinfo( | |||
|
529 | f, b'outside-narrow-merge-action', action[0].changes | |||
|
530 | ) | |||
|
531 | else: # TODO: handle the tree case | |||
|
532 | msg = _( | |||
|
533 | b'merge affects file \'%s\' outside narrow, ' | |||
|
534 | b'which is not yet supported' | |||
|
535 | ) | |||
|
536 | hint = _(b'merging in the other direction may work') | |||
|
537 | raise error.Abort(msg % f, hint=hint) | |||
528 | else: |
|
538 | else: | |
529 | msg = _(b'conflict in file \'%s\' is outside narrow clone') |
|
539 | msg = _(b'conflict in file \'%s\' is outside narrow clone') | |
530 | raise error.StateError(msg % f) |
|
540 | raise error.StateError(msg % f) |
@@ -83,12 +83,67 b' Can merge conflicting changes inside nar' | |||||
83 | TODO: Can merge non-conflicting changes outside narrow spec |
|
83 | TODO: Can merge non-conflicting changes outside narrow spec | |
84 |
|
84 | |||
85 | $ hg update -q 'desc("modify inside/f1")' |
|
85 | $ hg update -q 'desc("modify inside/f1")' | |
|
86 | ||||
|
87 | #if flat | |||
|
88 | ||||
86 | $ hg merge 'desc("modify outside/f1")' |
|
89 | $ hg merge 'desc("modify outside/f1")' | |
87 | abort: merge affects file 'outside/f1' outside narrow, which is not yet supported (flat !) |
|
90 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
91 | (branch merge, don't forget to commit) | |||
|
92 | ||||
|
93 | status should be clean | |||
|
94 | ||||
|
95 | $ hg status | |||
|
96 | ? inside/f1.orig | |||
|
97 | ||||
|
98 | file out of the spec should still not be in the dirstate at all | |||
|
99 | ||||
|
100 | $ hg debugdirstate | grep outside/f1 | |||
|
101 | [1] | |||
|
102 | ||||
|
103 | Commit that merge | |||
|
104 | ||||
|
105 | $ hg ci -m 'merge from outside to inside' | |||
|
106 | ||||
|
107 | status should be clean | |||
|
108 | ||||
|
109 | $ hg status | |||
|
110 | ? inside/f1.orig | |||
|
111 | ||||
|
112 | file out of the spec should not be in the mergestate anymore | |||
|
113 | ||||
|
114 | $ hg debugmergestate | grep outside/f1 | |||
|
115 | [1] | |||
|
116 | ||||
|
117 | file out of the spec should still not be in the dirstate at all | |||
|
118 | ||||
|
119 | $ hg debugdirstate | grep outside/f1 | |||
|
120 | [1] | |||
|
121 | ||||
|
122 | The filenode used should come from p2 | |||
|
123 | ||||
|
124 | $ hg manifest --debug --rev . | grep outside/f1 | |||
|
125 | 83cd11431a3b2aff8a3995e5f27bcf33cdb5be98 644 outside/f1 | |||
|
126 | $ hg manifest --debug --rev 'p1(.)' | grep outside/f1 | |||
|
127 | c6b956c48be2cd4fa94be16002aba311143806fa 644 outside/f1 | |||
|
128 | $ hg manifest --debug --rev 'p2(.)' | grep outside/f1 | |||
|
129 | 83cd11431a3b2aff8a3995e5f27bcf33cdb5be98 644 outside/f1 | |||
|
130 | ||||
|
131 | ||||
|
132 | remove the commit to get in the previous situation again | |||
|
133 | ||||
|
134 | $ hg debugstrip -r . | |||
|
135 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
136 | saved backup bundle to $TESTTMP/narrow/.hg/strip-backup/48eb25338b19-a1bb8350-backup.hg | |||
|
137 | ||||
|
138 | #else | |||
|
139 | ||||
|
140 | $ hg merge 'desc("modify outside/f1")' | |||
88 |
abort: merge affects file 'outside |
|
141 | abort: merge affects file 'outside/' outside narrow, which is not yet supported (tree !) | |
89 | (merging in the other direction may work) |
|
142 | (merging in the other direction may work) | |
90 | [255] |
|
143 | [255] | |
91 |
|
144 | |||
|
145 | #endif | |||
|
146 | ||||
92 | $ hg update -q 'desc("modify outside/f1")' |
|
147 | $ hg update -q 'desc("modify outside/f1")' | |
93 | $ hg merge 'desc("modify inside/f1")' |
|
148 | $ hg merge 'desc("modify inside/f1")' | |
94 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
149 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
General Comments 0
You need to be logged in to leave comments.
Login now