mercurial/merge.py
author Mads Kiilerich <mads@kiilerich.com>
Thu, 18 Oct 2012 00:33:29 +0200
changeset 17800 f3c36faa7374
parent 16794 98687cdddcb1
child 17889 ce7bc04d863b
permissions -rw-r--r--
run-tests: handle windows crlf in .py tests again Before af7c6bc48d8d all crlf occurrences in test output on Windows were simply changed to lf. In af7c6bc48d8d it was replaced by more clever handling in the .t test runner ... but the .py runner was forgotten and many .py tests were failing on Windows. The crlf/lf replacement is now reintroduced in the py test runner.
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 _
16719
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16696
diff changeset
    10
import error, scmutil, 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:]
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13323
diff changeset
    35
            f.close()
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    36
        except IOError, err:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    37
            if err.errno != errno.ENOENT:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    38
                raise
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    39
        self._dirty = False
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    40
    def commit(self):
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    41
        if self._dirty:
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    42
            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
    43
            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
    44
            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
    45
                f.write("\0".join([d] + v) + "\n")
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13323
diff changeset
    46
            f.close()
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
    47
            self._dirty = False
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    48
    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
    49
        hash = util.sha1(fcl.path()).hexdigest()
14168
135e244776f0 prevent transient leaks of file handle by using new helper functions
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14064
diff changeset
    50
        self._repo.opener.write("merge/" + hash, fcl.data())
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    51
        self._state[fd] = ['u', hash, fcl.path(), fca.path(),
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    52
                           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
    53
        self._dirty = True
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    54
    def __contains__(self, dfile):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    55
        return dfile in self._state
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    56
    def __getitem__(self, dfile):
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    57
        return self._state[dfile][0]
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    58
    def __iter__(self):
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    59
        l = self._state.keys()
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    60
        l.sort()
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    61
        for f in l:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    62
            yield f
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    63
    def mark(self, dfile, state):
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    64
        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
    65
        self._dirty = True
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    66
    def resolve(self, dfile, wctx, octx):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    67
        if self[dfile] == 'r':
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    68
            return 0
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    69
        state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    70
        f = self._repo.opener("merge/" + hash)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    71
        self._repo.wwrite(dfile, f.read(), flags)
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13323
diff changeset
    72
        f.close()
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    73
        fcd = wctx[dfile]
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    74
        fco = octx[ofile]
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    75
        fca = self._repo.filectx(afile, fileid=anode)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    76
        r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
13536
fac040b7e822 merge: drop resolve state for mergers with identical contents (issue2680)
Matt Mackall <mpm@selenic.com>
parents: 13437
diff changeset
    77
        if r is None:
fac040b7e822 merge: drop resolve state for mergers with identical contents (issue2680)
Matt Mackall <mpm@selenic.com>
parents: 13437
diff changeset
    78
            # no real conflict
fac040b7e822 merge: drop resolve state for mergers with identical contents (issue2680)
Matt Mackall <mpm@selenic.com>
parents: 13437
diff changeset
    79
            del self._state[dfile]
fac040b7e822 merge: drop resolve state for mergers with identical contents (issue2680)
Matt Mackall <mpm@selenic.com>
parents: 13437
diff changeset
    80
        elif not r:
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    81
            self.mark(dfile, 'r')
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    82
        return r
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
16093
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
    84
def _checkunknownfile(repo, wctx, mctx, f):
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
    85
    return (not repo.dirstate._ignore(f)
16534
11212babc690 merge: check for untracked files more precisely (issue3400)
Matt Mackall <mpm@selenic.com>
parents: 16492
diff changeset
    86
        and os.path.isfile(repo.wjoin(f))
16284
2b0a406d3043 merge: fix unknown file merge detection for case-folding systems
Matt Mackall <mpm@selenic.com>
parents: 16261
diff changeset
    87
        and repo.dirstate.normalize(f) not in repo.dirstate
16093
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
    88
        and mctx[f].cmp(wctx[f]))
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
    89
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
    90
def _checkunknown(repo, wctx, mctx):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
    91
    "check for collisions between unknown files and files in mctx"
15894
44fa047cef57 merge: report all files in _checkunknown
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 15774
diff changeset
    92
44fa047cef57 merge: report all files in _checkunknown
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 15774
diff changeset
    93
    error = False
16093
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
    94
    for f in mctx:
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
    95
        if f not in wctx and _checkunknownfile(repo, wctx, mctx, f):
15894
44fa047cef57 merge: report all files in _checkunknown
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 15774
diff changeset
    96
            error = True
16093
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
    97
            wctx._repo.ui.warn(_("%s: untracked file differs\n") % f)
15894
44fa047cef57 merge: report all files in _checkunknown
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 15774
diff changeset
    98
    if error:
44fa047cef57 merge: report all files in _checkunknown
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 15774
diff changeset
    99
        raise util.Abort(_("untracked files in working directory differ "
44fa047cef57 merge: report all files in _checkunknown
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 15774
diff changeset
   100
                           "from files in requested revision"))
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   101
15673
d550168f11ce merge: check filename case collision between changesets for branch merging
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15637
diff changeset
   102
def _checkcollision(mctx, wctx):
3785
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
   103
    "check for case folding collisions in the destination context"
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
   104
    folded = {}
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
   105
    for fn in mctx:
15637
7f01ad702405 icasefs: use util.normcase() instead of str.lower() or os.path.normpath()
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15538
diff changeset
   106
        fold = util.normcase(fn)
3785
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
   107
        if fold in folded:
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
   108
            raise util.Abort(_("case-folding collision between %s and %s")
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
   109
                             % (fn, folded[fold]))
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
   110
        folded[fold] = fn
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
   111
15673
d550168f11ce merge: check filename case collision between changesets for branch merging
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15637
diff changeset
   112
    if wctx:
16478
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   113
        # class to delay looking up copy mapping
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   114
        class pathcopies(object):
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   115
            @util.propertycache
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   116
            def map(self):
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   117
                # {dst@mctx: src@wctx} copy mapping
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   118
                return copies.pathcopies(wctx, mctx)
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   119
        pc = pathcopies()
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   120
15673
d550168f11ce merge: check filename case collision between changesets for branch merging
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15637
diff changeset
   121
        for fn in wctx:
d550168f11ce merge: check filename case collision between changesets for branch merging
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15637
diff changeset
   122
            fold = util.normcase(fn)
d550168f11ce merge: check filename case collision between changesets for branch merging
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15637
diff changeset
   123
            mfn = folded.get(fold, None)
16478
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   124
            if mfn and mfn != fn and pc.map.get(mfn) != fn:
15673
d550168f11ce merge: check filename case collision between changesets for branch merging
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15637
diff changeset
   125
                raise util.Abort(_("case-folding collision between %s and %s")
d550168f11ce merge: check filename case collision between changesets for branch merging
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15637
diff changeset
   126
                                 % (mfn, fn))
d550168f11ce merge: check filename case collision between changesets for branch merging
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15637
diff changeset
   127
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
   128
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
   129
    """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   130
    Forget removed files
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   131
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   132
    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
   133
    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
   134
    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
   135
    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
   136
    manifest.
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   137
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   138
    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
   139
    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
   140
    as removed.
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   141
    """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   142
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   143
    action = []
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   144
    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
   145
    for f in wctx.deleted():
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
   146
        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
   147
            action.append((f, state))
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   148
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   149
    if not branchmerge:
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   150
        for f in wctx.removed():
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
   151
            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
   152
                action.append((f, "f"))
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   153
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   154
    return action
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   155
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
   156
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
   157
    """
11817
d12fe809e1ee merge: fix typo in docstring
Alecs King <alecsk@gmail.com>
parents: 11759
diff changeset
   158
    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
   159
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   160
    overwrite = whether we clobber working files
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   161
    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
   162
    """
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   163
8733
f8be48c6b08c merge: simplify flag merging code slightly
Matt Mackall <mpm@selenic.com>
parents: 8545
diff changeset
   164
    def fmerge(f, f2, fa):
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   165
        """merge flags"""
5708
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   166
        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
   167
        if m == n: # flags agree
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   168
            return m # unchanged
8733
f8be48c6b08c merge: simplify flag merging code slightly
Matt Mackall <mpm@selenic.com>
parents: 8545
diff changeset
   169
        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
   170
            r = repo.ui.promptchoice(
8733
f8be48c6b08c merge: simplify flag merging code slightly
Matt Mackall <mpm@selenic.com>
parents: 8545
diff changeset
   171
                _(" conflicting flags for %s\n"
f8be48c6b08c merge: simplify flag merging code slightly
Matt Mackall <mpm@selenic.com>
parents: 8545
diff changeset
   172
                  "(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
   173
                (_("&None"), _("E&xec"), _("Sym&link")), 0)
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   174
            if r == 1:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   175
                return "x" # Exec
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   176
            if r == 2:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   177
                return "l" # Symlink
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 9030
diff changeset
   178
            return ""
5708
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   179
        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
   180
            return m
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   181
        if n and n != a: # changed from a to n
16257
7a5524f240ad merge: accept missing revisions in symlink flag merge (issue3316)
Matt Mackall <mpm@selenic.com>
parents: 16255
diff changeset
   182
            if (n == 'l' or a == 'l') and m1.get(f) != ma.get(f):
16255
ca5cc2976574 merge: handle linear update to symlink correctly (issue3316)
Matt Mackall <mpm@selenic.com>
parents: 16001
diff changeset
   183
                # can't automatically merge symlink flag when there
ca5cc2976574 merge: handle linear update to symlink correctly (issue3316)
Matt Mackall <mpm@selenic.com>
parents: 16001
diff changeset
   184
                # are file-level conflicts here, let filemerge take
ca5cc2976574 merge: handle linear update to symlink correctly (issue3316)
Matt Mackall <mpm@selenic.com>
parents: 16001
diff changeset
   185
                # care of it
16001
fcf66193b186 merge: defer symlink flag merging to filemerge (issue3200)
Matt Mackall <mpm@selenic.com>
parents: 15894
diff changeset
   186
                return m
5708
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   187
            return n
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
   188
        return '' # flag was cleared
3118
5644a05a608c merge: simplify exec flag handling
Matt Mackall <mpm@selenic.com>
parents: 3117
diff changeset
   189
3307
f009a6f12a59 merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents: 3306
diff changeset
   190
    def act(msg, m, f, *args):
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
   191
        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
   192
        action.append((f, m) + args)
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
   193
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   194
    action, copy = [], {}
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   195
8749
69caf50da4a0 merge: refactor some initialization, drop backwards var
Matt Mackall <mpm@selenic.com>
parents: 8748
diff changeset
   196
    if overwrite:
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   197
        pa = p1
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   198
    elif pa == p2: # backwards
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   199
        pa = p1.p1()
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   200
    elif pa and repo.ui.configbool("merge", "followcopies", True):
16794
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16719
diff changeset
   201
        copy, diverge, renamedelete = copies.mergecopies(repo, p1, p2, pa)
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   202
        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
   203
            act("divergent renames", "dr", of, fl)
16794
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16719
diff changeset
   204
        for of, fl in renamedelete.iteritems():
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16719
diff changeset
   205
            act("rename and delete", "rd", of, fl)
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   206
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   207
    repo.ui.note(_("resolving manifests\n"))
15625
efdcce3fd2d5 merge: make debug output easier to read
Martin Geisler <mg@aragost.com>
parents: 15619
diff changeset
   208
    repo.ui.debug(" overwrite: %s, partial: %s\n"
efdcce3fd2d5 merge: make debug output easier to read
Martin Geisler <mg@aragost.com>
parents: 15619
diff changeset
   209
                  % (bool(overwrite), bool(partial)))
efdcce3fd2d5 merge: make debug output easier to read
Martin Geisler <mg@aragost.com>
parents: 15619
diff changeset
   210
    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
   211
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   212
    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
   213
    copied = set(copy.values())
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
   214
11470
34e33d50c26b subrepo: correctly handle update -C with modified subrepos (issue2022)
Matt Mackall <mpm@selenic.com>
parents: 11466
diff changeset
   215
    if '.hgsubstate' in m1:
9783
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   216
        # check whether sub state is modified
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   217
        for s in p1.substate:
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   218
            if p1.sub(s).dirty():
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   219
                m1['.hgsubstate'] += "+"
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   220
                break
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   221
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   222
    # Compare manifests
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   223
    for f, n in m1.iteritems():
3248
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   224
        if partial and not partial(f):
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   225
            continue
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   226
        if f in m2:
8735
ff8519c437c6 merge: remove a flags case
Matt Mackall <mpm@selenic.com>
parents: 8734
diff changeset
   227
            rflags = fmerge(f, f, f)
8752
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   228
            a = ma.get(f, nullid)
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   229
            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
   230
                # 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
   231
                # 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
   232
                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
   233
                    act("update permissions", "e", f, rflags)
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   234
            elif n == a: # remote newer
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   235
                act("remote is newer", "g", f, rflags)
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   236
            else: # both changed
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   237
                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
   238
        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
   239
            pass
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   240
        elif f in copy:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   241
            f2 = copy[f]
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   242
            if f2 not in m2: # directory rename
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   243
                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
   244
                    f, None, f2, m1.flags(f))
8748
f325574dad1a merge: combine a copy and move case
Matt Mackall <mpm@selenic.com>
parents: 8747
diff changeset
   245
            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
   246
                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
   247
                    f, f2, f, fmerge(f, f2, f2), False)
