mercurial/merge.py
author Mads Kiilerich <mads@kiilerich.com>
Tue, 07 Dec 2010 03:29:21 +0100
changeset 13158 9e7e24052745
parent 12757 62c8f7691bc3
child 13162 115a9760c382
permissions -rw-r--r--
merge: fast-forward merge with descendant issue2538 gives a case where a changeset is merged with its child (which is on another branch), and to my surprise the result is a real merge with two parents, not just a "fast forward" "merge" with only the child as parent. That is essentially the same as issue619. Is the existing behaviour as intended and correct? Or is the following fix correct? Some extra "created new head" pops up with this fix, but it seems to me like they could be considered correct. The old branch head has been superseeded by changes on the other branch, and when the changes on the other branch is merged back to the branch it will introduce a new head not directly related to the previous branch head. (I guess the intention with existing behaviour could be to ensure that the changesets on the branch are directly connected and that no new heads pops up on merges.)
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
#
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
     3
# Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9783
diff changeset
     6
# GNU General Public License version 2 or any later version.
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
     8
from node import nullid, nullrev, hex, bin
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
     9
from i18n import _
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
    10
import util, filemerge, copies, subrepo
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8259
diff changeset
    11
import errno, os, shutil
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    12
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    13
class mergestate(object):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    14
    '''track 3-way merge state of individual files'''
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    15
    def __init__(self, repo):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    16
        self._repo = repo
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    17
        self._dirty = False
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    18
        self._read()
7848
89e05c02a4af resolve: move reset to localrepo.commit
Matt Mackall <mpm@selenic.com>
parents: 7768
diff changeset
    19
    def reset(self, node=None):
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    20
        self._state = {}
7848
89e05c02a4af resolve: move reset to localrepo.commit
Matt Mackall <mpm@selenic.com>
parents: 7768
diff changeset
    21
        if node:
89e05c02a4af resolve: move reset to localrepo.commit
Matt Mackall <mpm@selenic.com>
parents: 7768
diff changeset
    22
            self._local = node
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    23
        shutil.rmtree(self._repo.join("merge"), True)
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    24
        self._dirty = False
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    25
    def _read(self):
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    26
        self._state = {}
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    27
        try:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    28
            f = self._repo.opener("merge/state")
6530
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
    29
            for i, l in enumerate(f):
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
    30
                if i == 0:
11451
51021f4c80b5 resolve: do not crash on empty mergestate
Martin Geisler <mg@lazybytes.net>
parents: 11417
diff changeset
    31
                    self._local = bin(l[:-1])
6530
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
    32
                else:
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
    33
                    bits = l[:-1].split("\0")
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
    34
                    self._state[bits[0]] = bits[1:]
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    35
        except IOError, err:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    36
            if err.errno != errno.ENOENT:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    37
                raise
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    38
        self._dirty = False
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    39
    def commit(self):
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    40
        if self._dirty:
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    41
            f = self._repo.opener("merge/state", "w")
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    42
            f.write(hex(self._local) + "\n")
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    43
            for d, v in self._state.iteritems():
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    44
                f.write("\0".join([d] + v) + "\n")
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    45
            self._dirty = False
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    46
    def add(self, fcl, fco, fca, fd, flags):
6517
fcfb6a0a0a84 python-2.6: use sha wrapper from util for new merge code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6512
diff changeset
    47
        hash = util.sha1(fcl.path()).hexdigest()
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    48
        self._repo.opener("merge/" + hash, "w").write(fcl.data())
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    49
        self._state[fd] = ['u', hash, fcl.path(), fca.path(),
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    50
                           hex(fca.filenode()), fco.path(), flags]
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    51
        self._dirty = True
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    52
    def __contains__(self, dfile):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    53
        return dfile in self._state
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    54
    def __getitem__(self, dfile):
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    55
        return self._state[dfile][0]
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    56
    def __iter__(self):
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    57
        l = self._state.keys()
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    58
        l.sort()
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    59
        for f in l:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    60
            yield f
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    61
    def mark(self, dfile, state):
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    62
        self._state[dfile][0] = state
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    63
        self._dirty = True
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    64
    def resolve(self, dfile, wctx, octx):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    65
        if self[dfile] == 'r':
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    66
            return 0
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    67
        state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    68
        f = self._repo.opener("merge/" + hash)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    69
        self._repo.wwrite(dfile, f.read(), flags)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    70
        fcd = wctx[dfile]
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    71
        fco = octx[ofile]
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    72
        fca = self._repo.filectx(afile, fileid=anode)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    73
        r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    74
        if not r:
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    75
            self.mark(dfile, 'r')
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    76
        return r
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    77
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
    78
def _checkunknown(wctx, mctx):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
    79
    "check for collisions between unknown files and files in mctx"
3218
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3212
diff changeset
    80
    for f in wctx.unknown():
