[PATCH 1 of 2] merge: use labels in prompts to the user

Simon Farnsworth simonfar at fb.com
Fri Aug 12 16:41:04 UTC 2016


I missed the v4 tag on this patchset.

I'm going to leave it for now - I'll resend next week if I see no review 
comments.

Simon

On 12/08/2016 14:50, Simon Farnsworth wrote:
> # HG changeset patch
> # User Simon Farnsworth <simonfar at fb.com>
> # Date 1471006902 25200
> #      Fri Aug 12 06:01:42 2016 -0700
> # Node ID 6d3af00243808b1be9f27a5545be0fce0e43d1f2
> # Parent  37b6f0ec6241a62de90737409458cd622e2fac0d
> 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.
>
> diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
> --- a/mercurial/filemerge.py
> +++ b/mercurial/filemerge.py
> @@ -230,50 +230,56 @@
>                  util.writefile(file, newdata)
>
>  @internaltool('prompt', nomerge)
> -def _iprompt(repo, mynode, orig, fcd, fco, fca, toolconf):
> +def _iprompt(repo, mynode, orig, fcd, fco, fca, toolconf, labels=None):
>      """Asks the user which of the local `p1()` or the other `p2()` version to
>      keep as the merged version."""
>      ui = repo.ui
>      fd = fcd.path()
>
> +    prompts = partextras(labels)
> +    prompts['fd'] = fd
>      try:
>          if fco.isabsent():
>              index = ui.promptchoice(
> -                _("local changed %s which remote deleted\n"
> +                _("local%(l)s changed %(fd)s which remote%(o)s deleted\n"
>                    "use (c)hanged version, (d)elete, or leave (u)nresolved?"
> -                  "$$ &Changed $$ &Delete $$ &Unresolved") % fd, 2)
> +                  "$$ &Changed $$ &Delete $$ &Unresolved") % prompts, 2)
>              choice = ['local', 'other', 'unresolved'][index]
>          elif fcd.isabsent():
>              index = ui.promptchoice(
> -                _("remote changed %s which local deleted\n"
> +                _("remote%(o)s changed %(fd)s which local%(l)s deleted\n"
>                    "use (c)hanged version, leave (d)eleted, or "
>                    "leave (u)nresolved?"
> -                  "$$ &Changed $$ &Deleted $$ &Unresolved") % fd, 2)
> +                  "$$ &Changed $$ &Deleted $$ &Unresolved") % prompts, 2)
>              choice = ['other', 'local', 'unresolved'][index]
>          else:
>              index = ui.promptchoice(
> -                _("no tool found to merge %s\n"
> -                  "keep (l)ocal, take (o)ther, or leave (u)nresolved?"
> -                  "$$ &Local $$ &Other $$ &Unresolved") % fd, 2)
> +                _("no tool found to merge %(fd)s\n"
> +                  "keep (l)ocal%(l)s, take (o)ther%(o)s, or leave (u)nresolved?"
> +                  "$$ &Local $$ &Other $$ &Unresolved") % prompts, 2)
>              choice = ['local', 'other', 'unresolved'][index]
>
>          if choice == 'other':
> -            return _iother(repo, mynode, orig, fcd, fco, fca, toolconf)
> +            return _iother(repo, mynode, orig, fcd, fco, fca, toolconf,
> +                           labels)
>          elif choice == 'local':
> -            return _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf)
> +            return _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf,
> +                           labels)
>          elif choice == 'unresolved':
> -            return _ifail(repo, mynode, orig, fcd, fco, fca, toolconf)
> +            return _ifail(repo, mynode, orig, fcd, fco, fca, toolconf,
> +                          labels)
>      except error.ResponseExpected:
>          ui.write("\n")
> -        return _ifail(repo, mynode, orig, fcd, fco, fca, toolconf)
> +        return _ifail(repo, mynode, orig, fcd, fco, fca, toolconf,
> +                      labels)
>
>  @internaltool('local', nomerge)
> -def _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf):
> +def _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf, labels=None):
>      """Uses the local `p1()` version of files as the merged version."""
>      return 0, fcd.isabsent()
>
>  @internaltool('other', nomerge)
> -def _iother(repo, mynode, orig, fcd, fco, fca, toolconf):
> +def _iother(repo, mynode, orig, fcd, fco, fca, toolconf, labels=None):
>      """Uses the other `p2()` version of files as the merged version."""
>      if fco.isabsent():
>          # local changed, remote deleted -- 'deleted' picked
> @@ -285,7 +291,7 @@
>      return 0, deleted
>
>  @internaltool('fail', nomerge)
> -def _ifail(repo, mynode, orig, fcd, fco, fca, toolconf):
> +def _ifail(repo, mynode, orig, fcd, fco, fca, toolconf, labels=None):
>      """
>      Rather than attempting to merge files that were modified on both
>      branches, it marks them as unresolved. The resolve command must be
> @@ -537,6 +543,22 @@
>          newlabels.append(_formatconflictmarker(repo, ca, tmpl, labels[2], pad))
>      return newlabels
>
> +def partextras(labels):
> +    """Return a dictionary of extra labels for use in prompts to the user
> +
> +    Intended use is in strings of the form "(l)ocal%(l)s".
> +    """
> +    if labels is None:
> +        return {
> +            "l": "",
> +            "o": "",
> +        }
> +
> +    return {
> +        "l": " [%s]" % labels[0],
> +        "o": " [%s]" % labels[1],
> +    }
> +
>  def _filemerge(premerge, repo, mynode, orig, fcd, fco, fca, labels=None):
>      """perform a 3-way merge in the working directory
>
> @@ -588,7 +610,7 @@
>      toolconf = tool, toolpath, binary, symlink
>
>      if mergetype == nomerge:
> -        r, deleted = func(repo, mynode, orig, fcd, fco, fca, toolconf)
> +        r, deleted = func(repo, mynode, orig, fcd, fco, fca, toolconf, labels)
>          return True, r, deleted
>
>      if premerge:
> diff --git a/mercurial/merge.py b/mercurial/merge.py
> --- a/mercurial/merge.py
> +++ b/mercurial/merge.py
> @@ -1535,11 +1535,13 @@
>          if '.hgsubstate' in actionbyfile:
>              f = '.hgsubstate'
>              m, args, msg = actionbyfile[f]
> +            prompts = filemerge.partextras(labels)
> +            prompts['f'] = f
>              if m == 'cd':
>                  if repo.ui.promptchoice(
> -                    _("local changed %s which remote deleted\n"
> +                    _("local%(l)s changed %(f)s which remote%(o)s deleted\n"
>                        "use (c)hanged version or (d)elete?"
> -                      "$$ &Changed $$ &Delete") % f, 0):
> +                      "$$ &Changed $$ &Delete") % prompts, 0):
>                      actionbyfile[f] = ('r', None, "prompt delete")
>                  elif f in p1:
>                      actionbyfile[f] = ('am', None, "prompt keep")
> @@ -1549,9 +1551,9 @@
>                  f1, f2, fa, move, anc = args
>                  flags = p2[f2].flags()
>                  if repo.ui.promptchoice(
> -                    _("remote changed %s which local deleted\n"
> +                    _("remote%(o)s changed %(f)s which local%(l)s deleted\n"
>                        "use (c)hanged version or leave (d)eleted?"
> -                      "$$ &Changed $$ &Deleted") % f, 0) == 0:
> +                      "$$ &Changed $$ &Deleted") % prompts, 0) == 0:
>                      actionbyfile[f] = ('g', (flags, False), "prompt recreating")
>                  else:
>                      del actionbyfile[f]
> diff --git a/tests/failfilemerge.py b/tests/failfilemerge.py
> --- a/tests/failfilemerge.py
> +++ b/tests/failfilemerge.py
> @@ -9,7 +9,7 @@
>  )
>
>  def failfilemerge(filemergefn,
> -        premerge, repo, mynode, orig, fcd, fco, fca, labels=None):
> +                  premerge, repo, mynode, orig, fcd, fco, fca, labels=None):
>      raise error.Abort("^C")
>      return filemergefn(premerge, repo, mynode, orig, fcd, fco, fca, labels)
>
> diff --git a/tests/test-copy-move-merge.t b/tests/test-copy-move-merge.t
> --- a/tests/test-copy-move-merge.t
> +++ b/tests/test-copy-move-merge.t
> @@ -85,7 +85,7 @@
>    > c
>    > EOF
>    rebasing 2:add3f11052fa "other" (tip)
> -  remote changed a which local deleted
> +  remote [source] changed a which local [dest] deleted
>    use (c)hanged version, leave (d)eleted, or leave (u)nresolved? c
>
>    $ cat b
> diff --git a/tests/test-largefiles-update.t b/tests/test-largefiles-update.t
> --- a/tests/test-largefiles-update.t
> +++ b/tests/test-largefiles-update.t
> @@ -611,7 +611,7 @@
>    > EOF
>    rebasing 1:72518492caa6 "#1"
>    rebasing 4:07d6153b5c04 "#4"
> -  local changed .hglf/large1 which remote deleted
> +  local [dest] changed .hglf/large1 which remote [source] deleted
>    use (c)hanged version, (d)elete, or leave (u)nresolved? c
>
>    $ hg diff -c "tip~1" --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
> diff --git a/tests/test-merge-changedelete.t b/tests/test-merge-changedelete.t
> --- a/tests/test-merge-changedelete.t
> +++ b/tests/test-merge-changedelete.t
> @@ -717,9 +717,9 @@
>    $ echo changed >> file1
>    $ hg rm file2
>    $ hg update 1 -y
> -  local changed file1 which remote deleted
> +  local [working copy] changed file1 which remote [destination] deleted
>    use (c)hanged version, (d)elete, or leave (u)nresolved? u
> -  remote changed file2 which local deleted
> +  remote [destination] changed file2 which local [working copy] deleted
>    use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
>    1 files updated, 0 files merged, 0 files removed, 2 files unresolved
>    use 'hg resolve' to retry unresolved file merges
> @@ -893,9 +893,9 @@
>    $ echo changed >> file1
>    $ hg rm file2
>    $ hg update 1 --config ui.interactive=True --tool :prompt
> -  local changed file1 which remote deleted
> +  local [working copy] changed file1 which remote [destination] deleted
>    use (c)hanged version, (d)elete, or leave (u)nresolved?
> -  remote changed file2 which local deleted
> +  remote [destination] changed file2 which local [working copy] deleted
>    use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
>    1 files updated, 0 files merged, 0 files removed, 2 files unresolved
>    use 'hg resolve' to retry unresolved file merges
> @@ -943,9 +943,9 @@
>    $ echo changed >> file1
>    $ hg rm file2
>    $ hg update 1 --tool :merge3
> -  local changed file1 which remote deleted
> +  local [working copy] changed file1 which remote [destination] deleted
>    use (c)hanged version, (d)elete, or leave (u)nresolved? u
> -  remote changed file2 which local deleted
> +  remote [destination] changed file2 which local [working copy] deleted
>    use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
>    1 files updated, 0 files merged, 0 files removed, 2 files unresolved
>    use 'hg resolve' to retry unresolved file merges
> @@ -999,9 +999,9 @@
>    (status identical)
>
>    === :other -> :prompt ===
> -  local changed file1 which remote deleted
> +  local [working copy] changed file1 which remote [destination] deleted
>    use (c)hanged version, (d)elete, or leave (u)nresolved?
> -  remote changed file2 which local deleted
> +  remote [destination] changed file2 which local [working copy] deleted
>    use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
>    --- diff of status ---
>    (status identical)
> @@ -1026,9 +1026,9 @@
>    (status identical)
>
>    === :local -> :prompt ===
> -  local changed file1 which remote deleted
> +  local [working copy] changed file1 which remote [destination] deleted
>    use (c)hanged version, (d)elete, or leave (u)nresolved?
> -  remote changed file2 which local deleted
> +  remote [destination] changed file2 which local [working copy] deleted
>    use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
>    --- diff of status ---
>    (status identical)
> @@ -1043,9 +1043,9 @@
>    (status identical)
>
>    === :fail -> :prompt ===
> -  local changed file1 which remote deleted
> +  local [working copy] changed file1 which remote [destination] deleted
>    use (c)hanged version, (d)elete, or leave (u)nresolved?
> -  remote changed file2 which local deleted
> +  remote [destination] changed file2 which local [working copy] deleted
>    use (c)hanged version, leave (d)eleted, or leave (u)nresolved?
>    --- diff of status ---
>    (status identical)
> diff --git a/tests/test-merge-types.t b/tests/test-merge-types.t
> --- a/tests/test-merge-types.t
> +++ b/tests/test-merge-types.t
> @@ -173,7 +173,7 @@
>    (couldn't find merge tool hgmerge|tool hgmerge can't handle symlinks) (re)
>    picked tool ':prompt' for a (binary False symlink True changedelete False)
>    no tool found to merge a
> -  keep (l)ocal, take (o)ther, or leave (u)nresolved? u
> +  keep (l)ocal [working copy], take (o)ther [destination], or leave (u)nresolved? u
>    0 files updated, 0 files merged, 0 files removed, 1 files unresolved
>    use 'hg resolve' to retry unresolved file merges
>    1 other heads for branch "default"
> diff --git a/tests/test-rebase-newancestor.t b/tests/test-rebase-newancestor.t
> --- a/tests/test-rebase-newancestor.t
> +++ b/tests/test-rebase-newancestor.t
> @@ -135,7 +135,7 @@
>    note: rebase of 1:1d1a643d390e created no changes to commit
>    rebasing 2:ec2c14fb2984 "dev: f-dev stuff"
>    rebasing 4:4b019212aaf6 "dev: merge default"
> -  remote changed f-default which local deleted
> +  remote [source] changed f-default which local [dest] deleted
>    use (c)hanged version, leave (d)eleted, or leave (u)nresolved? c
>    rebasing 6:9455ee510502 "dev: merge default"
>    saved backup bundle to $TESTTMP/ancestor-merge/.hg/strip-backup/1d1a643d390e-43e9e04b-backup.hg (glob)
> @@ -164,7 +164,7 @@
>    > EOF
>    rebasing 2:ec2c14fb2984 "dev: f-dev stuff"
>    rebasing 4:4b019212aaf6 "dev: merge default"
> -  remote changed f-default which local deleted
> +  remote [source] changed f-default which local [dest] deleted
>    use (c)hanged version, leave (d)eleted, or leave (u)nresolved? c
>    rebasing 6:9455ee510502 "dev: merge default"
>    saved backup bundle to $TESTTMP/ancestor-merge-2/.hg/strip-backup/ec2c14fb2984-62d0b222-backup.hg (glob)
> diff --git a/tests/test-subrepo-missing.t b/tests/test-subrepo-missing.t
> --- a/tests/test-subrepo-missing.t
> +++ b/tests/test-subrepo-missing.t
> @@ -62,7 +62,7 @@
>    2 files updated, 0 files merged, 0 files removed, 0 files unresolved
>    $ rm .hgsubstate
>    $ hg up 0
> -  remote changed .hgsubstate which local deleted
> +  remote [destination] changed .hgsubstate which local [working copy] deleted
>    use (c)hanged version or leave (d)eleted? c
>    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
>    $ hg st
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mercurial-2Dscm.org_mailman_listinfo_mercurial-2Ddevel&d=CwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=mEgSWILcY4c4W3zjApBQLA&m=VIhAb2OCGLvrWY-7ln1AMUdy2Ysigpo2Fx2RL_fhGXw&s=ejYlRS5ya-vExpQ-7rMQjv68I0VL-HaOfVDbhMkYl8w&e=
>

-- 
Simon Farnsworth



More information about the Mercurial-devel mailing list