mercurial/merge.py
author Matt Mackall <mpm@selenic.com>
Sun, 08 Oct 2006 19:57:45 -0500
changeset 3292 764688cf51e5
parent 3252 ae85272b59a4
child 3295 72d1e521da77
permissions -rw-r--r--
merge: remember rename copies and parents properly on commit record copies in dirstate even if rename was remote this lets us record it properly at commit teach checkfilemerge about copies, including merge cases pull old copy code out of commit extend rename-merge1 test to show file index
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# merge.py - directory-level update/merge handling for Mercurial
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2006 Matt Mackall <mpm@selenic.com>
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
from node import *
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     9
from i18n import gettext as _
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    10
from demandload import *
3018
db3f42261452 fix errors reported by pychecker
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2978
diff changeset
    11
demandload(globals(), "errno util os tempfile")
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
3211
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    13
def filemerge(repo, fw, fo, fd, my, other, p1, p2, move):
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    14
    """perform a 3-way merge in the working directory
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
3211
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    16
    fw = filename in the working directory and first parent
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    17
    fo = filename in other parent
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    18
    fd = destination filename
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    19
    my = fileid in first parent
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    20
    other = fileid in second parent
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    21
    p1, p2 = hex changeset ids for merge command
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    22
    move = whether to move or copy the file to the destination
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    23
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    24
    TODO:
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    25
      if fw is copied in the working directory, we get confused
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    26
      implement move and fd
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    27
    """
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    28
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    29
    def temp(prefix, ctx):
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    30
        pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
        (fd, name) = tempfile.mkstemp(prefix=pre)
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
        f = os.fdopen(fd, "wb")
3211
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    33
        repo.wwrite(ctx.path(), ctx.data(), f)
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
        f.close()
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
        return name
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
3211
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    37
    fcm = repo.filectx(fw, fileid=my)
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    38
    fco = repo.filectx(fo, fileid=other)
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    39
    fca = fcm.ancestor(fco)
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    40
    if not fca:
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    41
        fca = repo.filectx(fw, fileid=-1)
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    42
    a = repo.wjoin(fw)
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    43
    b = temp("base", fca)
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    44
    c = temp("other", fco)
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
3211
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    46
    repo.ui.note(_("resolving %s\n") % fw)
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    47
    repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca))
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
    cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge")
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
           or "hgmerge")
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
    r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root,
3211
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    52
                    environ={'HG_FILE': fw,
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
                             'HG_MY_NODE': p1,
3211
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    54
                             'HG_OTHER_NODE': p2})
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
    if r:
3211
3fd098e0902d merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents: 3169
diff changeset
    56
        repo.ui.warn(_("merging %s failed!\n") % fw)
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
    57
    else:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
    58
        if fd != fw:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
    59
            repo.ui.debug(_("copying %s to %s\n") % (fw, fd))
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
    60
            repo.wwrite(fd, repo.wread(fw))
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
    61
            if move:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
    62
                repo.ui.debug(_("removing %s\n") % fw)
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
    63
                os.unlink(a)
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
    os.unlink(b)
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
    os.unlink(c)
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
    return r
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
3218
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3212
diff changeset
    69
def checkunknown(repo, m2, wctx):
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    70
    """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    71
    check for collisions between unknown files and files in m2
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    72
    """
3218
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3212
diff changeset
    73
    for f in wctx.unknown():
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    74
        if f in m2:
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    75
            if repo.file(f).cmp(m2[f], repo.wread(f)):
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    76
                raise util.Abort(_("'%s' already exists in the working"
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    77
                                   " dir and differs from remote") % f)
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    78
3218
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3212
diff changeset
    79