8744
6b675c781c6d merge: simplify 'other deleted' case
Matt Mackall <mpm@selenic.com>
parents: 8743
diff changeset
   248
        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
   249
            if n != ma[f]:
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 9030
diff changeset
   250
                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
   251
                    _(" 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
   252
                      "use (c)hanged version or (d)elete?") % f,
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 9030
diff changeset
   253
                    (_("&Changed"), _("&Delete")), 0):
3307
f009a6f12a59 merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents: 3306
diff changeset
   254
                    act("prompt delete", "r", f)
8736
7619b16ea880 merge: fix prompt keep
Matt Mackall <mpm@selenic.com>
parents: 8735
diff changeset
   255
                else:
7619b16ea880 merge: fix prompt keep
Matt Mackall <mpm@selenic.com>
parents: 8735
diff changeset
   256
                    act("prompt keep", "a", f)
8751
e8d80e0835c7 merge: make locally-added file test more correct
Matt Mackall <mpm@selenic.com>
parents: 8750
diff changeset
   257
            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
   258
                act("remote deleted", "f", f)
16094
0776a6cababe merge: don't use unknown()
Matt Mackall <mpm@selenic.com>
parents: 16093
diff changeset
   259
            else:
3307
f009a6f12a59 merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents: 3306
diff changeset
   260
                act("other deleted", "r", f)
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   261
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   262
    for f, n in m2.iteritems():
