##// END OF EJS Templates
narrow: allow merging non-conflicting change outside of the narrow spec...
marmoute -
r49565:f1eb77dc default
parent child Browse files
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 for f in sorted(ctx.modified() + ctx.added()):
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=repo.narrowmatch(),
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: # TODO: handle these cases
521 elif action[0].narrow_safe:
522 msg = _(
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/' outside narrow, which is not yet supported (tree !)
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