Mercurial > public > mercurial-scm > hg
comparison mercurial/filemerge.py @ 29774:a7f8939641aa
merge: use labels in prompts to the user
Now that we persist the labels, we can consistently use the labels in
prompts for the user without risk of confusion. This changes a huge amount
of command output:
This means that merge prompts like:
no tool found to merge a
keep (l)ocal, take (o)ther, or leave (u)nresolved? u
and
remote changed a which local deleted
use (c)hanged version, leave (d)eleted, or leave (u)nresolved? c
become:
no tool found to merge a
keep (l)ocal [working copy], take (o)ther [destination], or leave (u)nresolved? u
and
remote [source] changed a which local [dest] deleted
use (c)hanged version, leave (d)eleted, or leave (u)nresolved? c
where "working copy" and "destination" were supplied by the command that
requested the merge as labels for conflict markers, and thus should be
human-friendly.
author | Simon Farnsworth <simonfar@fb.com> |
---|---|
date | Fri, 12 Aug 2016 06:01:42 -0700 |
parents | 99b50346b750 |
children | 978b907d9b36 |
comparison
equal
deleted
inserted
replaced
29773:f2241c13d5a1 | 29774:a7f8939641aa |
---|---|
228 newdata = data.replace(style, tostyle) | 228 newdata = data.replace(style, tostyle) |
229 if newdata != data: | 229 if newdata != data: |
230 util.writefile(file, newdata) | 230 util.writefile(file, newdata) |
231 | 231 |
232 @internaltool('prompt', nomerge) | 232 @internaltool('prompt', nomerge) |
233 def _iprompt(repo, mynode, orig, fcd, fco, fca, toolconf): | 233 def _iprompt(repo, mynode, orig, fcd, fco, fca, toolconf, labels=None): |
234 """Asks the user which of the local `p1()` or the other `p2()` version to | 234 """Asks the user which of the local `p1()` or the other `p2()` version to |
235 keep as the merged version.""" | 235 keep as the merged version.""" |
236 ui = repo.ui | 236 ui = repo.ui |
237 fd = fcd.path() | 237 fd = fcd.path() |
238 | 238 |
239 prompts = partextras(labels) | |
240 prompts['fd'] = fd | |
239 try: | 241 try: |
240 if fco.isabsent(): | 242 if fco.isabsent(): |
241 index = ui.promptchoice( | 243 index = ui.promptchoice( |
242 _("local changed %s which remote deleted\n" | 244 _("local%(l)s changed %(fd)s which remote%(o)s deleted\n" |
243 "use (c)hanged version, (d)elete, or leave (u)nresolved?" | 245 "use (c)hanged version, (d)elete, or leave (u)nresolved?" |
244 "$$ &Changed $$ &Delete $$ &Unresolved") % fd, 2) | 246 "$$ &Changed $$ &Delete $$ &Unresolved") % prompts, 2) |
245 choice = ['local', 'other', 'unresolved'][index] | 247 choice = ['local', 'other', 'unresolved'][index] |
246 elif fcd.isabsent(): | 248 elif fcd.isabsent(): |
247 index = ui.promptchoice( | 249 index = ui.promptchoice( |
248 _("remote changed %s which local deleted\n" | 250 _("remote%(o)s changed %(fd)s which local%(l)s deleted\n" |
249 "use (c)hanged version, leave (d)eleted, or " | 251 "use (c)hanged version, leave (d)eleted, or " |
250 "leave (u)nresolved?" | 252 "leave (u)nresolved?" |
251 "$$ &Changed $$ &Deleted $$ &Unresolved") % fd, 2) | 253 "$$ &Changed $$ &Deleted $$ &Unresolved") % prompts, 2) |
252 choice = ['other', 'local', 'unresolved'][index] | 254 choice = ['other', 'local', 'unresolved'][index] |
253 else: | 255 else: |
254 index = ui.promptchoice( | 256 index = ui.promptchoice( |
255 _("no tool found to merge %s\n" | 257 _("no tool found to merge %(fd)s\n" |
256 "keep (l)ocal, take (o)ther, or leave (u)nresolved?" | 258 "keep (l)ocal%(l)s, take (o)ther%(o)s, or leave (u)nresolved?" |
257 "$$ &Local $$ &Other $$ &Unresolved") % fd, 2) | 259 "$$ &Local $$ &Other $$ &Unresolved") % prompts, 2) |
258 choice = ['local', 'other', 'unresolved'][index] | 260 choice = ['local', 'other', 'unresolved'][index] |
259 | 261 |
260 if choice == 'other': | 262 if choice == 'other': |
261 return _iother(repo, mynode, orig, fcd, fco, fca, toolconf) | 263 return _iother(repo, mynode, orig, fcd, fco, fca, toolconf, |
264 labels) | |
262 elif choice == 'local': | 265 elif choice == 'local': |
263 return _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf) | 266 return _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf, |
267 labels) | |
264 elif choice == 'unresolved': | 268 elif choice == 'unresolved': |
265 return _ifail(repo, mynode, orig, fcd, fco, fca, toolconf) | 269 return _ifail(repo, mynode, orig, fcd, fco, fca, toolconf, |
270 labels) | |
266 except error.ResponseExpected: | 271 except error.ResponseExpected: |
267 ui.write("\n") | 272 ui.write("\n") |
268 return _ifail(repo, mynode, orig, fcd, fco, fca, toolconf) | 273 return _ifail(repo, mynode, orig, fcd, fco, fca, toolconf, |
274 labels) | |
269 | 275 |
270 @internaltool('local', nomerge) | 276 @internaltool('local', nomerge) |
271 def _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf): | 277 def _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf, labels=None): |
272 """Uses the local `p1()` version of files as the merged version.""" | 278 """Uses the local `p1()` version of files as the merged version.""" |
273 return 0, fcd.isabsent() | 279 return 0, fcd.isabsent() |
274 | 280 |
275 @internaltool('other', nomerge) | 281 @internaltool('other', nomerge) |
276 def _iother(repo, mynode, orig, fcd, fco, fca, toolconf): | 282 def _iother(repo, mynode, orig, fcd, fco, fca, toolconf, labels=None): |
277 """Uses the other `p2()` version of files as the merged version.""" | 283 """Uses the other `p2()` version of files as the merged version.""" |
278 if fco.isabsent(): | 284 if fco.isabsent(): |
279 # local changed, remote deleted -- 'deleted' picked | 285 # local changed, remote deleted -- 'deleted' picked |
280 repo.wvfs.unlinkpath(fcd.path()) | 286 repo.wvfs.unlinkpath(fcd.path()) |
281 deleted = True | 287 deleted = True |
283 repo.wwrite(fcd.path(), fco.data(), fco.flags()) | 289 repo.wwrite(fcd.path(), fco.data(), fco.flags()) |
284 deleted = False | 290 deleted = False |
285 return 0, deleted | 291 return 0, deleted |
286 | 292 |
287 @internaltool('fail', nomerge) | 293 @internaltool('fail', nomerge) |
288 def _ifail(repo, mynode, orig, fcd, fco, fca, toolconf): | 294 def _ifail(repo, mynode, orig, fcd, fco, fca, toolconf, labels=None): |
289 """ | 295 """ |
290 Rather than attempting to merge files that were modified on both | 296 Rather than attempting to merge files that were modified on both |
291 branches, it marks them as unresolved. The resolve command must be | 297 branches, it marks them as unresolved. The resolve command must be |
292 used to resolve these conflicts.""" | 298 used to resolve these conflicts.""" |
293 # for change/delete conflicts write out the changed version, then fail | 299 # for change/delete conflicts write out the changed version, then fail |
535 _formatconflictmarker(repo, co, tmpl, labels[1], pad)] | 541 _formatconflictmarker(repo, co, tmpl, labels[1], pad)] |
536 if len(labels) > 2: | 542 if len(labels) > 2: |
537 newlabels.append(_formatconflictmarker(repo, ca, tmpl, labels[2], pad)) | 543 newlabels.append(_formatconflictmarker(repo, ca, tmpl, labels[2], pad)) |
538 return newlabels | 544 return newlabels |
539 | 545 |
546 def partextras(labels): | |
547 """Return a dictionary of extra labels for use in prompts to the user | |
548 | |
549 Intended use is in strings of the form "(l)ocal%(l)s". | |
550 """ | |
551 if labels is None: | |
552 return { | |
553 "l": "", | |
554 "o": "", | |
555 } | |
556 | |
557 return { | |
558 "l": " [%s]" % labels[0], | |
559 "o": " [%s]" % labels[1], | |
560 } | |
561 | |
540 def _filemerge(premerge, repo, mynode, orig, fcd, fco, fca, labels=None): | 562 def _filemerge(premerge, repo, mynode, orig, fcd, fco, fca, labels=None): |
541 """perform a 3-way merge in the working directory | 563 """perform a 3-way merge in the working directory |
542 | 564 |
543 premerge = whether this is a premerge | 565 premerge = whether this is a premerge |
544 mynode = parent node before merge | 566 mynode = parent node before merge |
586 precheck = None | 608 precheck = None |
587 | 609 |
588 toolconf = tool, toolpath, binary, symlink | 610 toolconf = tool, toolpath, binary, symlink |
589 | 611 |
590 if mergetype == nomerge: | 612 if mergetype == nomerge: |
591 r, deleted = func(repo, mynode, orig, fcd, fco, fca, toolconf) | 613 r, deleted = func(repo, mynode, orig, fcd, fco, fca, toolconf, labels) |
592 return True, r, deleted | 614 return True, r, deleted |
593 | 615 |
594 if premerge: | 616 if premerge: |
595 if orig != fco.path(): | 617 if orig != fco.path(): |
596 ui.status(_("merging %s and %s to %s\n") % (orig, fco.path(), fd)) | 618 ui.status(_("merging %s and %s to %s\n") % (orig, fco.path(), fd)) |