3248
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   263
        if partial and not partial(f):
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   264
            continue
8752
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   265
        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
   266
            continue
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   267
        if f in copy:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   268
            f2 = copy[f]
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   269
            if f2 not in m1: # directory rename
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   270
                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
   271
                    None, f, f2, m2.flags(f))
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   272
            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
   273
                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
   274
                    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
   275
            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
   276
                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
   277
                    f2, f, f, fmerge(f2, f, f2), True)
8741
e592180ba435 merge: reorder remote creation tests
Matt Mackall <mpm@selenic.com>
parents: 8740
diff changeset
   278
        elif f not in ma:
16094
0776a6cababe merge: don't use unknown()
Matt Mackall <mpm@selenic.com>
parents: 16093
diff changeset
   279
            if (not overwrite
0776a6cababe merge: don't use unknown()
Matt Mackall <mpm@selenic.com>
parents: 16093
diff changeset
   280
                and _checkunknownfile(repo, p1, p2, f)):
0776a6cababe merge: don't use unknown()
Matt Mackall <mpm@selenic.com>
parents: 16093
diff changeset
   281
                rflags = fmerge(f, f, f)
0776a6cababe merge: don't use unknown()
Matt Mackall <mpm@selenic.com>
parents: 16093
diff changeset
   282
                act("remote differs from untracked local",
0776a6cababe merge: don't use unknown()
Matt Mackall <mpm@selenic.com>
parents: 16093
diff changeset
   283
                    "m", f, f, f, rflags, False)