def forgetremoved(m2, wctx):
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    80
    """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    81
    Forget removed files
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    82
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    83
    If we're jumping between revisions (as opposed to merging), and if
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    84
    neither the working directory nor the target rev has the file,
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    85
    then we need to remove it from the dirstate, to prevent the
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    86
    dirstate from listing the file when it is no longer in the
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    87
    manifest.
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    88
    """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    89
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    90
    action = []
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    91
3218
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3212
diff changeset
    92
    for f in wctx.deleted() + wctx.removed():
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    93
        if f not in m2:
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    94
            action.append((f, "f"))
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    95
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    96
    return action
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    97
3153
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
    98
def nonoverlap(d1, d2):
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
    99
    """
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   100
    Return list of elements in d1 not in d2
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   101
    """
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   102
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   103
    l = []
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   104
    for d in d1:
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   105
        if d not in d2:
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   106
            l.append(d)
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   107
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   108
    l.sort()
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   109
    return l
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   110
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   111
def findold(fctx, limit):
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   112
    """
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   113
    find files that path was copied from, back to linkrev limit
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   114
    """
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   115
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   116
    old = {}
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   117
    orig = fctx.path()
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   118
    visit = [fctx]
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   119
    while visit:
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   120
        fc = visit.pop()
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   121
        if fc.rev() < limit:
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   122
            continue
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   123
        if fc.path() != orig and fc.path() not in old:
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   124
            old[fc.path()] = 1
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   125
        visit += fc.parents()
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   126
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   127
    old = old.keys()
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   128
    old.sort()
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   129
    return old
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   130
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   131
def findcopies(repo, m1, m2, limit):
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   132
    """
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   133
    Find moves and copies between m1 and m2 back to limit linkrev
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   134
    """
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   135
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   136
    if not repo.ui.config("merge", "followcopies"):
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   137
        return {}
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   138
3160
1839e6e91c3a findcopies: shortcut for empty working dir
Matt Mackall <mpm@selenic.com>
parents: 3155
diff changeset
   139
    # avoid silly behavior for update from empty dir
1839e6e91c3a findcopies: shortcut for empty working dir
Matt Mackall <mpm@selenic.com>
parents: 3155
diff changeset
   140
    if not m1:
1839e6e91c3a findcopies: shortcut for empty working dir
Matt Mackall <mpm@selenic.com>
parents: 3155
diff changeset
   141
        return {}
1839e6e91c3a findcopies: shortcut for empty working dir
Matt Mackall <mpm@selenic.com>
parents: 3155
diff changeset
   142
3155
56c59ba7aa76 findcopies: use dirstate rename information
Matt Mackall <mpm@selenic.com>
parents: 3153
diff changeset
   143
    dcopies = repo.dirstate.copies()
3153
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   144
    copy = {}
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   145
    match = {}
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   146
    u1 = nonoverlap(m1, m2)
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   147
    u2 = nonoverlap(m2, m1)
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   148
    ctx = util.cachefunc(lambda f,n: repo.filectx(f, fileid=n[:20]))
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   149
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   150
    def checkpair(c, f2, man):
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   151
        ''' check if an apparent pair actually matches '''
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   152
        c2 = ctx(f2, man[f2])
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   153
        ca = c.ancestor(c2)
3251
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   154
        if ca and ca.path() == c.path() or ca.path() == c2.path():
3153
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   155
            copy[c.path()] = f2
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   156
            copy[f2] = c.path()
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   157
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   158
    for f in u1:
3155
56c59ba7aa76 findcopies: use dirstate rename information
Matt Mackall <mpm@selenic.com>
parents: 3153
diff changeset
   159
        c = ctx(dcopies.get(f, f), m1[f])
3153
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   160
        for of in findold(c, limit):
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   161
            if of in m2:
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   162
                checkpair(c, of, m2)
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   163
            else:
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   164
                match.setdefault(of, []).append(f)
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   165
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   166
    for f in u2:
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   167
        c = ctx(f, m2[f])
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   168
        for of in findold(c, limit):
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   169
            if of in m1:
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   170
                checkpair(c, of, m1)
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   171
            elif of in match:
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   172
                for mf in match[of]:
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   173
                    checkpair(c, mf, m1)
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   174
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   175
    return copy
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   176
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   177
def manifestmerge(ui, m1, m2, ma, copy, overwrite, backwards, partial):
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   178
    """
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   179
    Merge manifest m1 with m2 using ancestor ma and generate merge action list
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   180
    """
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   181
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   182
    def fmerge(f, f2=None, fa=None):