11702
eb07fbc21e9c filectx: use cmp(self, fctx) instead of cmp(self, text)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11470
diff changeset
    81
        if f in mctx and mctx[f].cmp(wctx[f]):
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
    82
            raise util.Abort(_("untracked file in working directory differs"
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
    83
                               " from file in requested revision: '%s'") % f)
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    84
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
    85
def _checkcollision(mctx):
3785
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
    86
    "check for case folding collisions in the destination context"
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
    87
    folded = {}
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
    88
    for fn in mctx:
3785
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
    89
        fold = fn.lower()
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
    90
        if fold in folded:
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
    91
            raise util.Abort(_("case-folding collision between %s and %s")
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
    92
                             % (fn, folded[fold]))
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
    93
        folded[fold] = fn
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
    94
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
    95
def _forgetremoved(wctx, mctx, branchmerge):
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    96
    """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    97
    Forget removed files
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    98
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
    99
    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
   100
    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
   101
    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
   102
    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
   103
    manifest.
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   104
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   105
    If we're merging, and the other revision has removed a file
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   106
    that is not present in the working directory, we need to mark it
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   107
    as removed.
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   108
    """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   109
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   110
    action = []
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   111
    state = branchmerge and 'r' or 'f'
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   112
    for f in wctx.deleted():
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
   113
        if f not in mctx:
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   114
            action.append((f, state))
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   115
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   116
    if not branchmerge:
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   117
        for f in wctx.removed():
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
   118
            if f not in mctx:
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   119
                action.append((f, "f"))
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   120
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   121
    return action
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   122
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
   123
def manifestmerge(repo, p1, p2, pa, overwrite, partial):
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   124
    """
11817
d12fe809e1ee merge: fix typo in docstring
Alecs King <alecsk@gmail.com>
parents: 11759
diff changeset
   125
    Merge p1 and p2 with ancestor pa and generate merge action list
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   126
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   127
    overwrite = whether we clobber working files
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   128
    partial = function to filter file lists
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   129
    """
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   130
8733
f8be48c6b08c merge: simplify flag merging code slightly
Matt Mackall <mpm@selenic.com>
parents: 8545
diff changeset
   131
    def fmerge(f, f2, fa):
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   132
        """merge flags"""
5708
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   133
        a, m, n = ma.flags(fa), m1.flags(f), m2.flags(f2)
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   134
        if m == n: # flags agree
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   135
            return m # unchanged
8733
f8be48c6b08c merge: simplify flag merging code slightly
Matt Mackall <mpm@selenic.com>
parents: 8545
diff changeset
   136
        if m and n and not a: # flags set, don't agree, differ from parent
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 9030
diff changeset
   137
            r = repo.ui.promptchoice(
8733
f8be48c6b08c merge: simplify flag merging code slightly
Matt Mackall <mpm@selenic.com>
parents: 8545
diff changeset
   138
                _(" conflicting flags for %s\n"
f8be48c6b08c merge: simplify flag merging code slightly
Matt Mackall <mpm@selenic.com>
parents: 8545
diff changeset
   139
                  "(n)one, e(x)ec or sym(l)ink?") % f,
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 9030
diff changeset
   140
                (_("&None"), _("E&xec"), _("Sym&link")), 0)
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   141
            if r == 1:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   142
                return "x" # Exec
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   143
            if r == 2:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   144
                return "l" # Symlink
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 9030
diff changeset
   145
            return ""
5708
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   146
        if m and m != a: # changed from a to m
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   147
            return m
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   148
        if n and n != a: # changed from a to n
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   149
            return n
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   150
        return '' # flag was cleared
3118
5644a05a608c merge: simplify exec flag handling
Matt Mackall <mpm@selenic.com>
parents: 3117
diff changeset
   151
3307
f009a6f12a59 merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents: 3306
diff changeset
   152
    def act(msg, m, f, *args):
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
   153
        repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   154
        action.append((f, m) + args)
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   155
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   156
    action, copy = [], {}
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   157
8749
69caf50da4a0 merge: refactor some initialization, drop backwards var
Matt Mackall <mpm@selenic.com>
parents: 8748
diff changeset
   158
    if overwrite:
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   159
        pa = p1
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   160
    elif pa == p2: # backwards
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   161
        pa = p1.p1()
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   162
    elif pa and repo.ui.configbool("merge", "followcopies", True):
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   163
        dirs = repo.ui.configbool("merge", "followdirs", True)
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   164
        copy, diverge = copies.copies(repo, p1, p2, pa, dirs)
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   165
        for of, fl in diverge.iteritems():
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   166
            act("divergent renames", "dr", of, fl)
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   167
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   168
    repo.ui.note(_("resolving manifests\n"))
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9048
diff changeset
   169
    repo.ui.debug(" overwrite %s partial %s\n" % (overwrite, bool(partial)))
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9048
diff changeset
   170
    repo.ui.debug(" ancestor %s local %s remote %s\n" % (pa, p1, p2))
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   171
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   172
    m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest()
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   173
    copied = set(copy.values())
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
   174