0776a6cababe merge: don't use unknown()
Matt Mackall <mpm@selenic.com>
parents: 16093
diff changeset
   284
            else:
0776a6cababe merge: don't use unknown()
Matt Mackall <mpm@selenic.com>
parents: 16093
diff changeset
   285
                act("remote created", "g", f, m2.flags(f))
8741
e592180ba435 merge: reorder remote creation tests
Matt Mackall <mpm@selenic.com>
parents: 8740
diff changeset
   286
        elif n != ma[f]:
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 9030
diff changeset
   287
            if repo.ui.promptchoice(
8741
e592180ba435 merge: reorder remote creation tests
Matt Mackall <mpm@selenic.com>
parents: 8740
diff changeset
   288
                _("remote changed %s which local deleted\n"
e592180ba435 merge: reorder remote creation tests
Matt Mackall <mpm@selenic.com>
parents: 8740
diff changeset
   289
                  "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
   290
                (_("&Changed"), _("&Deleted")), 0) == 0:
8741
e592180ba435 merge: reorder remote creation tests
Matt Mackall <mpm@selenic.com>
parents: 8740
diff changeset
   291
                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
   292
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   293
    return action
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   294
8366
0bf0045000b5 some modernization cleanups, forward compatibility
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8312
diff changeset
   295
def actionkey(a):
0bf0045000b5 some modernization cleanups, forward compatibility
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8312
diff changeset
   296
    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
   297
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 12757
diff changeset
   298
def applyupdates(repo, action, wctx, mctx, actx, overwrite):
11454
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   299
    """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
   300
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   301
    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
   302
    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
   303
    actx is the context of the common ancestor
13162
115a9760c382 merge: document some internal return values.
Greg Ward <greg-hg@gerg.ca>
parents: 13158
diff changeset
   304
115a9760c382 merge: document some internal return values.
Greg Ward <greg-hg@gerg.ca>
parents: 13158
diff changeset
   305
    Return a tuple of counts (updated, merged, removed, unresolved) that
115a9760c382 merge: document some internal return values.
Greg Ward <greg-hg@gerg.ca>
parents: 13158
diff changeset
   306
    describes how many files were affected by the update.
11454
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   307
    """
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   308
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   309
    updated, merged, removed, unresolved = 0, 0, 0, 0
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   310
    ms = mergestate(repo)
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 13874
diff changeset
   311
    ms.reset(wctx.p1().node())
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   312
    moves = []
8366
0bf0045000b5 some modernization cleanups, forward compatibility
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8312
diff changeset
   313
    action.sort(key=actionkey)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   314
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   315
    # prescan for merges
5042
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   316
    for a in action:
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   317
        f, m = a[:2]
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   318
        if m == 'm': # merge
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   319
            f2, fd, flags, move = a[2:]
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   320
            if f == '.hgsubstate': # merged internally
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   321
                continue
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9048
diff changeset
   322
            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
   323
            fcl = wctx[f]
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   324
            fco = mctx[f2]
12008
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   325
            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
   326
                if fcl.parents():
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 13874
diff changeset
   327
                    fca = fcl.p1()
12664
545ec1775021 merge: handle no file parent in backwards merge (issue2364)
Matt Mackall <mpm@selenic.com>
parents: 12401
diff changeset
   328
                else:
545ec1775021 merge: handle no file parent in backwards merge (issue2364)
Matt Mackall <mpm@selenic.com>
parents: 12401
diff changeset
   329
                    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
   330
            else:
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   331
                fca = fcl.ancestor(fco, actx)
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   332
            if not fca:
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   333
                fca = repo.filectx(f, fileid=nullrev)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   334
            ms.add(fcl, fco, fca, fd, flags)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   335
            if f != fd and move:
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   336
                moves.append(f)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   337
14398
ae1f7a5373e8 applyupdates: audit unlinking of renamed files and directories
Adrian Buehlmann <adrian@cadifra.com>
parents: 14232
diff changeset
   338
    audit = scmutil.pathauditor(repo.root)
ae1f7a5373e8 applyupdates: audit unlinking of renamed files and directories
Adrian Buehlmann <adrian@cadifra.com>
parents: 14232
diff changeset
   339
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   340
    # remove renamed files after safely stored
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   341
    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
   342
        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
   343
            repo.ui.debug("removing %s\n" % f)
14398
ae1f7a5373e8 applyupdates: audit unlinking of renamed files and directories
Adrian Buehlmann <adrian@cadifra.com>
parents: 14232
diff changeset
   344
            audit(f)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   345
            os.unlink(repo.wjoin(f))
5042
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   346
10431
ba5e508b5e92 update: make calls to ui.progress()
Augie Fackler <durin42@gmail.com>
parents: 10282
diff changeset
   347
    numupdates = len(action)
ba5e508b5e92 update: make calls to ui.progress()
Augie Fackler <durin42@gmail.com>
parents: 10282
diff changeset
   348
    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
   349
        f, m = a[:2]
15041
3afe5edda4e3 merge: use repo.ui directly instead local variable
Martin Geisler <mg@aragost.com>
parents: 14980
diff changeset
   350
        repo.ui.progress(_('updating'), i + 1, item=f, total=numupdates,
3afe5edda4e3 merge: use repo.ui directly instead local variable
Martin Geisler <mg@aragost.com>
parents: 14980
diff changeset
   351
                         unit=_('files'))
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   352
        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
   353
            continue
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   354
        if m == "r": # remove
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   355
            repo.ui.note(_("removing %s\n") % f)
14398
ae1f7a5373e8 applyupdates: audit unlinking of renamed files and directories
Adrian Buehlmann <adrian@cadifra.com>
parents: 14232
diff changeset
   356
            audit(f)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   357
            if f == '.hgsubstate': # subrepo states need updating
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 12757
diff changeset
   358
                subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   359
            try:
13235
6bf39d88c857 rename util.unlink to unlinkpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 13162
diff changeset
   360
                util.unlinkpath(repo.wjoin(f))
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   361
            except OSError, inst:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   362
                if inst.errno != errno.ENOENT:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   363
                    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
   364
                                 (f, inst.strerror))
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3618
diff changeset
   365
            removed += 1
