mercurial/filemerge.py
author Matt Mackall <mpm@selenic.com>
Sun, 03 Feb 2008 19:29:05 -0600
changeset 6003 7855b88ba838
child 6004 5af5f0f9d724
permissions -rw-r--r--
filemerge: pull file-merging code into its own module
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# filemerge.py - file-level merge handling for Mercurial
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
from node import *
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     9
from i18n import _
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    10
import util, os, tempfile, context
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    11
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
def filemerge(repo, fw, fd, fo, wctx, mctx):
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
    """perform a 3-way merge in the working directory
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
    fw = original filename in the working directory
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    16
    fd = destination filename in the working directory
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
    fo = filename in other parent
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
    wctx, mctx = working and merge changecontexts
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
    """
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
    def temp(prefix, ctx):
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
        pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
        (fd, name) = tempfile.mkstemp(prefix=pre)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
        data = repo.wwritedata(ctx.path(), ctx.data())
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
        f = os.fdopen(fd, "wb")
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
        f.write(data)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    27
        f.close()
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    28
        return name
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
    fcm = wctx.filectx(fw)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
    fcmdata = wctx.filectx(fd).data()
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
    fco = mctx.filectx(fo)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
    if not fco.cmp(fcmdata): # files identical?
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
        return None
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
    fca = fcm.ancestor(fco)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
    if not fca:
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
        fca = repo.filectx(fw, fileid=nullrev)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    40
    a = repo.wjoin(fd)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    41
    b = temp("base", fca)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
    c = temp("other", fco)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    44
    if fw != fo:
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
        repo.ui.status(_("merging %s and %s\n") % (fw, fo))
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
    else:
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
        repo.ui.status(_("merging %s\n") % fw)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
    repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca))
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
    cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge")
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
           or "hgmerge")
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
    r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root,
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    54
                    environ={'HG_FILE': fd,
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
                             'HG_MY_NODE': str(wctx.parents()[0]),
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
                             'HG_OTHER_NODE': str(mctx),
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
                             'HG_MY_ISLINK': fcm.islink(),
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
                             'HG_OTHER_ISLINK': fco.islink(),
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
                             'HG_BASE_ISLINK': fca.islink(),})
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
    if r:
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
        repo.ui.warn(_("merging %s failed!\n") % fd)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
    os.unlink(b)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
    os.unlink(c)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
    return r