11470
34e33d50c26b subrepo: correctly handle update -C with modified subrepos (issue2022)
Matt Mackall <mpm@selenic.com>
parents: 11466
diff changeset
   175
    if '.hgsubstate' in m1:
9783
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   176
        # check whether sub state is modified
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   177
        for s in p1.substate:
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   178
            if p1.sub(s).dirty():
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   179
                m1['.hgsubstate'] += "+"
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   180
                break
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   181
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   182
    # Compare manifests
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   183
    for f, n in m1.iteritems():
3248
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   184
        if partial and not partial(f):
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   185
            continue
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   186
        if f in m2:
8735
ff8519c437c6 merge: remove a flags case
Matt Mackall <mpm@selenic.com>
parents: 8734
diff changeset
   187
            rflags = fmerge(f, f, f)
8752
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   188
            a = ma.get(f, nullid)
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   189
            if n == m2[f] or m2[f] == a: # same or local newer
11466
ad27428c59ce update: synchronize permissions in the dirstate (issue1473)
Matt Mackall <mpm@selenic.com>
parents: 11454
diff changeset
   190
                # is file locally modified or flags need changing?
ad27428c59ce update: synchronize permissions in the dirstate (issue1473)
Matt Mackall <mpm@selenic.com>
parents: 11454
diff changeset
   191
                # dirstate flags may need to be made current
ad27428c59ce update: synchronize permissions in the dirstate (issue1473)
Matt Mackall <mpm@selenic.com>
parents: 11454
diff changeset
   192
                if m1.flags(f) != rflags or n[20:]:
8752
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   193
                    act("update permissions", "e", f, rflags)
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   194
            elif n == a: # remote newer
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   195
                act("remote is newer", "g", f, rflags)
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   196
            else: # both changed
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   197
                act("versions differ", "m", f, f, f, rflags, False)
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   198
        elif f in copied: # files we'll deal with on m2 side
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   199
            pass
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   200
        elif f in copy:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   201
            f2 = copy[f]
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   202
            if f2 not in m2: # directory rename
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   203
                act("remote renamed directory to " + f2, "d",
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   204
                    f, None, f2, m1.flags(f))
8748
f325574dad1a merge: combine a copy and move case
Matt Mackall <mpm@selenic.com>
parents: 8747
diff changeset
   205
            else: # case 2 A,B/B/B or case 4,21 A/B/B
f325574dad1a merge: combine a copy and move case
Matt Mackall <mpm@selenic.com>
parents: 8747
diff changeset
   206
                act("local copied/moved to " + f2, "m",
3730
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
   207
                    f, f2, f, fmerge(f, f2, f2), False)
8744
6b675c781c6d merge: simplify 'other deleted' case
Matt Mackall <mpm@selenic.com>
parents: 8743
diff changeset
   208
        elif f in ma: # clean, a different, no remote
8739
226f1005133c merge: drop an overwrite test
Matt Mackall <mpm@selenic.com>
parents: 8738
diff changeset
   209
            if n != ma[f]:
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 9030
diff changeset
   210
                if repo.ui.promptchoice(
5670
840e2b315c1f Fix misleading error and prompts during update/merge (issue556)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5489
diff changeset
   211
                    _(" local changed %s which remote deleted\n"
840e2b315c1f Fix misleading error and prompts during update/merge (issue556)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5489
diff changeset
   212
                      "use (c)hanged version or (d)elete?") % f,
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 9030
diff changeset
   213
                    (_("&Changed"), _("&Delete")), 0):
3307
f009a6f12a59 merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents: 3306
diff changeset
   214
                    act("prompt delete", "r", f)
8736
7619b16ea880 merge: fix prompt keep
Matt Mackall <mpm@selenic.com>
parents: 8735
diff changeset
   215
                else:
7619b16ea880 merge: fix prompt keep
Matt Mackall <mpm@selenic.com>
parents: 8735
diff changeset
   216
                    act("prompt keep", "a", f)
8751
e8d80e0835c7 merge: make locally-added file test more correct
Matt Mackall <mpm@selenic.com>
parents: 8750
diff changeset
   217
            elif n[20:] == "a": # added, no remote
e8d80e0835c7 merge: make locally-added file test more correct
Matt Mackall <mpm@selenic.com>
parents: 8750
diff changeset
   218
                act("remote deleted", "f", f)
8744
6b675c781c6d merge: simplify 'other deleted' case
Matt Mackall <mpm@selenic.com>
parents: 8743
diff changeset
   219
            elif n[20:] != "u":