3118
5644a05a608c merge: simplify exec flag handling
Matt Mackall <mpm@selenic.com>
parents: 3117
diff changeset
   183
        """merge executable flags"""
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   184
        if not f2:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   185
            f2 = f
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   186
            fa = f
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   187
        a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2)
3118
5644a05a608c merge: simplify exec flag handling
Matt Mackall <mpm@selenic.com>
parents: 3117
diff changeset
   188
        return ((a^b) | (a^c)) ^ a
5644a05a608c merge: simplify exec flag handling
Matt Mackall <mpm@selenic.com>
parents: 3117
diff changeset
   189
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   190
    action = []
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   191
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   192
    def act(msg, f, m, *args):
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   193
        ui.debug(" %s: %s -> %s\n" % (f, msg, m))
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   194
        action.append((f, m) + args)
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   195
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   196
    # Compare manifests
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   197
    for f, n in m1.iteritems():
3248
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   198
        if partial and not partial(f):
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   199
            continue
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   200
        if f in m2:
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   201
            # are files different?
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   202
            if n != m2[f]:
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   203
                a = ma.get(f, nullid)
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   204
                # are both different from the ancestor?
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   205
                if not overwrite and n != a and m2[f] != a:
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   206
                    act("versions differ", f, "m", fmerge(f), n[:20], m2[f])
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   207
                # are we clobbering?
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   208
                # is remote's version newer?
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   209
                # or are we going back in time and clean?
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   210
                elif overwrite or m2[f] != a or (backwards and not n[20:]):
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   211
                    act("remote is newer", f, "g", m2.execf(f), m2[f])
3113
d1d1cd5b9484 merge: eliminate confusing queued variable
Matt Mackall <mpm@selenic.com>
parents: 3112
diff changeset
   212
                # local is newer, not overwrite, check mode bits
3118
5644a05a608c merge: simplify exec flag handling
Matt Mackall <mpm@selenic.com>
parents: 3117
diff changeset
   213
                elif fmerge(f) != m1.execf(f):
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   214
                    act("update permissions", f, "e", m2.execf(f))
3113
d1d1cd5b9484 merge: eliminate confusing queued variable
Matt Mackall <mpm@selenic.com>
parents: 3112
diff changeset
   215
            # contents same, check mode bits
d1d1cd5b9484 merge: eliminate confusing queued variable
Matt Mackall <mpm@selenic.com>
parents: 3112
diff changeset
   216
            elif m1.execf(f) != m2.execf(f):
3120
1c1e59aac82a merge: simplify local created logic
Matt Mackall <mpm@selenic.com>
parents: 3119
diff changeset
   217
                if overwrite or fmerge(f) != m1.execf(f):
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   218
                    act("update permissions", f, "e", m2.execf(f))
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   219
        elif f in copy:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   220
            f2 = copy[f]
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   221
            if f in ma: # case 3,20 A/B/A
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   222
                act("remote moved",
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   223
                    f, "c", f2, f2, m1[f], m2[f2], fmerge(f, f2, f), True)
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   224
            else:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   225
                if f2 in m1: # case 2 A,B/B/B
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   226
                    act("local copied",
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   227
                        f, "c", f2, f, m1[f], m2[f2], fmerge(f, f2, f2), False)
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   228
                else: # case 4,21 A/B/B
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   229
                    act("local moved",
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   230
                        f, "c", f2, f, m1[f], m2[f2], fmerge(f, f2, f2), False)
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   231
        elif f in ma:
3117
7a635ef25132 merge: simplify tests for local changed/remote deleted
Matt Mackall <mpm@selenic.com>
parents: 3116
diff changeset
   232
            if n != ma[f] and not overwrite:
3119
b1de36a4b4df merge: simplify prompt code
Matt Mackall <mpm@selenic.com>
parents: 3118
diff changeset
   233
                if ui.prompt(
3117
7a635ef25132 merge: simplify tests for local changed/remote deleted
Matt Mackall <mpm@selenic.com>
parents: 3116
diff changeset
   234
                    (_(" local changed %s which remote deleted\n") % f) +
3119
b1de36a4b4df merge: simplify prompt code
Matt Mackall <mpm@selenic.com>
parents: 3118
diff changeset
   235
                    _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   236
                    act("prompt delete", f, "r")
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   237
            else:
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   238
                act("other deleted", f, "r")
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   239
        else:
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   240
            # file is created on branch or in working directory
3120
1c1e59aac82a merge: simplify local created logic
Matt Mackall <mpm@selenic.com>
parents: 3119
diff changeset
   241
            if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   242
                act("remote deleted", f, "r")
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   243
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   244
    for f, n in m2.iteritems():
3248
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   245
        if partial and not partial(f):
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   246
            continue
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   247
        if f in m1:
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   248
            continue
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   249
        if f in copy:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   250
            f2 = copy[f]
3252
ae85272b59a4 merge: copy fixes and tests
Matt Mackall <mpm@selenic.com>
parents: 3251
diff changeset
   251
            if f2 not in m2: # already seen
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   252
                continue
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   253
            # rename case 1, A/A,B/A
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   254
            act("remote copied",
3252
ae85272b59a4 merge: copy fixes and tests
Matt Mackall <mpm@selenic.com>
parents: 3251
diff changeset
   255
                f2, "c", f, f, m1[f2], m2[f], fmerge(f2, f, f2), False)
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   256
        elif f in ma:
3116
920f54a2249e merge: more simplification of m2 manifest scanning
Matt Mackall <mpm@selenic.com>
parents: 3115
diff changeset
   257
            if overwrite or backwards:
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   258
                act("recreating", f, "g", m2.execf(f), n)
3116
920f54a2249e merge: more simplification of m2 manifest scanning
Matt Mackall <mpm@selenic.com>
parents: 3115
diff changeset
   259
            elif n != ma[f]:
3119
b1de36a4b4df merge: simplify prompt code
Matt Mackall <mpm@selenic.com>
parents: 3118
diff changeset
   260
                if ui.prompt(
3116
920f54a2249e merge: more simplification of m2 manifest scanning
Matt Mackall <mpm@selenic.com>
parents: 3115
diff changeset
   261
                    (_("remote changed %s which local deleted\n") % f) +
3119
b1de36a4b4df merge: simplify prompt code
Matt Mackall <mpm@selenic.com>
parents: 3118
diff changeset
   262
                    _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   263
                    act("prompt recreating", f, "g", m2.execf(f), n)
3115
bb74f809bc95 merge: reorder tests on m2 items in manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3114
diff changeset
   264
        else:
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   265
            act("remote created", f, "g", m2.execf(f), n)
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   266
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   267
    return action
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   268
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   269
def applyupdates(repo, action, xp1, xp2):
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   270
    updated, merged, removed, unresolved = 0, 0, 0, 0
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   271
    action.sort()
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   272
    for a in action:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   273
        f, m = a[:2]
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   274
        if f[0] == "/":
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   275
            continue
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   276
        if m == "r": # remove
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   277
            repo.ui.note(_("removing %s\n") % f)
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   278
            util.audit_path(f)
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   279
            try:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   280
                util.unlink(repo.wjoin(f))
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   281
            except OSError, inst:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   282
                if inst.errno != errno.ENOENT:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   283
                    repo.ui.warn(_("update failed to remove %s: %s!\n") %
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   284
                                 (f, inst.strerror))
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   285
            removed +=1
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   286
        elif m == "c": # copy
3251
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   287
            f2, fd, my, other, flag, move = a[2:]
3252
ae85272b59a4 merge: copy fixes and tests
Matt Mackall <mpm@selenic.com>
parents: 3251
diff changeset
   288
            repo.ui.status(_("merging %s and %s to %s\n") % (f, f2, fd))
3251
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   289
            if filemerge(repo, f, f2, fd, my, other, xp1, xp2, move):
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   290
                unresolved += 1
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   291
            util.set_exec(repo.wjoin(fd), flag)
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   292
            merged += 1
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   293
        elif m == "m": # merge
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   294
            flag, my, other = a[2:]
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   295
            repo.ui.status(_("merging %s\n") % f)
3212
cac7be0b9b99 merge: remove old merge function
Matt Mackall <mpm@selenic.com>
parents: 3211
diff changeset
   296
            if filemerge(repo, f, f, f, my, other, xp1, xp2, False):
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   297
                unresolved += 1
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   298
            util.set_exec(repo.wjoin(f), flag)
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   299
            merged += 1
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   300
        elif m == "g": # get
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   301
            flag, node = a[2:]
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   302
            repo.ui.note(_("getting %s\n") % f)
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   303
            t = repo.file(f).read(node)
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   304
            repo.wwrite(f, t)
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   305
            util.set_exec(repo.wjoin(f), flag)
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   306
            updated += 1
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   307
        elif m == "e": # exec
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   308
            flag = a[2:]
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   309
            util.set_exec(repo.wjoin(f), flag)
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   310
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   311
    return updated, merged, removed, unresolved
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   312
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   313
def recordupdates(repo, action, branchmerge):
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   314
    for a in action:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   315
        f, m = a[:2]
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   316
        if m == "r": # remove
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   317
            if branchmerge:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   318
                repo.dirstate.update([f], 'r')
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   319
            else:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   320
                repo.dirstate.forget([f])
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   321
        elif m == "f": # forget
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   322
            repo.dirstate.forget([f])
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   323
        elif m == "g": # get
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   324
            if branchmerge:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   325
                repo.dirstate.update([f], 'n', st_mtime=-1)
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   326
            else:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   327
                repo.dirstate.update([f], 'n')
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   328
        elif m == "m": # merge
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   329
            flag, my, other = a[2:]
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   330
            if branchmerge:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   331
                # We've done a branch merge, mark this file as merged
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   332
                # so that we properly record the merger later
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   333
                repo.dirstate.update([f], 'm')
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   334
            else:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   335
                # We've update-merged a locally modified file, so
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   336
                # we set the dirstate to emulate a normal checkout
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   337
                # of that file some time in the past. Thus our
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   338
                # merge will appear as a normal local file
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   339
                # modification.
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   340
                fl = repo.file(f)
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   341
                f_len = fl.size(fl.rev(other))
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   342
                repo.dirstate.update([f], 'n', st_size=f_len, st_mtime=-1)
3251
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   343
        elif m == "c": # copy
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   344
            f2, fd, my, other, flag, move = a[2:]
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   345
            if branchmerge:
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   346
                # We've done a branch merge, mark this file as merged
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   347
                # so that we properly record the merger later
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   348
                repo.dirstate.update([fd], 'm')
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   349
            else:
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   350
                # We've update-merged a locally modified file, so
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   351
                # we set the dirstate to emulate a normal checkout
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   352
                # of that file some time in the past. Thus our
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   353
                # merge will appear as a normal local file
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   354
                # modification.
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   355
                fl = repo.file(f)
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   356
                f_len = fl.size(fl.rev(other))
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   357
                repo.dirstate.update([fd], 'n', st_size=f_len, st_mtime=-1)
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   358
            if move:
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   359
                repo.dirstate.update([f], 'r')
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   360
            if f != fd:
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   361
                repo.dirstate.copy(f, fd)
3292
764688cf51e5 merge: remember rename copies and parents properly on commit
Matt Mackall <mpm@selenic.com>
parents: 3252
diff changeset
   362
            else:
764688cf51e5 merge: remember rename copies and parents properly on commit
Matt Mackall <mpm@selenic.com>
parents: 3252
diff changeset
   363
                repo.dirstate.copy(f2, fd)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   364
2811
1ea086bc2086 Merge: combine choose and moddirstate to partial
Matt Mackall <mpm@selenic.com>
parents: 2810
diff changeset
   365
def update(repo, node, branchmerge=False, force=False, partial=None,
2815
4870f795f681 Merge: combine force and forcemerge arguments
Matt Mackall <mpm@selenic.com>
parents: 2814
diff changeset
   366
           wlock=None, show_stats=True, remind=True):
4870f795f681 Merge: combine force and forcemerge arguments
Matt Mackall <mpm@selenic.com>
parents: 2814
diff changeset
   367
4870f795f681 Merge: combine force and forcemerge arguments
Matt Mackall <mpm@selenic.com>
parents: 2814
diff changeset
   368
    overwrite = force and not branchmerge
4870f795f681 Merge: combine force and forcemerge arguments
Matt Mackall <mpm@selenic.com>
parents: 2814
diff changeset
   369
    forcemerge = force and branchmerge
2812
3aeab7bb5adc Refactor update locking slightly
Matt Mackall <mpm@selenic.com>
parents: 2811
diff changeset
   370
3aeab7bb5adc Refactor update locking slightly
Matt Mackall <mpm@selenic.com>
parents: 2811
diff changeset
   371
    if not wlock:
3aeab7bb5adc Refactor update locking slightly
Matt Mackall <mpm@selenic.com>
parents: 2811
diff changeset
   372
        wlock = repo.wlock()
3aeab7bb5adc Refactor update locking slightly
Matt Mackall <mpm@selenic.com>
parents: 2811
diff changeset
   373
2814
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
   374
    ### check phase
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
   375
3218
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3212
diff changeset
   376
    wc = repo.workingctx()
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3212
diff changeset
   377
    pl = wc.parents()
3167
e67c22bc8bba merge: use repo.parents and parent contexts in update
Matt Mackall <mpm@selenic.com>
parents: 3162
diff changeset
   378
    if not overwrite and len(pl) > 1:
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   379
        raise util.Abort(_("outstanding uncommitted merges"))
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   380
3167
e67c22bc8bba merge: use repo.parents and parent contexts in update
Matt Mackall <mpm@selenic.com>
parents: 3162
diff changeset
   381
    p1, p2 = pl[0], repo.changectx(node)
e67c22bc8bba merge: use repo.parents and parent contexts in update
Matt Mackall <mpm@selenic.com>
parents: 3162
diff changeset
   382
    pa = p1.ancestor(p2)
2814
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
   383
2968
545d33aa3f82 merge: add backwards variable
Matt Mackall <mpm@selenic.com>
parents: 2899
diff changeset
   384
    # are we going backwards?
545d33aa3f82 merge: add backwards variable
Matt Mackall <mpm@selenic.com>
parents: 2899
diff changeset
   385
    backwards = (pa == p2)
545d33aa3f82 merge: add backwards variable
Matt Mackall <mpm@selenic.com>
parents: 2899
diff changeset
   386
2814
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
   387
    # is there a linear path from p1 to p2?
3110
40e777bda455 merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents: 3109
diff changeset
   388
    if pa == p1 or pa == p2:
40e777bda455 merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents: 3109
diff changeset
   389
        if branchmerge:
40e777bda455 merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents: 3109
diff changeset
   390
            raise util.Abort(_("there is nothing to merge, just use "
40e777bda455 merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents: 3109
diff changeset
   391
                               "'hg update' or look at 'hg heads'"))
40e777bda455 merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents: 3109
diff changeset
   392
    elif not (overwrite or branchmerge):
2815
4870f795f681 Merge: combine force and forcemerge arguments
Matt Mackall <mpm@selenic.com>
parents: 2814
diff changeset
   393
        raise util.Abort(_("update spans branches, use 'hg merge' "
2814
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
   394
                           "or 'hg update -C' to lose changes"))
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
   395
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
   396
    if branchmerge and not forcemerge:
3218
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3212
diff changeset
   397
        if wc.modified() or wc.added() or wc.removed():
2814
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
   398
            raise util.Abort(_("outstanding uncommitted changes"))
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
   399
3248
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   400
    m1 = wc.manifest()
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   401
    m2 = p2.manifest()
3167
e67c22bc8bba merge: use repo.parents and parent contexts in update
Matt Mackall <mpm@selenic.com>
parents: 3162
diff changeset
   402
    ma = pa.manifest()
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   403
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   404
    # resolve the manifest to determine which files
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   405
    # we care about merging
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   406
    repo.ui.note(_("resolving manifests\n"))
3110
40e777bda455 merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents: 3109
diff changeset
   407
    repo.ui.debug(_(" overwrite %s branchmerge %s partial %s\n") %
40e777bda455 merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents: 3109
diff changeset
   408
                  (overwrite, branchmerge, bool(partial)))
3167
e67c22bc8bba merge: use repo.parents and parent contexts in update
Matt Mackall <mpm@selenic.com>
parents: 3162
diff changeset
   409
    repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (p1, p2, pa))
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   410
3100
87ea5a71f7b9 merge: convert actions to list
Matt Mackall <mpm@selenic.com>
parents: 2981
diff changeset
   411
    action = []
3155
56c59ba7aa76 findcopies: use dirstate rename information
Matt Mackall <mpm@selenic.com>
parents: 3153
diff changeset
   412
    copy = {}
56c59ba7aa76 findcopies: use dirstate rename information
Matt Mackall <mpm@selenic.com>
parents: 3153
diff changeset
   413
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   414
    if not force:
3218
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3212
diff changeset
   415
        checkunknown(repo, m2, wc)
3110
40e777bda455 merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents: 3109
diff changeset
   416
    if not branchmerge:
3218
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3212
diff changeset
   417
        action += forgetremoved(m2, wc)
3161
84561ea8711e merge: move findcopies after workingmanifest
Matt Mackall <mpm@selenic.com>
parents: 3160
diff changeset
   418
    if not (backwards or overwrite):
3167
e67c22bc8bba merge: use repo.parents and parent contexts in update
Matt Mackall <mpm@selenic.com>
parents: 3162
diff changeset
   419
        copy = findcopies(repo, m1, m2, pa.rev())
3153
c82ea81d6850 Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents: 3121
diff changeset
   420
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   421
    action += manifestmerge(repo.ui, m1, m2, ma, copy,
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   422
                            overwrite, backwards, partial)
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   423
2897
dd032b0f02ac merge: move forgets to the apply stage
Matt Mackall <mpm@selenic.com>
parents: 2896
diff changeset
   424
    ### apply phase
dd032b0f02ac merge: move forgets to the apply stage
Matt Mackall <mpm@selenic.com>
parents: 2896
diff changeset
   425
3110
40e777bda455 merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents: 3109
diff changeset
   426
    if not branchmerge:
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   427
        # we don't need to do any magic, just jump to the new rev
3167
e67c22bc8bba merge: use repo.parents and parent contexts in update
Matt Mackall <mpm@selenic.com>
parents: 3162
diff changeset
   428
        p1, p2 = p2, repo.changectx(nullid)
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   429
3167
e67c22bc8bba merge: use repo.parents and parent contexts in update
Matt Mackall <mpm@selenic.com>
parents: 3162
diff changeset
   430
    xp1, xp2 = str(p1), str(p2)
3169
9e002614f2eb merge: minor nullid cleanup
Matt Mackall <mpm@selenic.com>
parents: 3167
diff changeset
   431
    if not p2: xp2 = ''
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   432
3109
62044d161470 merge: simplify hook code
Matt Mackall <mpm@selenic.com>
parents: 3108
diff changeset
   433
    repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   434
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   435
    updated, merged, removed, unresolved = applyupdates(repo, action, xp1, xp2)
2899
8743188f4d2e merge: consolidate dirstate updates
Matt Mackall <mpm@selenic.com>
parents: 2898
diff changeset
   436
8743188f4d2e merge: consolidate dirstate updates
Matt Mackall <mpm@selenic.com>
parents: 2898
diff changeset
   437
    # update dirstate
8743188f4d2e merge: consolidate dirstate updates
Matt Mackall <mpm@selenic.com>
parents: 2898
diff changeset
   438
    if not partial:
3247
7a0d70b69d74 merge: reorder dirstate update slightly for correctness
Matt Mackall <mpm@selenic.com>
parents: 3218
diff changeset
   439
        recordupdates(repo, action, branchmerge)
3167
e67c22bc8bba merge: use repo.parents and parent contexts in update
Matt Mackall <mpm@selenic.com>
parents: 3162
diff changeset
   440
        repo.dirstate.setparents(p1.node(), p2.node())
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   441
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   442
    if show_stats:
2977
87a0332ab58b merge: combine merge and get lists
Matt Mackall <mpm@selenic.com>
parents: 2976
diff changeset
   443
        stats = ((updated, _("updated")),
2980
54d85098fb82 merge: make unresolved a counter
Matt Mackall <mpm@selenic.com>
parents: 2979
diff changeset
   444
                 (merged - unresolved, _("merged")),
2978
962b9c7df641 merge: add remove to the action hash
Matt Mackall <mpm@selenic.com>
parents: 2977
diff changeset
   445
                 (removed, _("removed")),
2980
54d85098fb82 merge: make unresolved a counter
Matt Mackall <mpm@selenic.com>
parents: 2979
diff changeset
   446
                 (unresolved, _("unresolved")))
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   447
        note = ", ".join([_("%d files %s") % s for s in stats])
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   448
        repo.ui.status("%s\n" % note)
2811
1ea086bc2086 Merge: combine choose and moddirstate to partial
Matt Mackall <mpm@selenic.com>
parents: 2810
diff changeset
   449
    if not partial:
2810
ca06d35af65e Rename merge.allow -> merge.branchmerge
Matt Mackall <mpm@selenic.com>
parents: 2803
diff changeset
   450
        if branchmerge:
2813
56f99f5aab34 Merge: refactor err and failedmerge -> unresolved
Matt Mackall <mpm@selenic.com>
parents: 2812
diff changeset
   451
            if unresolved:
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   452
                repo.ui.status(_("There are unresolved merges,"
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   453
                                " you can redo the full merge using:\n"
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   454
                                "  hg update -C %s\n"
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   455
                                "  hg merge %s\n"
3167
e67c22bc8bba merge: use repo.parents and parent contexts in update
Matt Mackall <mpm@selenic.com>
parents: 3162
diff changeset
   456
                                % (p1.rev(), p2.rev())))
2803
987c31e2a08c Merge with crew
Matt Mackall <mpm@selenic.com>
parents: 2775
diff changeset
   457
            elif remind:
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   458
                repo.ui.status(_("(branch merge, don't forget to commit)\n"))
2813
56f99f5aab34 Merge: refactor err and failedmerge -> unresolved
Matt Mackall <mpm@selenic.com>
parents: 2812
diff changeset
   459
        elif unresolved:
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   460
            repo.ui.status(_("There are unresolved merges with"
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   461
                             " locally modified files.\n"))
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   462
3109
62044d161470 merge: simplify hook code
Matt Mackall <mpm@selenic.com>
parents: 3108
diff changeset
   463
    repo.hook('update', parent1=xp1, parent2=xp2, error=unresolved)
2980
54d85098fb82 merge: make unresolved a counter
Matt Mackall <mpm@selenic.com>
parents: 2979
diff changeset
   464
    return unresolved
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   465