3308
ecc1bf27378c merge: unify merge and copy actions
Matt Mackall <mpm@selenic.com>
parents: 3307
diff changeset
   366
        elif m == "m": # merge
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   367
            if f == '.hgsubstate': # subrepo states need updating
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16551
diff changeset
   368
                subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16551
diff changeset
   369
                                 overwrite)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   370
                continue
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   371
            f2, fd, flags, move = a[2:]
14406
c97c10a1b4bc applyupdates: audit merged files
Adrian Buehlmann <adrian@cadifra.com>
parents: 14405
diff changeset
   372
            repo.wopener.audit(fd)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   373
            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
   374
            if r is not None and r > 0:
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   375
                unresolved += 1
3309
e8be5942335d merge: pull file copy/move out of filemerge
Matt Mackall <mpm@selenic.com>
parents: 3308
diff changeset
   376
            else:
3400
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
   377
                if r is None:
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
   378
                    updated += 1
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
   379
                else:
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
   380
                    merged += 1
13718
5b3383ea67d2 merge: avoid unlinking destination of merge when case changes (issue2715)
Matt Mackall <mpm@selenic.com>
parents: 13550
diff changeset
   381
            if (move and repo.dirstate.normalize(fd) != f
5b3383ea67d2 merge: avoid unlinking destination of merge when case changes (issue2715)
Matt Mackall <mpm@selenic.com>
parents: 13550
diff changeset
   382
                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
   383
                repo.ui.debug("removing %s\n" % f)
14398
ae1f7a5373e8 applyupdates: audit unlinking of renamed files and directories
Adrian Buehlmann <adrian@cadifra.com>
parents: 14232
diff changeset
   384
                audit(f)
5042
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   385
                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
   386
        elif m == "g": # get
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   387
            flags = a[2]
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   388
            repo.ui.note(_("getting %s\n") % f)
3303
488d3062d225 merge: eliminate nodes from action list
Matt Mackall <mpm@selenic.com>
parents: 3299
diff changeset
   389
            t = mctx.filectx(f).data()
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   390
            repo.wwrite(f, t, flags)
11755
7d2aaeea67ed merge: drop reference to file contents after write
Matt Mackall <mpm@selenic.com>
parents: 11716
diff changeset
   391
            t = None
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   392
            updated += 1
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   393
            if f == '.hgsubstate': # subrepo states need updating
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 12757
diff changeset
   394
                subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   395
        elif m == "d": # directory rename
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   396
            f2, fd, flags = a[2:]
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   397
            if f:
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   398
                repo.ui.note(_("moving %s to %s\n") % (f, fd))
14398
ae1f7a5373e8 applyupdates: audit unlinking of renamed files and directories
Adrian Buehlmann <adrian@cadifra.com>
parents: 14232
diff changeset
   399
                audit(f)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   400
                t = wctx.filectx(f).data()
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   401
                repo.wwrite(fd, t, flags)
13235
6bf39d88c857 rename util.unlink to unlinkpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 13162
diff changeset
   402
                util.unlinkpath(repo.wjoin(f))
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   403
            if f2:
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   404
                repo.ui.note(_("getting %s to %s\n") % (f2, fd))
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   405
                t = mctx.filectx(f2).data()
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   406
                repo.wwrite(fd, t, flags)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   407
            updated += 1
4674
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
   408
        elif m == "dr": # divergent renames
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
   409
            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
   410
            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
   411
                           "multiple times to:\n") % f)
4674
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
   412
            for nf in fl:
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
   413
                repo.ui.warn(" %s\n" % nf)
16794
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16719
diff changeset
   414
        elif m == "rd": # rename and delete
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16719
diff changeset
   415
            fl = a[2]
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16719
diff changeset
   416
            repo.ui.warn(_("note: possible conflict - %s was deleted "
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16719
diff changeset
   417
                           "and renamed to:\n") % f)
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16719
diff changeset
   418
            for nf in fl:
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16719
diff changeset
   419
                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
   420
        elif m == "e": # exec
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
   421
            flags = a[2]
14405
f2295a829f47 applyupdates: audit path on flag changes
Adrian Buehlmann <adrian@cadifra.com>
parents: 14398
diff changeset
   422
            repo.wopener.audit(f)