3307
f009a6f12a59 merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents: 3306
diff changeset
   220
                act("other deleted", "r", f)
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   221
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   222
    for f, n in m2.iteritems():
3248
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   223
        if partial and not partial(f):
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   224
            continue
8752
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   225
        if f in m1 or f in copied: # files already visited
3729
581d20773326 merge: add copied hash to simplify copy logic
Matt Mackall <mpm@selenic.com>
parents: 3728
diff changeset
   226
            continue
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   227
        if f in copy:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   228
            f2 = copy[f]
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   229
            if f2 not in m1: # directory rename
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   230
                act("local renamed directory to " + f2, "d",
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   231
                    None, f, f2, m2.flags(f))
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   232
            elif f2 in m2: # rename case 1, A/A,B/A
3730
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
   233
                act("remote copied to " + f, "m",
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
   234
                    f2, f, f, fmerge(f2, f, f2), False)
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
   235
            else: # case 3,20 A/B/A
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
   236
                act("remote moved to " + f, "m",
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
   237
                    f2, f, f, fmerge(f2, f, f2), True)
8741
e592180ba435 merge: reorder remote creation tests
Matt Mackall <mpm@selenic.com>
parents: 8740
diff changeset
   238
        elif f not in ma:
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   239
            act("remote created", "g", f, m2.flags(f))
8741
e592180ba435 merge: reorder remote creation tests
Matt Mackall <mpm@selenic.com>
parents: 8740
diff changeset
   240
        elif n != ma[f]:
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 9030
diff changeset
   241
            if repo.ui.promptchoice(
8741
e592180ba435 merge: reorder remote creation tests
Matt Mackall <mpm@selenic.com>
parents: 8740
diff changeset
   242
                _("remote changed %s which local deleted\n"
e592180ba435 merge: reorder remote creation tests
Matt Mackall <mpm@selenic.com>
parents: 8740
diff changeset
   243
                  "use (c)hanged version or leave (d)eleted?") % f,
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 9030
diff changeset
   244
                (_("&Changed"), _("&Deleted")), 0) == 0:
8741
e592180ba435 merge: reorder remote creation tests
Matt Mackall <mpm@selenic.com>
parents: 8740
diff changeset
   245
                act("prompt recreating", "g", f, m2.flags(f))
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   246
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   247
    return action
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   248
8366
0bf0045000b5 some modernization cleanups, forward compatibility
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8312
diff changeset
   249
def actionkey(a):
0bf0045000b5 some modernization cleanups, forward compatibility
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8312
diff changeset
   250
    return a[1] == 'r' and -1 or 0, a
6805
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
   251
11454
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   252
def applyupdates(repo, action, wctx, mctx, actx):
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   253
    """apply the merge action list to the working directory
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   254
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   255
    wctx is the working copy context
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   256
    mctx is the context to be merged into the working copy
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   257
    actx is the context of the common ancestor
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   258
    """
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   259
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   260
    updated, merged, removed, unresolved = 0, 0, 0, 0
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   261
    ms = mergestate(repo)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   262
    ms.reset(wctx.parents()[0].node())
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   263
    moves = []
8366
0bf0045000b5 some modernization cleanups, forward compatibility
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8312
diff changeset
   264
    action.sort(key=actionkey)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   265
    substate = wctx.substate # prime
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   266
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   267
    # prescan for merges
10431
ba5e508b5e92 update: make calls to ui.progress()
Augie Fackler <durin42@gmail.com>
parents: 10282
diff changeset
   268
    u = repo.ui
5042
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   269
    for a in action:
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   270
        f, m = a[:2]
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   271
        if m == 'm': # merge
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   272
            f2, fd, flags, move = a[2:]
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   273
            if f == '.hgsubstate': # merged internally
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   274
                continue
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9048
diff changeset
   275
            repo.ui.debug("preserving %s for resolve of %s\n" % (f, fd))
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   276
            fcl = wctx[f]
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   277
            fco = mctx[f2]
12008
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   278
            if mctx == actx: # backwards, use working dir parent as ancestor
12664
545ec1775021 merge: handle no file parent in backwards merge (issue2364)
Matt Mackall <mpm@selenic.com>
parents: 12401
diff changeset
   279
                if fcl.parents():
545ec1775021 merge: handle no file parent in backwards merge (issue2364)
Matt Mackall <mpm@selenic.com>
parents: 12401
diff changeset
   280
                    fca = fcl.parents()[0]
545ec1775021 merge: handle no file parent in backwards merge (issue2364)
Matt Mackall <mpm@selenic.com>
parents: 12401
diff changeset
   281
                else:
545ec1775021 merge: handle no file parent in backwards merge (issue2364)
Matt Mackall <mpm@selenic.com>
parents: 12401
diff changeset
   282
                    fca = repo.filectx(f, fileid=nullrev)
