[PATCH 1 of 4 V3] filemerge: add `summarize()`

Phil Cohen phillco at fb.com
Thu Mar 16 22:29:49 EDT 2017


Two things are new here since last time -- detecting absentfilectxs and 
the 'else' case that runs when the origfile is missing. Let me know if 
the assumption there holds.

The "look at the origfile" behavior (the "if" branch) came from the 
original code that launches the merge tool.

On 3/16/17 7:17 PM, Phil Cohen wrote:
> # HG changeset patch
> # User Phil Cohen <phillco at fb.com>
> # Date 1489716177 25200
> #      Thu Mar 16 19:02:57 2017 -0700
> # Node ID ad81d182e88ffd3da20364f18204facf6e7750a3
> # Parent  568d80b24b3a3e4e6874ac0d95ddee056fef14e4
> filemerge: add `summarize()`
>
> returns a dictionary of each version of a conflict, given the contexts
>
> diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
> --- a/mercurial/filemerge.py
> +++ b/mercurial/filemerge.py
> @@ -7,6 +7,7 @@
>
>  from __future__ import absolute_import
>
> +import copy
>  import filecmp
>  import os
>  import re
> @@ -567,6 +568,60 @@
>          "o": " [%s]" % labels[1],
>      }
>
> +def summarize(repo, workingfilectx, otherctx, basectx):
> +    origfile = None if workingfilectx.isabsent() else \
> +        scmutil.origpath(repo.ui, repo, repo.wjoin(workingfilectx.path()))
> +
> +    def flags(context):
> +        if isinstance(context, absentfilectx):
> +            return {'exists': False}
> +        return {
> +            'contents': context.data(),
> +            'exists': True,
> +            'isexec': context.isexec(),
> +            'issymlink': context.islink(),
> +        }
> +
> +    output = flags(workingfilectx)
> +
> +    if origfile and util.filestat(origfile).stat:
> +        # Since you can start a merge with a dirty working copy (either via
> +        # `up -n` or `merge -f`), "local" must reflect that, not the underlying
> +        # commit. Those contents are available in the .orig version, so we look
> +        # there and mock up the schema to look like the other contexts.
> +        local = {
> +            'contents': util.readfile(origfile),
> +            'exists': True,
> +            'isexec': util.isexec(origfile),
> +            'issymlink': util.statislink(util.filestat(origfile).stat),
> +        }
> +    else:
> +        # No backup file. This happens whenever the merge was esoteric enough
> +        # that we didn't launch a merge tool*, and instead prompted the user to
> +        # "use (c)hanged version, (d)elete, or leave (u)nresolved".
> +        #
> +        # The only way to exit that prompt with a conflict is to choose "u",
> +        # which leaves the local version in the working copy (with all its
> +        # pre-merge properties including any local changes), so we can reuse
> +        # that.
> +        #
> +        # Another alternative might be to use repo['.'][path] but that wouldn't
> +        # have any dirty pre-merge changes.
> +        #
> +        # *If we had, we'd've we would've overwritten the working copy, made a
> +        # backup and hit the above case.
> +        local = copy.copy(output)
> +
> +    output['path'] = repo.wjoin(workingfilectx.path())
> +
> +    return {
> +        'base': flags(basectx),
> +        'local': local,
> +        'other': flags(otherctx),
> +        'output': output,
> +        'path': workingfilectx.path(),
> +    }
> +
>  def _filemerge(premerge, repo, mynode, orig, fcd, fco, fca, labels=None):
>      """perform a 3-way merge in the working directory
>
> _______________________________________________
> 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=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=mx0opQh0kf4fCU4SUKtQ-w&m=zNEo24XeGP6uuFpeTZpDknUXdTs3odSRA4zQ58SSUxo&s=lmzkUhUGn-ONxybCITeUUIp5zDxXPo-qLupBGN19eGA&e=
>


More information about the Mercurial-devel mailing list