Show More
@@ -134,7 +134,13 b' def _prepare_files(tr, ctx, error=False,' | |||
|
134 | 134 | for s in salvaged: |
|
135 | 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 | 144 | # reuse an existing manifest revision |
|
139 | 145 | repo.ui.debug(b'reusing known manifest\n') |
|
140 | 146 | mn = ctx.manifestnode() |
@@ -142,11 +148,11 b' def _prepare_files(tr, ctx, error=False,' | |||
|
142 | 148 | if writechangesetcopy: |
|
143 | 149 | files.update_added(ctx.filesadded()) |
|
144 | 150 | files.update_removed(ctx.filesremoved()) |
|
145 | elif not ctx.files(): | |
|
151 | elif not ctx.files() and not narrow_files: | |
|
146 | 152 | repo.ui.debug(b'reusing manifest from p1 (no file change)\n') |
|
147 | 153 | mn = p1.manifestnode() |
|
148 | 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 | 157 | if origctx and origctx.manifestnode() == mn: |
|
152 | 158 | origfiles = origctx.files() |
@@ -177,7 +183,7 b' def _get_salvaged(repo, ms, ctx):' | |||
|
177 | 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 | 187 | repo = ctx.repo() |
|
182 | 188 | p1 = ctx.p1() |
|
183 | 189 | p2 = ctx.p2() |
@@ -198,8 +204,24 b' def _process_files(tr, ctx, ms, files, e' | |||
|
198 | 204 | linkrev = len(repo) |
|
199 | 205 | repo.ui.note(_(b"committing files:\n")) |
|
200 | 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 | 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 | 225 | try: |
|
204 | 226 | fctx = ctx[f] |
|
205 | 227 | if fctx is None: |
@@ -239,7 +261,17 b' def _process_files(tr, ctx, ms, files, e' | |||
|
239 | 261 | if not rf(f): |
|
240 | 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 | 276 | return mn |
|
245 | 277 | |
@@ -409,7 +441,17 b' def _filecommit(' | |||
|
409 | 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 | 455 | """make a new manifest entry (or reuse a new one) |
|
414 | 456 | |
|
415 | 457 | given an initialised manifest context and precomputed list of |
@@ -451,6 +493,10 b' def _commit_manifest(tr, linkrev, ctx, m' | |||
|
451 | 493 | # at this point is merges, and we already error out in the |
|
452 | 494 | # case where the merge has files outside of the narrowspec, |
|
453 | 495 | # so this is safe. |
|
496 | if has_some_narrow_action: | |
|
497 | match = None | |
|
498 | else: | |
|
499 | match = repo.narrowmatch() | |
|
454 | 500 | mn = mctx.write( |
|
455 | 501 | tr, |
|
456 | 502 | linkrev, |
@@ -458,7 +504,7 b' def _commit_manifest(tr, linkrev, ctx, m' | |||
|
458 | 504 | p2.manifestnode(), |
|
459 | 505 | added, |
|
460 | 506 | drop, |
|
461 |
match= |
|
|
507 | match=match, | |
|
462 | 508 | ) |
|
463 | 509 | else: |
|
464 | 510 | repo.ui.debug( |
@@ -518,13 +518,23 b' def _filternarrowactions(narrowmatch, br' | |||
|
518 | 518 | mresult.removefile(f) # just updating, ignore changes outside clone |
|
519 | 519 | elif action[0].no_op: |
|
520 | 520 | mresult.removefile(f) # merge does not affect file |
|
521 |
elif action[0].narrow_safe: |
|
|
522 |
|
|
|
523 | b'merge affects file \'%s\' outside narrow, ' | |
|
524 | b'which is not yet supported' | |
|
525 | ) | |
|
526 | hint = _(b'merging in the other direction may work') | |
|
527 | raise error.Abort(msg % f, hint=hint) | |
|
521 | elif action[0].narrow_safe: | |
|
522 | if ( | |
|
523 | not f.endswith(b'/') | |
|
524 | and action[0].changes == mergestatemod.CHANGE_MODIFIED | |
|
525 | ): | |
|
526 | mresult.removefile(f) # merge won't affect on-disk files | |
|
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 | 538 | else: |
|
529 | 539 | msg = _(b'conflict in file \'%s\' is outside narrow clone') |
|
530 | 540 | raise error.StateError(msg % f) |
@@ -83,12 +83,67 b' Can merge conflicting changes inside nar' | |||
|
83 | 83 | TODO: Can merge non-conflicting changes outside narrow spec |
|
84 | 84 | |
|
85 | 85 | $ hg update -q 'desc("modify inside/f1")' |
|
86 | ||
|
87 | #if flat | |
|
88 | ||
|
86 | 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 | 141 |
abort: merge affects file 'outside |
|
89 | 142 | (merging in the other direction may work) |
|
90 | 143 | [255] |
|
91 | 144 | |
|
145 | #endif | |
|
146 | ||
|
92 | 147 | $ hg update -q 'desc("modify outside/f1")' |
|
93 | 148 | $ hg merge 'desc("modify inside/f1")' |
|
94 | 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