12008
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   283
            else:
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   284
                fca = fcl.ancestor(fco, actx)
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   285
            if not fca:
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   286
                fca = repo.filectx(f, fileid=nullrev)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   287
            ms.add(fcl, fco, fca, fd, flags)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   288
            if f != fd and move:
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   289
                moves.append(f)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   290
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   291
    # remove renamed files after safely stored
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   292
    for f in moves:
12032
ad787252fed6 util: remove lexists, Python 2.4 introduced os.path.lexists
Martin Geisler <mg@lazybytes.net>
parents: 12010
diff changeset
   293
        if os.path.lexists(repo.wjoin(f)):
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9048
diff changeset
   294
            repo.ui.debug("removing %s\n" % f)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   295
            os.unlink(repo.wjoin(f))
5042
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   296
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5060
diff changeset
   297
    audit_path = util.path_auditor(repo.root)
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5060
diff changeset
   298
10431
ba5e508b5e92 update: make calls to ui.progress()
Augie Fackler <durin42@gmail.com>
parents: 10282
diff changeset
   299
    numupdates = len(action)
ba5e508b5e92 update: make calls to ui.progress()
Augie Fackler <durin42@gmail.com>
parents: 10282
diff changeset
   300
    for i, a in enumerate(action):
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   301
        f, m = a[:2]
12746
8b438cb84c57 merge/progress: marking strings for localization
timeless <timeless@gmail.com>
parents: 12681
diff changeset
   302
        u.progress(_('updating'), i + 1, item=f, total=numupdates,
8b438cb84c57 merge/progress: marking strings for localization
timeless <timeless@gmail.com>
parents: 12681
diff changeset
   303
                   unit=_('files'))
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   304
        if f and f[0] == "/":
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   305
            continue
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   306
        if m == "r": # remove
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   307
            repo.ui.note(_("removing %s\n") % f)
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5060
diff changeset
   308
            audit_path(f)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   309
            if f == '.hgsubstate': # subrepo states need updating
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   310
                subrepo.submerge(repo, wctx, mctx, wctx)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   311
            try:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   312
                util.unlink(repo.wjoin(f))
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   313
            except OSError, inst:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   314
                if inst.errno != errno.ENOENT:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   315
                    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
   316
                                 (f, inst.strerror))
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3618
diff changeset
   317
            removed += 1
3308
ecc1bf27378c merge: unify merge and copy actions
Matt Mackall <mpm@selenic.com>
parents: 3307
diff changeset
   318
        elif m == "m": # merge
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   319
            if f == '.hgsubstate': # subrepo states need updating
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   320
                subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx))
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   321
                continue
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   322
            f2, fd, flags, move = a[2:]
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   323
            r = ms.resolve(fd, wctx, mctx)
9030
3f56055ff1d7 compat: can't compare two values of unequal datatypes
Alejandro Santos <alejolp@alejolp.com>
parents: 8814
diff changeset
   324
            if r is not None and r > 0:
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   325
                unresolved += 1
3309
e8be5942335d merge: pull file copy/move out of filemerge
Matt Mackall <mpm@selenic.com>
parents: 3308
diff changeset
   326
            else:
3400
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
   327
                if r is None:
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
   328
                    updated += 1
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
   329
                else:
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
   330
                    merged += 1
6877
1d38f3605b20 util: set_flags shouldn't know about repo flag formats
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   331
            util.set_flags(repo.wjoin(fd), 'l' in flags, 'x' in flags)
12032
ad787252fed6 util: remove lexists, Python 2.4 introduced os.path.lexists
Martin Geisler <mg@lazybytes.net>
parents: 12010
diff changeset
   332
            if f != fd and move and os.path.lexists(repo.wjoin(f)):
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9048
diff changeset
   333
                repo.ui.debug("removing %s\n" % f)
5042
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   334
                os.unlink(repo.wjoin(f))
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   335
        elif m == "g": # get
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   336
            flags = a[2]
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   337
            repo.ui.note(_("getting %s\n") % f)
3303
488d3062d225 merge: eliminate nodes from action list
Matt Mackall <mpm@selenic.com>
parents: 3299
diff changeset
   338
            t = mctx.filectx(f).data()
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   339
            repo.wwrite(f, t, flags)
11755
7d2aaeea67ed merge: drop reference to file contents after write
Matt Mackall <mpm@selenic.com>
parents: 11716
diff changeset
   340
            t = None
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   341
            updated += 1
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   342
            if f == '.hgsubstate': # subrepo states need updating
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   343
                subrepo.submerge(repo, wctx, mctx, wctx)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   344
        elif m == "d": # directory rename
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   345
            f2, fd, flags = a[2:]
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   346
            if f:
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   347
                repo.ui.note(_("moving %s to %s\n") % (f, fd))
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   348
                t = wctx.filectx(f).data()
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   349
                repo.wwrite(fd, t, flags)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   350
                util.unlink(repo.wjoin(f))
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   351
            if f2:
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   352
                repo.ui.note(_("getting %s to %s\n") % (f2, fd))
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   353
                t = mctx.filectx(f2).data()
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   354
                repo.wwrite(fd, t, flags)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   355
            updated += 1