14232
df2399663392 rename util.set_flags to setflags
Adrian Buehlmann <adrian@cadifra.com>
parents: 14220
diff changeset
   423
            util.setflags(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
   424
    ms.commit()
15041
3afe5edda4e3 merge: use repo.ui directly instead local variable
Martin Geisler <mg@aragost.com>
parents: 14980
diff changeset
   425
    repo.ui.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
   426
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   427
    return updated, merged, removed, unresolved
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   428
3372
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   429
def recordupdates(repo, action, branchmerge):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   430
    "record merge actions to the dirstate"
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   431
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   432
    for a in action:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   433
        f, m = a[:2]
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   434
        if m == "r": # remove
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   435
            if branchmerge:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   436
                repo.dirstate.remove(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   437
            else:
14434
cc8c09855d19 dirstate: rename forget to drop
Matt Mackall <mpm@selenic.com>
parents: 14406
diff changeset
   438
                repo.dirstate.drop(f)
7768
5bf5fd1e2a74 merge: mark kept local files as readded on linear update (issue539)
Matt Mackall <mpm@selenic.com>
parents: 7631
diff changeset
   439
        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
   440
            if not branchmerge:
5bf5fd1e2a74 merge: mark kept local files as readded on linear update (issue539)
Matt Mackall <mpm@selenic.com>
parents: 7631
diff changeset
   441
                repo.dirstate.add(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   442
        elif m == "f": # forget
14434
cc8c09855d19 dirstate: rename forget to drop
Matt Mackall <mpm@selenic.com>
parents: 14406
diff changeset
   443
            repo.dirstate.drop(f)
7569
89207edf3973 correctly update dirstate after update+mode change (issue1456)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7066
diff changeset
   444
        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
   445
            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
   446
        elif m == "g": # get
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   447
            if branchmerge:
10968
7a0d096e221e dirstate: more explicit name, rename normaldirty() to otherparent()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10492
diff changeset
   448
                repo.dirstate.otherparent(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   449
            else:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   450
                repo.dirstate.normal(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   451
        elif m == "m": # merge
3303
488d3062d225 merge: eliminate nodes from action list
Matt Mackall <mpm@selenic.com>
parents: 3299
diff changeset
   452
            f2, fd, flag, move = a[2:]
3251
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   453
            if branchmerge:
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   454
                # 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
   455
                # 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
   456
                repo.dirstate.merge(fd)
3372
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   457
                if f != f2: # copy/rename
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   458
                    if move:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   459
                        repo.dirstate.remove(f)
3372
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   460
                    if f != fd:
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   461
                        repo.dirstate.copy(f, fd)
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   462
                    else:
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   463
                        repo.dirstate.copy(f2, fd)
3251
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   464
            else:
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   465
                # We've update-merged a locally modified file, so
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   466
                # we set the dirstate to emulate a normal checkout
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   467
                # 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
   468
                # merge will appear as a normal local file
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   469
                # modification.
11178
21a7ae13208f merge: avoid to break the dirstate copy status on moved files
Gilles Moris <gilles.moris@free.fr>
parents: 11101
diff changeset
   470
                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
   471
                    repo.dirstate.normallookup(fd)
3308
ecc1bf27378c merge: unify merge and copy actions
Matt Mackall <mpm@selenic.com>
parents: 3307
diff changeset
   472
                if move:
14434
cc8c09855d19 dirstate: rename forget to drop
Matt Mackall <mpm@selenic.com>
parents: 14406
diff changeset
   473
                    repo.dirstate.drop(f)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   474
        elif m == "d": # directory rename
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   475
            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
   476
            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
   477
                # untracked file moved
9797124581c9 merge: fix adding untracked files on directory rename (issue612)
Matt Mackall <mpm@selenic.com>
parents: 4748
diff changeset
   478
                continue
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   479
            if branchmerge:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   480
                repo.dirstate.add(fd)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   481
                if f:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   482
                    repo.dirstate.remove(f)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   483
                    repo.dirstate.copy(f, fd)
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   484
                if f2:
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   485
                    repo.dirstate.copy(f2, fd)
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   486
            else:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   487
                repo.dirstate.normal(fd)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   488
                if f:
14434
cc8c09855d19 dirstate: rename forget to drop
Matt Mackall <mpm@selenic.com>
parents: 14406
diff changeset
   489
                    repo.dirstate.drop(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   490
16696
d1afbf03e69a rebase: allow collapsing branches in place (issue3111)
Patrick Mezard <patrick@mezard.eu>
parents: 16683
diff changeset
   491
def update(repo, node, branchmerge, force, partial, ancestor=None,
d1afbf03e69a rebase: allow collapsing branches in place (issue3111)
Patrick Mezard <patrick@mezard.eu>
parents: 16683
diff changeset
   492
           mergeancestor=False):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   493
    """
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   494
    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
   495
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   496
    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
   497
    branchmerge = whether to merge between branches
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   498
    force = whether to force branch merging or file overwriting
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   499
    partial = a function to filter file lists (dirstate not updated)
16696
d1afbf03e69a rebase: allow collapsing branches in place (issue3111)
Patrick Mezard <patrick@mezard.eu>
parents: 16683
diff changeset
   500
    mergeancestor = if false, merging with an ancestor (fast-forward)
d1afbf03e69a rebase: allow collapsing branches in place (issue3111)
Patrick Mezard <patrick@mezard.eu>
parents: 16683
diff changeset
   501
      is only allowed between different named branches. This flag
d1afbf03e69a rebase: allow collapsing branches in place (issue3111)
Patrick Mezard <patrick@mezard.eu>
parents: 16683
diff changeset
   502
      is used by rebase extension as a temporary fix and should be
d1afbf03e69a rebase: allow collapsing branches in place (issue3111)
Patrick Mezard <patrick@mezard.eu>
parents: 16683
diff changeset
   503
      avoided in general.
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   504
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   505
    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
   506
    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
   507
    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
   508
    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
   509
    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
   510
12279
28e2e3804f2e combine tests
Adrian Buehlmann <adrian@cadifra.com>
parents: 12032
diff changeset
   511
    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
   512
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   513
    -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
   514
     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
   515
     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
   516
     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
   517
     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
   518
     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
   519
     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
   520
     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
   521
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   522
    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
   523
    * = 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
   524
    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
   525
    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
   526
                 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
   527
    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
   528
    4 = incompatible options (checked in commands.py)
13162
115a9760c382 merge: document some internal return values.
Greg Ward <greg-hg@gerg.ca>
parents: 13158
diff changeset
   529
115a9760c382 merge: document some internal return values.
Greg Ward <greg-hg@gerg.ca>
parents: 13158
diff changeset
   530
    Return the same tuple as applyupdates().
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   531
    """
2815
4870f795f681 Merge: combine force and forcemerge arguments
Matt Mackall <mpm@selenic.com>
parents: 2814
diff changeset
   532
9717
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   533
    onode = node
4917
126f527b3ba3 Make repo locks recursive, eliminate all passing of lock/wlock
Matt Mackall <mpm@selenic.com>
parents: 4915
diff changeset
   534
    wlock = repo.wlock()
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   535
    try:
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6746
diff changeset
   536
        wc = repo[None]
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   537
        if node is None:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   538
            # tip of current branch
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   539
            try:
16719
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16696
diff changeset
   540
                node = repo.branchtip(wc.branch())
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16696
diff changeset
   541
            except error.RepoLookupError:
5570
78a6b985882f update: default to tipmost branch if default branch doesn't exist
Matt Mackall <mpm@selenic.com>
parents: 5489
diff changeset
   542
                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
   543
                    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
   544
                else:
78a6b985882f update: default to tipmost branch if default branch doesn't exist
Matt Mackall <mpm@selenic.com>
parents: 5489
diff changeset
   545
                    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
   546
        overwrite = force and not branchmerge
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   547
        pl = wc.parents()
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6746
diff changeset
   548
        p1, p2 = pl[0], repo[node]
13874
9d67277c9204 merge: add ancestor to the update function
Matt Mackall <mpm@selenic.com>
parents: 13728
diff changeset
   549
        if ancestor:
9d67277c9204 merge: add ancestor to the update function
Matt Mackall <mpm@selenic.com>
parents: 13728
diff changeset
   550
            pa = repo[ancestor]
9d67277c9204 merge: add ancestor to the update function
Matt Mackall <mpm@selenic.com>
parents: 13728
diff changeset
   551
        else:
9d67277c9204 merge: add ancestor to the update function
Matt Mackall <mpm@selenic.com>
parents: 13728
diff changeset
   552
            pa = p1.ancestor(p2)
9d67277c9204 merge: add ancestor to the update function
Matt Mackall <mpm@selenic.com>
parents: 13728
diff changeset
   553
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   554
        fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
3314
b16456909a0a merge: various tidying
Matt Mackall <mpm@selenic.com>
parents: 3312
diff changeset
   555
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   556
        ### check phase
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   557
        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
   558
            raise util.Abort(_("outstanding uncommitted merges"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   559
        if branchmerge:
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   560
            if pa == p2:
11417
6f1d1ed3e19a merge: improve merge with ancestor message
Matt Mackall <mpm@selenic.com>
parents: 11178
diff changeset
   561
                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
   562
                                   " has no effect"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   563
            elif pa == p1:
16696
d1afbf03e69a rebase: allow collapsing branches in place (issue3111)
Patrick Mezard <patrick@mezard.eu>
parents: 16683
diff changeset
   564
                if not mergeancestor and p1.branch() == p2.branch():
15619
6c8573dd1b6b merge: make 'nothing to merge' aborts consistent
Kevin Bullock <kbullock@ringworld.org>
parents: 15538
diff changeset
   565
                    raise util.Abort(_("nothing to merge"),
6c8573dd1b6b merge: make 'nothing to merge' aborts consistent
Kevin Bullock <kbullock@ringworld.org>
parents: 15538
diff changeset
   566
                                     hint=_("use 'hg update' "
6c8573dd1b6b merge: make 'nothing to merge' aborts consistent
Kevin Bullock <kbullock@ringworld.org>
parents: 15538
diff changeset
   567
                                            "or check 'hg heads'"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   568
            if not force and (wc.files() or wc.deleted()):
15619
6c8573dd1b6b merge: make 'nothing to merge' aborts consistent
Kevin Bullock <kbullock@ringworld.org>
parents: 15538
diff changeset
   569
                raise util.Abort(_("outstanding uncommitted changes"),
6c8573dd1b6b merge: make 'nothing to merge' aborts consistent
Kevin Bullock <kbullock@ringworld.org>
parents: 15538
diff changeset
   570
                                 hint=_("use 'hg status' to list changes"))
13437
6169493ac3f9 Do not allow merging with uncommitted changes in a subrepo
Oleg Stepanov <oleg.stepanov@jetbrains.com>
parents: 13400
diff changeset
   571
            for s in wc.substate:
6169493ac3f9 Do not allow merging with uncommitted changes in a subrepo
Oleg Stepanov <oleg.stepanov@jetbrains.com>
parents: 13400
diff changeset
   572
                if wc.sub(s).dirty():
6169493ac3f9 Do not allow merging with uncommitted changes in a subrepo
Oleg Stepanov <oleg.stepanov@jetbrains.com>
parents: 13400
diff changeset
   573
                    raise util.Abort(_("outstanding uncommitted changes in "
6169493ac3f9 Do not allow merging with uncommitted changes in a subrepo
Oleg Stepanov <oleg.stepanov@jetbrains.com>
parents: 13400
diff changeset
   574
                                       "subrepository '%s'") % s)
6169493ac3f9 Do not allow merging with uncommitted changes in a subrepo
Oleg Stepanov <oleg.stepanov@jetbrains.com>
parents: 13400
diff changeset
   575
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   576
        elif not overwrite:
12401
4cdaf1adafc8 backout most of 4f8067c94729
Matt Mackall <mpm@selenic.com>
parents: 12387
diff changeset
   577
            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
   578
                pass # all good
14663
88cb01c4575e update: check wc.dirty() before setting overwrite=True
Augie Fackler <durin42@gmail.com>
parents: 14485
diff changeset
   579
            elif wc.dirty(missing=True):
12681
bc13e17067d9 update: use higher level wording for "crosses branches" error
Brodie Rao <brodie@bitheap.org>
parents: 12664
diff changeset
   580
                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
   581
                                   " --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
   582
            elif onode is None:
14485
610873cf064a Make pull -u behave like pull && update
Brendan Cully <brendan@kublai.com>
parents: 14434
diff changeset
   583
                raise util.Abort(_("crosses branches (merge branches or update"
12681
bc13e17067d9 update: use higher level wording for "crosses branches" error
Brodie Rao <brodie@bitheap.org>
parents: 12664
diff changeset
   584
                                   " --check to force update)"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   585
            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
   586
                # Allow jumping branches if clean and specific rev given
16092
914bc95e227b update: use normal update path with --check (issue2450)
Matt Mackall <mpm@selenic.com>
parents: 16001
diff changeset
   587
                pa = p1
2814
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
   588
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   589
        ### calculate phase
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   590
        action = []
15538
b0a88bda3381 update: don't clobber untracked files with wrong casing
Mads Kiilerich <mads@kiilerich.com>
parents: 15041
diff changeset
   591
        folding = not util.checkcase(repo.path)
b0a88bda3381 update: don't clobber untracked files with wrong casing
Mads Kiilerich <mads@kiilerich.com>
parents: 15041
diff changeset
   592
        if folding:
16478
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   593
            # collision check is not needed for clean update
16492
774e2dcd0a65 update: fix case-collision with a clean wd and no --clean
Patrick Mezard <patrick@mezard.eu>
parents: 16478
diff changeset
   594
            if (not branchmerge and
774e2dcd0a65 update: fix case-collision with a clean wd and no --clean
Patrick Mezard <patrick@mezard.eu>
parents: 16478
diff changeset
   595
                (force or not wc.dirty(missing=True, branch=False))):
16478
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   596
                _checkcollision(p2, None)
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   597
            else:
cbf2ea2f5ca1 icasefs: make case-folding collision detection as rename aware (issue3370)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16284
diff changeset
   598
                _checkcollision(p2, wc)
16284
2b0a406d3043 merge: fix unknown file merge detection for case-folding systems
Matt Mackall <mpm@selenic.com>
parents: 16261
diff changeset
   599
        if not force:
2b0a406d3043 merge: fix unknown file merge detection for case-folding systems
Matt Mackall <mpm@selenic.com>
parents: 16261
diff changeset
   600
            _checkunknown(repo, wc, p2)
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
   601
        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
   602
        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
   603
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   604
        ### apply phase
13550
1792b8a9422b merge: back out single-parent fast-forward merge
Matt Mackall <mpm@selenic.com>
parents: 13536
diff changeset
   605
        if not branchmerge: # 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
   606
            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
   607
        if not partial:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   608
            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
   609
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 12757
diff changeset
   610
        stats = applyupdates(repo, action, wc, p2, pa, overwrite)
2899
8743188f4d2e merge: consolidate dirstate updates
Matt Mackall <mpm@selenic.com>
parents: 2898
diff changeset
   611
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   612
        if not partial:
16551
ebf6d38c9063 localrepo: add setparents() to adjust dirstate copies (issue3407)
Patrick Mezard <patrick@mezard.eu>
parents: 16534
diff changeset
   613
            repo.setparents(fp1, fp2)
13550
1792b8a9422b merge: back out single-parent fast-forward merge
Matt Mackall <mpm@selenic.com>
parents: 13536
diff changeset
   614
            recordupdates(repo, action, branchmerge)
13561
0ab0ceefddf2 merge: remove last traces of fastforward merging
Mads Kiilerich <mads@kiilerich.com>
parents: 13550
diff changeset
   615
            if not branchmerge:
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   616
                repo.dirstate.setbranch(p2.branch())
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   617
    finally:
8109
496ae1ea4698 switch lock releasing in the core from gc to explicit
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7848
diff changeset
   618
        wlock.release()
10492
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
   619
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
   620
    if not partial:
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
   621
        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
   622
    return stats