[PATCH 1 of 4 V3] filemerge: add `summarize()`
Phil Cohen
phillco at fb.com
Fri Mar 17 02:17:15 UTC 2017
# 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
More information about the Mercurial-devel
mailing list