4674
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
   356
        elif m == "dr": # divergent renames
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
   357
            fl = a[2]
12757
62c8f7691bc3 merge: make 'diverging renames' diagnostic a more helpful note.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 12746
diff changeset
   358
            repo.ui.warn(_("note: possible conflict - %s was renamed "
62c8f7691bc3 merge: make 'diverging renames' diagnostic a more helpful note.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 12746
diff changeset
   359
                           "multiple times to:\n") % f)
4674
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
   360
            for nf in fl:
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
   361
                repo.ui.warn(" %s\n" % nf)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   362
        elif m == "e": # exec
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   363
            flags = a[2]
6877
1d38f3605b20 util: set_flags shouldn't know about repo flag formats
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   364
            util.set_flags(repo.wjoin(f), 'l' in flags, 'x' in flags)
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
   365
    ms.commit()
12746
8b438cb84c57 merge/progress: marking strings for localization
timeless <timeless@gmail.com>
parents: 12681
diff changeset
   366
    u.progress(_('updating'), None, total=numupdates, unit=_('files'))
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   367
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   368
    return updated, merged, removed, unresolved
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   369
3372
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   370
def recordupdates(repo, action, branchmerge):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   371
    "record merge actions to the dirstate"
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   372
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   373
    for a in action:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   374
        f, m = a[:2]
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   375
        if m == "r": # remove
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   376
            if branchmerge:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   377
                repo.dirstate.remove(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   378
            else:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   379
                repo.dirstate.forget(f)
7768
5bf5fd1e2a74 merge: mark kept local files as readded on linear update (issue539)
Matt Mackall <mpm@selenic.com>
parents: 7631
diff changeset
   380
        elif m == "a": # re-add
5bf5fd1e2a74 merge: mark kept local files as readded on linear update (issue539)
Matt Mackall <mpm@selenic.com>
parents: 7631
diff changeset
   381
            if not branchmerge:
5bf5fd1e2a74 merge: mark kept local files as readded on linear update (issue539)
Matt Mackall <mpm@selenic.com>
parents: 7631
diff changeset
   382
                repo.dirstate.add(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   383
        elif m == "f": # forget
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   384
            repo.dirstate.forget(f)
7569
89207edf3973 correctly update dirstate after update+mode change (issue1456)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7066
diff changeset
   385
        elif m == "e": # exec change
7630
a679bd371091 merge: fix execute bit update issue introduced by 89207edf3973
Patrick Mezard <pmezard@gmail.com>
parents: 7569
diff changeset
   386
            repo.dirstate.normallookup(f)
7569
89207edf3973 correctly update dirstate after update+mode change (issue1456)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7066
diff changeset
   387
        elif m == "g": # get
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   388
            if branchmerge:
10968
7a0d096e221e dirstate: more explicit name, rename normaldirty() to otherparent()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10492
diff changeset
   389
                repo.dirstate.otherparent(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   390
            else:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   391
                repo.dirstate.normal(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   392
        elif m == "m": # merge
3303
488d3062d225 merge: eliminate nodes from action list
Matt Mackall <mpm@selenic.com>
parents: 3299
diff changeset
   393
            f2, fd, flag, move = a[2:]
3251
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   394
            if branchmerge:
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   395
                # 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
   396
                # so that we properly record the merger later
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   397
                repo.dirstate.merge(fd)
3372
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   398
                if f != f2: # copy/rename
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   399
                    if move:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   400
                        repo.dirstate.remove(f)
3372
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   401
                    if f != fd:
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   402
                        repo.dirstate.copy(f, fd)
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   403
                    else:
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   404
                        repo.dirstate.copy(f2, fd)
3251
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   405
            else:
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   406
                # We've update-merged a locally modified file, so
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   407
                # we set the dirstate to emulate a normal checkout
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   408
                # 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
   409
                # merge will appear as a normal local file
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   410
                # modification.
11178
21a7ae13208f merge: avoid to break the dirstate copy status on moved files
Gilles Moris <gilles.moris@free.fr>
parents: 11101
diff changeset
   411
                if f2 == fd: # file not locally copied/moved
21a7ae13208f merge: avoid to break the dirstate copy status on moved files
Gilles Moris <gilles.moris@free.fr>
parents: 11101
diff changeset
   412
                    repo.dirstate.normallookup(fd)
3308
ecc1bf27378c merge: unify merge and copy actions
Matt Mackall <mpm@selenic.com>
parents: 3307
diff changeset
   413
                if move:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   414
                    repo.dirstate.forget(f)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   415
        elif m == "d": # directory rename
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   416
            f2, fd, flag = a[2:]
4819
9797124581c9 merge: fix adding untracked files on directory rename (issue612)
Matt Mackall <mpm@selenic.com>
parents: 4748
diff changeset
   417
            if not f2 and f not in repo.dirstate:
9797124581c9 merge: fix adding untracked files on directory rename (issue612)
Matt Mackall <mpm@selenic.com>
parents: 4748
diff changeset
   418
                # untracked file moved
9797124581c9 merge: fix adding untracked files on directory rename (issue612)
Matt Mackall <mpm@selenic.com>
parents: 4748
diff changeset
   419
                continue
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   420
            if branchmerge:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   421
                repo.dirstate.add(fd)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   422
                if f:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   423
                    repo.dirstate.remove(f)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   424
                    repo.dirstate.copy(f, fd)
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   425
                if f2:
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   426
                    repo.dirstate.copy(f2, fd)
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   427
            else:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   428
                repo.dirstate.normal(fd)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   429
                if f:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   430
                    repo.dirstate.forget(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   431
4917
126f527b3ba3 Make repo locks recursive, eliminate all passing of lock/wlock
Matt Mackall <mpm@selenic.com>
parents: 4915
diff changeset
   432
def update(repo, node, branchmerge, force, partial):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   433
    """
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   434
    Perform a merge between the working directory and the given node
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   435
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   436
    node = the node to update to, or None if unspecified
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   437
    branchmerge = whether to merge between branches
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   438
    force = whether to force branch merging or file overwriting
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   439
    partial = a function to filter file lists (dirstate not updated)
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   440
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   441
    The table below shows all the behaviors of the update command
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   442
    given the -c and -C or no options, whether the working directory
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   443
    is dirty, whether a revision is specified, and the relationship of
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   444
    the parent rev to the target rev (linear, on the same named
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   445
    branch, or on another named branch).
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   446
12279
28e2e3804f2e combine tests
Adrian Buehlmann <adrian@cadifra.com>
parents: 12032
diff changeset
   447
    This logic is tested by test-update-branches.t.
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   448
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   449
    -c  -C  dirty  rev  |  linear   same  cross
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   450
     n   n    n     n   |    ok     (1)     x
9717
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   451
     n   n    n     y   |    ok     ok     ok
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   452
     n   n    y     *   |   merge   (2)    (2)
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   453
     n   y    *     *   |    ---  discard  ---
9717
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   454
     y   n    y     *   |    ---    (3)    ---
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   455
     y   n    n     *   |    ---    ok     ---
9717
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   456
     y   y    *     *   |    ---    (4)    ---
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   457
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   458
    x = can't happen
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   459
    * = don't-care
9717
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   460
    1 = abort: crosses branches (use 'hg merge' or 'hg update -c')
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   461
    2 = abort: crosses branches (use 'hg merge' to merge or
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   462
                 use 'hg update -C' to discard changes)
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   463
    3 = abort: uncommitted local changes
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   464
    4 = incompatible options (checked in commands.py)
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   465
    """
2815
4870f795f681 Merge: combine force and forcemerge arguments
Matt Mackall <mpm@selenic.com>
parents: 2814
diff changeset
   466
9717
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   467
    onode = node
4917
126f527b3ba3 Make repo locks recursive, eliminate all passing of lock/wlock
Matt Mackall <mpm@selenic.com>
parents: 4915
diff changeset
   468
    wlock = repo.wlock()
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   469
    try:
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6746
diff changeset
   470
        wc = repo[None]
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   471
        if node is None:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   472
            # tip of current branch
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   473
            try:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   474
                node = repo.branchtags()[wc.branch()]
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   475
            except KeyError:
5570
78a6b985882f update: default to tipmost branch if default branch doesn't exist
Matt Mackall <mpm@selenic.com>
parents: 5489
diff changeset
   476
                if wc.branch() == "default": # no default branch!
78a6b985882f update: default to tipmost branch if default branch doesn't exist
Matt Mackall <mpm@selenic.com>
parents: 5489
diff changeset
   477
                    node = repo.lookup("tip") # update to tip
78a6b985882f update: default to tipmost branch if default branch doesn't exist
Matt Mackall <mpm@selenic.com>
parents: 5489
diff changeset
   478
                else:
78a6b985882f update: default to tipmost branch if default branch doesn't exist
Matt Mackall <mpm@selenic.com>
parents: 5489
diff changeset
   479
                    raise util.Abort(_("branch %s not found") % wc.branch())
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   480
        overwrite = force and not branchmerge
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   481
        pl = wc.parents()
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6746
diff changeset
   482
        p1, p2 = pl[0], repo[node]
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   483
        pa = p1.ancestor(p2)
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   484
        fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   485
        fastforward = False
3314
b16456909a0a merge: various tidying
Matt Mackall <mpm@selenic.com>
parents: 3312
diff changeset
   486
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   487
        ### check phase
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   488
        if not overwrite and len(pl) > 1:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   489
            raise util.Abort(_("outstanding uncommitted merges"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   490
        if branchmerge:
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   491
            if pa == p2:
11417
6f1d1ed3e19a merge: improve merge with ancestor message
Matt Mackall <mpm@selenic.com>
parents: 11178
diff changeset
   492
                raise util.Abort(_("merging with a working directory ancestor"
6f1d1ed3e19a merge: improve merge with ancestor message
Matt Mackall <mpm@selenic.com>
parents: 11178
diff changeset
   493
                                   " has no effect"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   494
            elif pa == p1:
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   495
                if p1.branch() != p2.branch():
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   496
                    fastforward = True
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   497
                else:
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   498
                    raise util.Abort(_("nothing to merge (use 'hg update'"
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   499
                                       " or check 'hg heads')"))
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   500
            if not force and (wc.files() or wc.deleted()):
8545
3682a19bb637 merge: give hint as to how to discover uncommitted changes
Steve Borho <steve@borho.org>
parents: 8518
diff changeset
   501
                raise util.Abort(_("outstanding uncommitted changes "
3682a19bb637 merge: give hint as to how to discover uncommitted changes
Steve Borho <steve@borho.org>
parents: 8518
diff changeset
   502
                                   "(use 'hg status' to list changes)"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   503
        elif not overwrite:
12401
4cdaf1adafc8 backout most of 4f8067c94729
Matt Mackall <mpm@selenic.com>
parents: 12387
diff changeset
   504
            if pa == p1 or pa == p2: # linear
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   505
                pass # all good
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   506
            elif wc.files() or wc.deleted():
12681
bc13e17067d9 update: use higher level wording for "crosses branches" error
Brodie Rao <brodie@bitheap.org>
parents: 12664
diff changeset
   507
                raise util.Abort(_("crosses branches (merge branches or use"
bc13e17067d9 update: use higher level wording for "crosses branches" error
Brodie Rao <brodie@bitheap.org>
parents: 12664
diff changeset
   508
                                   " --clean to discard changes)"))
9717
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   509
            elif onode is None:
12681
bc13e17067d9 update: use higher level wording for "crosses branches" error
Brodie Rao <brodie@bitheap.org>
parents: 12664
diff changeset
   510
                raise util.Abort(_("crosses branches (merge branches or use"
bc13e17067d9 update: use higher level wording for "crosses branches" error
Brodie Rao <brodie@bitheap.org>
parents: 12664
diff changeset
   511
                                   " --check to force update)"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   512
            else:
9717
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   513
                # Allow jumping branches if clean and specific rev given
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   514
                overwrite = True
2814
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
   515
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   516
        ### calculate phase
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   517
        action = []
11101
502474839293 context: only scan unknowns when needed
Matt Mackall <mpm@selenic.com>
parents: 10968
diff changeset
   518
        wc.status(unknown=True) # prime cache
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   519
        if not force:
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
   520
            _checkunknown(wc, p2)
6746
1dca460e7d1e rename checkfolding to checkcase
Matt Mackall <mpm@selenic.com>
parents: 6740
diff changeset
   521
        if not util.checkcase(repo.path):
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
   522
            _checkcollision(p2)
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
   523
        action += _forgetremoved(wc, p2, branchmerge)
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   524
        action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   525
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   526
        ### apply phase
13158
9e7e24052745 merge: fast-forward merge with descendant
Mads Kiilerich <mads@kiilerich.com>
parents: 12757
diff changeset
   527
        if not branchmerge or fastforward: # just jump to the new rev
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   528
            fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   529
        if not partial:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   530
            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
   531
11454
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   532
        stats = applyupdates(repo, action, wc, p2, pa)
2899
8743188f4d2e merge: consolidate dirstate updates
Matt Mackall <mpm@selenic.com>
parents: 2898
diff changeset
   533
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   534
        if not partial:
10968
7a0d096e221e dirstate: more explicit name, rename normaldirty() to otherparent()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10492
diff changeset
   535
            repo.dirstate.setparents(fp1, fp2)
13158
9e7e24052745 merge: fast-forward merge with descendant
Mads Kiilerich <mads@kiilerich.com>
parents: 12757
diff changeset
   536
            recordupdates(repo, action, branchmerge and not fastforward)
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   537
            if not branchmerge and not fastforward:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   538
                repo.dirstate.setbranch(p2.branch())
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   539
    finally:
8109
496ae1ea4698 switch lock releasing in the core from gc to explicit
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7848
diff changeset
   540
        wlock.release()
10492
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
   541
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
   542
    if not partial:
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
   543
        repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
   544
    return stats