mercurial/merge.py
author Pierre-Yves David <pierre-yves.david@fb.com>
Tue, 25 Feb 2014 18:54:47 -0800
branchstable
changeset 20593 3678707e4017
parent 20592 303cbfe3dcc8
child 20594 ba619c50a355
permissions -rw-r--r--
merge: add "other" file node in the merge state file This data is mostly redundant with the "other" changeset node (+ other changeset file path). However, more data never hurt. The old format do not store it so this require some dancing to add and remove it on demand.
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
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
     8
import struct
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
     9
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    10
from node import nullid, nullrev, hex, bin
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
    11
from i18n import _
18985
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
    12
from mercurial import obsolete
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
    13
import error, util, filemerge, copies, subrepo, worker, dicthelpers
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8259
diff changeset
    14
import errno, os, shutil
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    15
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    16
_pack = struct.pack
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    17
_unpack = struct.unpack
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    18
20593
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    19
def _droponode(data):
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    20
    # used for compatibility for v1
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    21
    bits = data.split("\0")
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    22
    bits = bits[:-2] + bits[-1:]
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    23
    return "\0".join(bits)
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    24
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    25
class mergestate(object):
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    26
    '''track 3-way merge state of individual files
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    27
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    28
    it is stored on disk when needed. Two file are used, one with an old
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    29
    format, one with a new format. Both contains similar data, but the new
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    30
    format can store new kind of field.
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    31
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    32
    Current new format is a list of arbitrary record of the form:
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    33
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    34
        [type][length][content]
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    35
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    36
    Type is a single character, length is a 4 bytes integer, content is an
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    37
    arbitrary suites of bytes of lenght `length`.
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    38
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    39
    Type should be a letter. Capital letter are mandatory record, Mercurial
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    40
    should abort if they are unknown. lower case record can be safely ignored.
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    41
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    42
    Currently known record:
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    43
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    44
    L: the node of the "local" part of the merge (hexified version)
20591
02c60e380fd0 merge: record the "other" node in merge state
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20590
diff changeset
    45
    O: the node of the "other" part of the merge (hexified version)
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    46
    F: a file to be merged entry
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    47
    '''
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    48
    statepathv1 = "merge/state"
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    49
    statepathv2 = "merge/state2"
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    50
    def __init__(self, repo):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    51
        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
    52
        self._dirty = False
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    53
        self._read()
20591
02c60e380fd0 merge: record the "other" node in merge state
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20590
diff changeset
    54
    def reset(self, node=None, other=None):
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    55
        self._state = {}
7848
89e05c02a4af resolve: move reset to localrepo.commit
Matt Mackall <mpm@selenic.com>
parents: 7768
diff changeset
    56
        if node:
89e05c02a4af resolve: move reset to localrepo.commit
Matt Mackall <mpm@selenic.com>
parents: 7768
diff changeset
    57
            self._local = node
20591
02c60e380fd0 merge: record the "other" node in merge state
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20590
diff changeset
    58
            self._other = other
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    59
        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
    60
        self._dirty = False
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    61
    def _read(self):
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    62
        self._state = {}
20589
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
    63
        records = self._readrecords()
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
    64
        for rtype, record in records:
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
    65
            if rtype == 'L':
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
    66
                self._local = bin(record)
20591
02c60e380fd0 merge: record the "other" node in merge state
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20590
diff changeset
    67
            elif rtype == 'O':
02c60e380fd0 merge: record the "other" node in merge state
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20590
diff changeset
    68
                self._other = bin(record)
20589
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
    69
            elif rtype == "F":
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
    70
                bits = record.split("\0")
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
    71
                self._state[bits[0]] = bits[1:]
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
    72
            elif not rtype.islower():
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
    73
                raise util.Abort(_('unsupported merge state record:'
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
    74
                                   % rtype))
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
    75
        self._dirty = False
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
    76
    def _readrecords(self):
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    77
        v1records = self._readrecordsv1()
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    78
        v2records = self._readrecordsv2()
20593
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    79
        oldv2 = set() # old format version of v2 record
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    80
        for rec in v2records:
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    81
            if rec[0] == 'L':
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    82
                oldv2.add(rec)
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    83
            elif rec[0] == 'F':
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    84
                # drop the onode data (not contained in v1)
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    85
                oldv2.add(('F', _droponode(rec[1])))
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    86
        for rec in v1records:
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    87
            if rec not in oldv2:
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    88
                # v1 file is newer than v2 file, use it
20592
303cbfe3dcc8 merge: infer the "other" changeset when falling back to v1 format
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20591
diff changeset
    89
                # we have to infer the "other" changeset of the merge
303cbfe3dcc8 merge: infer the "other" changeset when falling back to v1 format
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20591
diff changeset
    90
                # we cannot do better than that with v1 of the format
303cbfe3dcc8 merge: infer the "other" changeset when falling back to v1 format
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20591
diff changeset
    91
                mctx = self._repo[None].parents()[-1]
303cbfe3dcc8 merge: infer the "other" changeset when falling back to v1 format
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20591
diff changeset
    92
                v1records.append(('O', mctx.hex()))
20593
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    93
                # add place holder "other" file node information
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    94
                # nobody is using it yet so we do no need to fetch the data
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    95
                # if mctx was wrong `mctx[bits[-2]]` may fails.
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    96
                for idx, r in enumerate(v1records):
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    97
                    if r[0] == 'F':
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    98
                        bits = r[1].split("\0")
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    99
                        bits.insert(-2, '')
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
   100
                        v1records[idx] = (r[0], "\0".join(bits))
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   101
                return v1records
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   102
        else:
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   103
            return v2records
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   104
    def _readrecordsv1(self):
20589
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   105
        records = []
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   106
        try:
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   107
            f = self._repo.opener(self.statepathv1)
6530
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
   108
            for i, l in enumerate(f):
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
   109
                if i == 0:
20589
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   110
                    records.append(('L', l[:-1]))
6530
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
   111
                else:
20589
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   112
                    records.append(('F', l[:-1]))
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13323
diff changeset
   113
            f.close()
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   114
        except IOError, err:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   115
            if err.errno != errno.ENOENT:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   116
                raise
20589
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   117
        return records
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   118
    def _readrecordsv2(self):
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   119
        records = []
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   120
        try:
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   121
            f = self._repo.opener(self.statepathv2)
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   122
            data = f.read()
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   123
            off = 0
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   124
            end = len(data)
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   125
            while off < end:
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   126
                rtype = data[off]
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   127
                off += 1
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   128
                lenght = _unpack('>I', data[off:(off + 4)])[0]
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   129
                off += 4
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   130
                record = data[off:(off + lenght)]
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   131
                off += lenght
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   132
                records.append((rtype, record))
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   133
            f.close()
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   134
        except IOError, err:
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   135
            if err.errno != errno.ENOENT:
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   136
                raise
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   137
        return records
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
   138
    def commit(self):
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
   139
        if self._dirty:
20589
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   140
            records = []
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   141
            records.append(("L", hex(self._local)))
20591
02c60e380fd0 merge: record the "other" node in merge state
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20590
diff changeset
   142
            records.append(("O", hex(self._other)))
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
   143
            for d, v in self._state.iteritems():
20589
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   144
                records.append(("F", "\0".join([d] + v)))
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   145
            self._writerecords(records)
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
   146
            self._dirty = False
20589
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   147
    def _writerecords(self, records):
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   148
        self._writerecordsv1(records)
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   149
        self._writerecordsv2(records)
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   150
    def _writerecordsv1(self, records):
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   151
        f = self._repo.opener(self.statepathv1, "w")
20589
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   152
        irecords = iter(records)
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   153
        lrecords = irecords.next()
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   154
        assert lrecords[0] == 'L'
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   155
        f.write(hex(self._local) + "\n")
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   156
        for rtype, data in irecords:
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   157
            if rtype == "F":
20593
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
   158
                f.write("%s\n" % _droponode(data))
20589
31993cd23b11 merge: change the merge state serialisation to use a record based logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20588
diff changeset
   159
        f.close()
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   160
    def _writerecordsv2(self, records):
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   161
        f = self._repo.opener(self.statepathv2, "w")
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   162
        for key, data in records:
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   163
            assert len(key) == 1
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   164
            format = ">sI%is" % len(data)
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   165
            f.write(_pack(format, key, len(data), data))
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   166
        f.close()
18338
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   167
    def add(self, fcl, fco, fca, fd):
6517
fcfb6a0a0a84 python-2.6: use sha wrapper from util for new merge code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6512
diff changeset
   168
        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
   169
        self._repo.opener.write("merge/" + hash, fcl.data())
20593
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
   170
        self._state[fd] = ['u', hash, fcl.path(),
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
   171
                           fca.path(), hex(fca.filenode()),
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
   172
                           fco.path(), hex(fco.filenode()),
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
   173
                           fcl.flags()]
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
   174
        self._dirty = True
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   175
    def __contains__(self, dfile):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   176
        return dfile in self._state
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   177
    def __getitem__(self, dfile):
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   178
        return self._state[dfile][0]
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   179
    def __iter__(self):
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   180
        l = self._state.keys()
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   181
        l.sort()
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   182
        for f in l:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   183
            yield f
19285
feaf5749d7a4 merge: add a files method to the mergestate class
Bryan O'Sullivan <bryano@fb.com>
parents: 19226
diff changeset
   184
    def files(self):
feaf5749d7a4 merge: add a files method to the mergestate class
Bryan O'Sullivan <bryano@fb.com>
parents: 19226
diff changeset
   185
        return self._state.keys()
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   186
    def mark(self, dfile, state):
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   187
        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
   188
        self._dirty = True
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   189
    def resolve(self, dfile, wctx, octx):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   190
        if self[dfile] == 'r':
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   191
            return 0
20593
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
   192
        stateentry = self._state[dfile]
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
   193
        state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
18338
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   194
        fcd = wctx[dfile]
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   195
        fco = octx[ofile]
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   196
        fca = self._repo.filectx(afile, fileid=anode)
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   197
        # "premerge" x flags
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   198
        flo = fco.flags()
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   199
        fla = fca.flags()
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   200
        if 'x' in flags + flo + fla and 'l' not in flags + flo + fla:
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   201
            if fca.node() == nullid:
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   202
                self._repo.ui.warn(_('warning: cannot merge flags for %s\n') %
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   203
                                   afile)
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   204
            elif flags == fla:
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   205
                flags = flo
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   206
        # restore local
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   207
        f = self._repo.opener("merge/" + hash)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   208
        self._repo.wwrite(dfile, f.read(), flags)
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13323
diff changeset
   209
        f.close()
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   210
        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
   211
        if r is None:
fac040b7e822 merge: drop resolve state for mergers with identical contents (issue2680)
Matt Mackall <mpm@selenic.com>
parents: 13437
diff changeset
   212
            # no real conflict
fac040b7e822 merge: drop resolve state for mergers with identical contents (issue2680)
Matt Mackall <mpm@selenic.com>
parents: 13437
diff changeset
   213
            del self._state[dfile]
fac040b7e822 merge: drop resolve state for mergers with identical contents (issue2680)
Matt Mackall <mpm@selenic.com>
parents: 13437
diff changeset
   214
        elif not r:
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   215
            self.mark(dfile, 'r')
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   216
        return r
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   217
16093
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
   218
def _checkunknownfile(repo, wctx, mctx, f):
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
   219
    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
   220
        and os.path.isfile(repo.wjoin(f))
19157
113681bbef9e manifestmerge: local unknown, remote created: don't traverse symlinks
Siddharth Agarwal <sid0@fb.com>
parents: 19105
diff changeset
   221
        and repo.wopener.audit.check(f)
16284
2b0a406d3043 merge: fix unknown file merge detection for case-folding systems
Matt Mackall <mpm@selenic.com>
parents: 16261
diff changeset
   222
        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
   223
        and mctx[f].cmp(wctx[f]))
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
   224
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
   225
def _checkunknown(repo, wctx, mctx):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   226
    "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
   227
44fa047cef57 merge: report all files in _checkunknown
Jordi Guti?rrez Hermoso <jordigh@octave.org>
parents: 15774
diff changeset
   228
    error = False
16093
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
   229
    for f in mctx:
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
   230
        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
   231
            error = True
16093
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
   232
            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
   233
    if error:
44fa047cef57 merge: report all files in _checkunknown
Jordi Guti?rrez Hermoso <jordigh@octave.org>
parents: 15774
diff changeset
   234
        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
   235
                           "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
   236
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
   237
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
   238
    """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   239
    Forget removed files
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   240
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   241
    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
   242
    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
   243
    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
   244
    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
   245
    manifest.
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   246
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   247
    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
   248
    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
   249
    as removed.
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   250
    """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   251
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   252
    actions = []
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   253
    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
   254
    for f in wctx.deleted():
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
   255
        if f not in mctx:
18541
5ed6a375e9ca merge: delay debug messages for merge actions
Mads Kiilerich <madski@unity3d.com>
parents: 18540
diff changeset
   256
            actions.append((f, state, None, "forget deleted"))
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   257
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   258
    if not branchmerge:
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   259
        for f in wctx.removed():
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
   260
            if f not in mctx:
18541
5ed6a375e9ca merge: delay debug messages for merge actions
Mads Kiilerich <madski@unity3d.com>
parents: 18540
diff changeset
   261
                actions.append((f, "f", None, "forget removed"))
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   262
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   263
    return actions
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   264
19105
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   265
def _checkcollision(repo, wmf, actions, prompts):
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   266
    # build provisional merged manifest up
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   267
    pmmf = set(wmf)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   268
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   269
    def addop(f, args):
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   270
        pmmf.add(f)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   271
    def removeop(f, args):
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   272
        pmmf.discard(f)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   273
    def nop(f, args):
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   274
        pass
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   275
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   276
    def renameop(f, args):
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   277
        f2, fd, flags = args
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   278
        if f:
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   279
            pmmf.discard(f)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   280
        pmmf.add(fd)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   281
    def mergeop(f, args):
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   282
        f2, fd, move = args
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   283
        if move:
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   284
            pmmf.discard(f)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   285
        pmmf.add(fd)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   286
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   287
    opmap = {
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   288
        "a": addop,
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   289
        "d": renameop,
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   290
        "dr": nop,
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   291
        "e": nop,
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   292
        "f": addop, # untracked file should be kept in working directory
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   293
        "g": addop,
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   294
        "m": mergeop,
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   295
        "r": removeop,
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   296
        "rd": nop,
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   297
    }
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   298
    for f, m, args, msg in actions:
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   299
        op = opmap.get(m)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   300
        assert op, m
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   301
        op(f, args)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   302
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   303
    opmap = {
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   304
        "cd": addop,
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   305
        "dc": addop,
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   306
    }
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   307
    for f, m in prompts:
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   308
        op = opmap.get(m)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   309
        assert op, m
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   310
        op(f, None)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   311
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   312
    # check case-folding collision in provisional merged manifest
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   313
    foldmap = {}
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   314
    for f in sorted(pmmf):
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   315
        fold = util.normcase(f)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   316
        if fold in foldmap:
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   317
            raise util.Abort(_("case-folding collision between %s and %s")
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   318
                             % (f, foldmap[fold]))
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   319
        foldmap[fold] = f
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   320
18778
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   321
def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial,
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   322
                  acceptremote=False):
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   323
    """
11817
d12fe809e1ee merge: fix typo in docstring
Alecs King <alecsk@gmail.com>
parents: 11759
diff changeset
   324
    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
   325
18605
bcf29565d89f manifestmerge: pass in branchmerge and force separately
Siddharth Agarwal <sid0@fb.com>
parents: 18544
diff changeset
   326
    branchmerge and force are as passed in to update
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   327
    partial = function to filter file lists
18778
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   328
    acceptremote = accept the incoming changes without prompting
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   329
    """
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   330
18605
bcf29565d89f manifestmerge: pass in branchmerge and force separately
Siddharth Agarwal <sid0@fb.com>
parents: 18544
diff changeset
   331
    overwrite = force and not branchmerge
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   332
    actions, copy, movewithdir = [], {}, {}
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   333
18651
e556659340f0 manifestmerge: fix order in which manifests are fetched
Siddharth Agarwal <sid0@fb.com>
parents: 18650
diff changeset
   334
    followcopies = False
8749
69caf50da4a0 merge: refactor some initialization, drop backwards var
Matt Mackall <mpm@selenic.com>
parents: 8748
diff changeset
   335
    if overwrite:
18611
18c2184c27dc merge: rename p1 to wctx in manifestmerge
Bryan O'Sullivan <bryano@fb.com>
parents: 18606
diff changeset
   336
        pa = wctx
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   337
    elif pa == p2: # backwards
18611
18c2184c27dc merge: rename p1 to wctx in manifestmerge
Bryan O'Sullivan <bryano@fb.com>
parents: 18606
diff changeset
   338
        pa = wctx.p1()
18612
0b6e6eacc939 merge: don't call copies.mergecopies unless we need to
Bryan O'Sullivan <bryano@fb.com>
parents: 18611
diff changeset
   339
    elif not branchmerge and not wctx.dirty(missing=True):
0b6e6eacc939 merge: don't call copies.mergecopies unless we need to
Bryan O'Sullivan <bryano@fb.com>
parents: 18611
diff changeset
   340
        pass
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   341
    elif pa and repo.ui.configbool("merge", "followcopies", True):
18651
e556659340f0 manifestmerge: fix order in which manifests are fetched
Siddharth Agarwal <sid0@fb.com>
parents: 18650
diff changeset
   342
        followcopies = True
e556659340f0 manifestmerge: fix order in which manifests are fetched
Siddharth Agarwal <sid0@fb.com>
parents: 18650
diff changeset
   343
e556659340f0 manifestmerge: fix order in which manifests are fetched
Siddharth Agarwal <sid0@fb.com>
parents: 18650
diff changeset
   344
    # manifests fetched in order are going to be faster, so prime the caches
e556659340f0 manifestmerge: fix order in which manifests are fetched
Siddharth Agarwal <sid0@fb.com>
parents: 18650
diff changeset
   345
    [x.manifest() for x in
e556659340f0 manifestmerge: fix order in which manifests are fetched
Siddharth Agarwal <sid0@fb.com>
parents: 18650
diff changeset
   346
     sorted(wctx.parents() + [p2, pa], key=lambda x: x.rev())]
e556659340f0 manifestmerge: fix order in which manifests are fetched
Siddharth Agarwal <sid0@fb.com>
parents: 18650
diff changeset
   347
e556659340f0 manifestmerge: fix order in which manifests are fetched
Siddharth Agarwal <sid0@fb.com>
parents: 18650
diff changeset
   348
    if followcopies:
18611
18c2184c27dc merge: rename p1 to wctx in manifestmerge
Bryan O'Sullivan <bryano@fb.com>
parents: 18606
diff changeset
   349
        ret = copies.mergecopies(repo, wctx, p2, pa)
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 18042
diff changeset
   350
        copy, movewithdir, diverge, renamedelete = ret
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   351
        for of, fl in diverge.iteritems():
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   352
            actions.append((of, "dr", (fl,), "divergent renames"))
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
   353
        for of, fl in renamedelete.iteritems():
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   354
            actions.append((of, "rd", (fl,), "rename and delete"))
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   355
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   356
    repo.ui.note(_("resolving manifests\n"))
18605
bcf29565d89f manifestmerge: pass in branchmerge and force separately
Siddharth Agarwal <sid0@fb.com>
parents: 18544
diff changeset
   357
    repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n"
bcf29565d89f manifestmerge: pass in branchmerge and force separately
Siddharth Agarwal <sid0@fb.com>
parents: 18544
diff changeset
   358
                  % (bool(branchmerge), bool(force), bool(partial)))
18611
18c2184c27dc merge: rename p1 to wctx in manifestmerge
Bryan O'Sullivan <bryano@fb.com>
parents: 18606
diff changeset
   359
    repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2))
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   360
18611
18c2184c27dc merge: rename p1 to wctx in manifestmerge
Bryan O'Sullivan <bryano@fb.com>
parents: 18606
diff changeset
   361
    m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest()
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   362
    copied = set(copy.values())
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 18042
diff changeset
   363
    copied.update(movewithdir.values())
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
   364
11470
34e33d50c26b subrepo: correctly handle update -C with modified subrepos (issue2022)
Matt Mackall <mpm@selenic.com>
parents: 11466
diff changeset
   365
    if '.hgsubstate' in m1:
9783
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   366
        # check whether sub state is modified
18611
18c2184c27dc merge: rename p1 to wctx in manifestmerge
Bryan O'Sullivan <bryano@fb.com>
parents: 18606
diff changeset
   367
        for s in sorted(wctx.substate):
18c2184c27dc merge: rename p1 to wctx in manifestmerge
Bryan O'Sullivan <bryano@fb.com>
parents: 18606
diff changeset
   368
            if wctx.sub(s).dirty():
9783
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   369
                m1['.hgsubstate'] += "+"
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   370
                break
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   371
18606
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   372
    aborts, prompts = [], []
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   373
    # Compare manifests
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   374
    fdiff = dicthelpers.diff(m1, m2)
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   375
    flagsdiff = m1.flagsdiff(m2)
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   376
    diff12 = dicthelpers.join(fdiff, flagsdiff)
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   377
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   378
    for f, (n12, fl12) in diff12.iteritems():
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   379
        if n12:
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   380
            n1, n2 = n12
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   381
        else: # file contents didn't change, but flags did
18895
ed676ed67a5c manifestmerge: handle workdir removed, remote removed with flags
Siddharth Agarwal <sid0@fb.com>
parents: 18876
diff changeset
   382
            n1 = n2 = m1.get(f, None)
ed676ed67a5c manifestmerge: handle workdir removed, remote removed with flags
Siddharth Agarwal <sid0@fb.com>
parents: 18876
diff changeset
   383
            if n1 is None:
ed676ed67a5c manifestmerge: handle workdir removed, remote removed with flags
Siddharth Agarwal <sid0@fb.com>
parents: 18876
diff changeset
   384
                # Since n1 == n2, the file isn't present in m2 either. This
ed676ed67a5c manifestmerge: handle workdir removed, remote removed with flags
Siddharth Agarwal <sid0@fb.com>
parents: 18876
diff changeset
   385
                # means that the file was removed or deleted locally and
ed676ed67a5c manifestmerge: handle workdir removed, remote removed with flags
Siddharth Agarwal <sid0@fb.com>
parents: 18876
diff changeset
   386
                # removed remotely, but that residual entries remain in flags.
ed676ed67a5c manifestmerge: handle workdir removed, remote removed with flags
Siddharth Agarwal <sid0@fb.com>
parents: 18876
diff changeset
   387
                # This can happen in manifests generated by workingctx.
ed676ed67a5c manifestmerge: handle workdir removed, remote removed with flags
Siddharth Agarwal <sid0@fb.com>
parents: 18876
diff changeset
   388
                continue
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   389
        if fl12:
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   390
            fl1, fl2 = fl12
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   391
        else: # flags didn't change, file contents did
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   392
            fl1 = fl2 = m1.flags(f)
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   393
3248
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   394
        if partial and not partial(f):
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   395
            continue
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   396
        if n1 and n2:
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   397
            fla = ma.flags(f)
18338
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   398
            nol = 'l' not in fl1 + fl2 + fla
8752
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   399
            a = ma.get(f, nullid)
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   400
            if n2 == a and fl2 == fla:
18338
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   401
                pass # remote unchanged - keep local
18818
a0bff3d4f67b manifestmerge: rename n to n1 and n2
Siddharth Agarwal <sid0@fb.com>
parents: 18780
diff changeset
   402
            elif n1 == a and fl1 == fla: # local unchanged - use remote
a0bff3d4f67b manifestmerge: rename n to n1 and n2
Siddharth Agarwal <sid0@fb.com>
parents: 18780
diff changeset
   403
                if n1 == n2: # optimization: keep local content
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   404
                    actions.append((f, "e", (fl2,), "update permissions"))
18338
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   405
                else:
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   406
                    actions.append((f, "g", (fl2,), "remote is newer"))
18338
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   407
            elif nol and n2 == a: # remote only changed 'x'
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   408
                actions.append((f, "e", (fl2,), "update permissions"))
18818
a0bff3d4f67b manifestmerge: rename n to n1 and n2
Siddharth Agarwal <sid0@fb.com>
parents: 18780
diff changeset
   409
            elif nol and n1 == a: # local only changed 'x'
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   410
                actions.append((f, "g", (fl1,), "remote is newer"))
18338
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   411
            else: # both changed something
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   412
                actions.append((f, "m", (f, f, False), "versions differ"))
8752
f177bdab261b merge: simplify file revision comparison logic
Matt Mackall <mpm@selenic.com>
parents: 8751
diff changeset
   413
        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
   414
            pass
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   415
        elif n1 and f in movewithdir: # directory rename
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 18042
diff changeset
   416
            f2 = movewithdir[f]
18823
b2a36e9b9ccc manifestmerge: drop redundant flags calls
Siddharth Agarwal <sid0@fb.com>
parents: 18822
diff changeset
   417
            actions.append((f, "d", (None, f2, fl1),
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   418
                            "remote renamed directory to " + f2))
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   419
        elif n1 and f in copy:
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   420
            f2 = copy[f]
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   421
            actions.append((f, "m", (f2, f, False),
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   422
                            "local copied/moved to " + f2))
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   423
        elif n1 and f in ma: # clean, a different, no remote
18818
a0bff3d4f67b manifestmerge: rename n to n1 and n2
Siddharth Agarwal <sid0@fb.com>
parents: 18780
diff changeset
   424
            if n1 != ma[f]:
18539
cf25e4efd685 merge: delay prompts a bit and show them in (extra) sorted order
Mads Kiilerich <madski@unity3d.com>
parents: 18505
diff changeset
   425
                prompts.append((f, "cd")) # prompt changed/deleted
18818
a0bff3d4f67b manifestmerge: rename n to n1 and n2
Siddharth Agarwal <sid0@fb.com>
parents: 18780
diff changeset
   426
            elif n1[20:] == "a": # added, no remote
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   427
                actions.append((f, "f", None, "remote deleted"))
16094
0776a6cababe merge: don't use unknown()
Matt Mackall <mpm@selenic.com>
parents: 16093
diff changeset
   428
            else:
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   429
                actions.append((f, "r", None, "other deleted"))
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   430
        elif n2 and f in movewithdir:
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 18042
diff changeset
   431
            f2 = movewithdir[f]
18823
b2a36e9b9ccc manifestmerge: drop redundant flags calls
Siddharth Agarwal <sid0@fb.com>
parents: 18822
diff changeset
   432
            actions.append((None, "d", (f, f2, fl2),
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   433
                            "local renamed directory to " + f2))
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   434
        elif n2 and f in copy:
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   435
            f2 = copy[f]
18339
aadefcee1f5e merge: remove "case" comments
Mads Kiilerich <mads@kiilerich.com>
parents: 18338
diff changeset
   436
            if f2 in m2:
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   437
                actions.append((f2, "m", (f, f, False),
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   438
                                "remote copied to " + f))
18339
aadefcee1f5e merge: remove "case" comments
Mads Kiilerich <mads@kiilerich.com>
parents: 18338
diff changeset
   439
            else:
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   440
                actions.append((f2, "m", (f, f, True),
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   441
                                "remote moved to " + f))
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   442
        elif n2 and f not in ma:
18606
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   443
            # local unknown, remote created: the logic is described by the
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   444
            # following table:
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   445
            #
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   446
            # force  branchmerge  different  |  action
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   447
            #   n         *           n      |    get
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   448
            #   n         *           y      |   abort
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   449
            #   y         n           *      |    get
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   450
            #   y         y           n      |    get
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   451
            #   y         y           y      |   merge
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   452
            #
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   453
            # Checking whether the files are different is expensive, so we
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   454
            # don't do that when we can avoid it.
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   455
            if force and not branchmerge:
18823
b2a36e9b9ccc manifestmerge: drop redundant flags calls
Siddharth Agarwal <sid0@fb.com>
parents: 18822
diff changeset
   456
                actions.append((f, "g", (fl2,), "remote created"))
18339
aadefcee1f5e merge: remove "case" comments
Mads Kiilerich <mads@kiilerich.com>
parents: 18338
diff changeset
   457
            else:
18611
18c2184c27dc merge: rename p1 to wctx in manifestmerge
Bryan O'Sullivan <bryano@fb.com>
parents: 18606
diff changeset
   458
                different = _checkunknownfile(repo, wctx, p2, f)
18606
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   459
                if force and branchmerge and different:
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   460
                    actions.append((f, "m", (f, f, False),
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   461
                                    "remote differs from untracked local"))
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   462
                elif not force and different:
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   463
                    aborts.append((f, "ud"))
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   464
                else:
18823
b2a36e9b9ccc manifestmerge: drop redundant flags calls
Siddharth Agarwal <sid0@fb.com>
parents: 18822
diff changeset
   465
                    actions.append((f, "g", (fl2,), "remote created"))
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   466
        elif n2 and n2 != ma[f]:
20415
e4d7cbc94219 merge: don't overwrite file untracked after remove, abort with 'untracked files'
Mads Kiilerich <madski@unity3d.com>
parents: 20280
diff changeset
   467
            different = _checkunknownfile(repo, wctx, p2, f)
e4d7cbc94219 merge: don't overwrite file untracked after remove, abort with 'untracked files'
Mads Kiilerich <madski@unity3d.com>
parents: 20280
diff changeset
   468
            if not force and different:
e4d7cbc94219 merge: don't overwrite file untracked after remove, abort with 'untracked files'
Mads Kiilerich <madski@unity3d.com>
parents: 20280
diff changeset
   469
                aborts.append((f, "ud"))
e4d7cbc94219 merge: don't overwrite file untracked after remove, abort with 'untracked files'
Mads Kiilerich <madski@unity3d.com>
parents: 20280
diff changeset
   470
            else:
e4d7cbc94219 merge: don't overwrite file untracked after remove, abort with 'untracked files'
Mads Kiilerich <madski@unity3d.com>
parents: 20280
diff changeset
   471
                # if different: old untracked f may be overwritten and lost
e4d7cbc94219 merge: don't overwrite file untracked after remove, abort with 'untracked files'
Mads Kiilerich <madski@unity3d.com>
parents: 20280
diff changeset
   472
                prompts.append((f, "dc")) # prompt deleted/changed
18539
cf25e4efd685 merge: delay prompts a bit and show them in (extra) sorted order
Mads Kiilerich <madski@unity3d.com>
parents: 18505
diff changeset
   473
18606
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   474
    for f, m in sorted(aborts):
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   475
        if m == "ud":
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   476
            repo.ui.warn(_("%s: untracked file differs\n") % f)
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   477
        else: assert False, m
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   478
    if aborts:
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   479
        raise util.Abort(_("untracked files in working directory differ "
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   480
                           "from files in requested revision"))
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   481
19105
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   482
    if not util.checkcase(repo.path):
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   483
        # check collision between files only in p2 for clean update
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   484
        if (not branchmerge and
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   485
            (force or not wctx.dirty(missing=True, branch=False))):
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   486
            _checkcollision(repo, m2, [], [])
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   487
        else:
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   488
            _checkcollision(repo, m1, actions, prompts)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   489
18539
cf25e4efd685 merge: delay prompts a bit and show them in (extra) sorted order
Mads Kiilerich <madski@unity3d.com>
parents: 18505
diff changeset
   490
    for f, m in sorted(prompts):
cf25e4efd685 merge: delay prompts a bit and show them in (extra) sorted order
Mads Kiilerich <madski@unity3d.com>
parents: 18505
diff changeset
   491
        if m == "cd":
18778
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   492
            if acceptremote:
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   493
                actions.append((f, "r", None, "remote delete"))
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   494
            elif repo.ui.promptchoice(
18543
c8ba98bf0e71 merge: don't indent "local changed %s which remote deleted" prompt
Mads Kiilerich <madski@unity3d.com>
parents: 18542
diff changeset
   495
                _("local changed %s which remote deleted\n"
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19157
diff changeset
   496
                  "use (c)hanged version or (d)elete?"
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19157
diff changeset
   497
                  "$$ &Changed $$ &Delete") % f, 0):
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   498
                actions.append((f, "r", None, "prompt delete"))
16094
0776a6cababe merge: don't use unknown()
Matt Mackall <mpm@selenic.com>
parents: 16093
diff changeset
   499
            else:
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   500
                actions.append((f, "a", None, "prompt keep"))
18539
cf25e4efd685 merge: delay prompts a bit and show them in (extra) sorted order
Mads Kiilerich <madski@unity3d.com>
parents: 18505
diff changeset
   501
        elif m == "dc":
18778
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   502
            if acceptremote:
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   503
                actions.append((f, "g", (m2.flags(f),), "remote recreating"))
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   504
            elif repo.ui.promptchoice(
8741
e592180ba435 merge: reorder remote creation tests
Matt Mackall <mpm@selenic.com>
parents: 8740
diff changeset
   505
                _("remote changed %s which local deleted\n"
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19157
diff changeset
   506
                  "use (c)hanged version or leave (d)eleted?"
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19157
diff changeset
   507
                  "$$ &Changed $$ &Deleted") % f, 0) == 0:
18544
d0a8f09a22eb merge: inline act()
Mads Kiilerich <madski@unity3d.com>
parents: 18543
diff changeset
   508
                actions.append((f, "g", (m2.flags(f),), "prompt recreating"))
18539
cf25e4efd685 merge: delay prompts a bit and show them in (extra) sorted order
Mads Kiilerich <madski@unity3d.com>
parents: 18505
diff changeset
   509
        else: assert False, m
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   510
    return actions
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   511
8366
0bf0045000b5 some modernization cleanups, forward compatibility
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8312
diff changeset
   512
def actionkey(a):
19987
ba6486076429 merge: move forgets to the beginning of the action list
Siddharth Agarwal <sid0@fb.com>
parents: 19951
diff changeset
   513
    return a[1] in "rf" 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
   514
18632
3e20079117c5 merge: handle subrepo merges and .hgsubstate specially
Bryan O'Sullivan <bryano@fb.com>
parents: 18630
diff changeset
   515
def getremove(repo, mctx, overwrite, args):
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   516
    """apply usually-non-interactive updates to the working directory
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   517
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   518
    mctx is the context to be merged into the working copy
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   519
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   520
    yields tuples for progress updates
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   521
    """
18640
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   522
    verbose = repo.ui.verbose
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   523
    unlink = util.unlinkpath
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   524
    wjoin = repo.wjoin
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   525
    fctx = mctx.filectx
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   526
    wwrite = repo.wwrite
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   527
    audit = repo.wopener.audit
18633
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   528
    i = 0
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   529
    for arg in args:
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   530
        f = arg[0]
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   531
        if arg[1] == 'r':
18640
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   532
            if verbose:
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   533
                repo.ui.note(_("removing %s\n") % f)
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   534
            audit(f)
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   535
            try:
18640
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   536
                unlink(wjoin(f), ignoremissing=True)
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   537
            except OSError, inst:
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   538
                repo.ui.warn(_("update failed to remove %s: %s!\n") %
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   539
                             (f, inst.strerror))
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   540
        else:
18640
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   541
            if verbose:
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   542
                repo.ui.note(_("getting %s\n") % f)
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   543
            wwrite(f, fctx(f).data(), arg[2][0])
18633
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   544
        if i == 100:
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   545
            yield i, f
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   546
            i = 0
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   547
        i += 1
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   548
    if i > 0:
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   549
        yield i, f
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   550
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   551
def applyupdates(repo, actions, wctx, mctx, actx, overwrite):
11454
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   552
    """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
   553
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   554
    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
   555
    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
   556
    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
   557
115a9760c382 merge: document some internal return values.
Greg Ward <greg-hg@gerg.ca>
parents: 13158
diff changeset
   558
    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
   559
    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
   560
    """
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   561
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   562
    updated, merged, removed, unresolved = 0, 0, 0, 0
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   563
    ms = mergestate(repo)
20591
02c60e380fd0 merge: record the "other" node in merge state
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20590
diff changeset
   564
    ms.reset(wctx.p1().node(), mctx.node())
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   565
    moves = []
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   566
    actions.sort(key=actionkey)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   567
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   568
    # prescan for merges
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   569
    for a in actions:
18541
5ed6a375e9ca merge: delay debug messages for merge actions
Mads Kiilerich <madski@unity3d.com>
parents: 18540
diff changeset
   570
        f, m, args, msg = a
5ed6a375e9ca merge: delay debug messages for merge actions
Mads Kiilerich <madski@unity3d.com>
parents: 18540
diff changeset
   571
        repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
18329
eb6ca96f4dd0 merge: consistently use "x" instead of 'x' for internal action types
Mads Kiilerich <mads@kiilerich.com>
parents: 18328
diff changeset
   572
        if m == "m": # merge
18540
139529b0a191 merge: make all action tuples have the same length - keep args as tuple
Mads Kiilerich <madski@unity3d.com>
parents: 18539
diff changeset
   573
            f2, fd, move = args
18332
6ba58ab719e5 merge: .hgsubstate is special as merge destination, not as merge source
Mads Kiilerich <mads@kiilerich.com>
parents: 18331
diff changeset
   574
            if fd == '.hgsubstate': # merged internally
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   575
                continue
18541
5ed6a375e9ca merge: delay debug messages for merge actions
Mads Kiilerich <madski@unity3d.com>
parents: 18540
diff changeset
   576
            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
   577
            fcl = wctx[f]
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   578
            fco = mctx[f2]
12008
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   579
            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
   580
                if fcl.parents():
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 13874
diff changeset
   581
                    fca = fcl.p1()
12664
545ec1775021 merge: handle no file parent in backwards merge (issue2364)
Matt Mackall <mpm@selenic.com>
parents: 12401
diff changeset
   582
                else:
545ec1775021 merge: handle no file parent in backwards merge (issue2364)
Matt Mackall <mpm@selenic.com>
parents: 12401
diff changeset
   583
                    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
   584
            else:
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   585
                fca = fcl.ancestor(fco, actx)
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   586
            if not fca:
fad5ed0ff997 merge: move reverse-merge logic out of filemerge (issue2342)
Matt Mackall <mpm@selenic.com>
parents: 11755
diff changeset
   587
                fca = repo.filectx(f, fileid=nullrev)
18338
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   588
            ms.add(fcl, fco, fca, fd)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   589
            if f != fd and move:
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   590
                moves.append(f)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   591
18328
2fee5119099b merge: consistently use repo.wopener.audit instead of creating a new auditor
Mads Kiilerich <mads@kiilerich.com>
parents: 18143
diff changeset
   592
    audit = repo.wopener.audit
14398
ae1f7a5373e8 applyupdates: audit unlinking of renamed files and directories
Adrian Buehlmann <adrian@cadifra.com>
parents: 14232
diff changeset
   593
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   594
    # remove renamed files after safely stored
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   595
    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
   596
        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
   597
            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
   598
            audit(f)
18333
f6f23ecafc9b merge: use util.unlinkpath for removing moved files
Mads Kiilerich <mads@kiilerich.com>
parents: 18332
diff changeset
   599
            util.unlinkpath(repo.wjoin(f))
5042
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   600
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   601
    numupdates = len(actions)
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   602
    workeractions = [a for a in actions if a[1] in 'gr']
19095
5cc71484ee9c merge: increase safety of parallel updating/removing on icasefs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18985
diff changeset
   603
    updateactions = [a for a in workeractions if a[1] == 'g']
5cc71484ee9c merge: increase safety of parallel updating/removing on icasefs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18985
diff changeset
   604
    updated = len(updateactions)
5cc71484ee9c merge: increase safety of parallel updating/removing on icasefs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18985
diff changeset
   605
    removeactions = [a for a in workeractions if a[1] == 'r']
5cc71484ee9c merge: increase safety of parallel updating/removing on icasefs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18985
diff changeset
   606
    removed = len(removeactions)
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   607
    actions = [a for a in actions if a[1] not in 'gr']
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   608
18632
3e20079117c5 merge: handle subrepo merges and .hgsubstate specially
Bryan O'Sullivan <bryano@fb.com>
parents: 18630
diff changeset
   609
    hgsub = [a[1] for a in workeractions if a[0] == '.hgsubstate']
3e20079117c5 merge: handle subrepo merges and .hgsubstate specially
Bryan O'Sullivan <bryano@fb.com>
parents: 18630
diff changeset
   610
    if hgsub and hgsub[0] == 'r':
3e20079117c5 merge: handle subrepo merges and .hgsubstate specially
Bryan O'Sullivan <bryano@fb.com>
parents: 18630
diff changeset
   611
        subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
3e20079117c5 merge: handle subrepo merges and .hgsubstate specially
Bryan O'Sullivan <bryano@fb.com>
parents: 18630
diff changeset
   612
18633
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   613
    z = 0
18639
5774732bb5e5 merge: apply non-interactive working dir updates in parallel
Bryan O'Sullivan <bryano@fb.com>
parents: 18633
diff changeset
   614
    prog = worker.worker(repo.ui, 0.001, getremove, (repo, mctx, overwrite),
19095
5cc71484ee9c merge: increase safety of parallel updating/removing on icasefs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18985
diff changeset
   615
                         removeactions)
5cc71484ee9c merge: increase safety of parallel updating/removing on icasefs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18985
diff changeset
   616
    for i, item in prog:
5cc71484ee9c merge: increase safety of parallel updating/removing on icasefs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18985
diff changeset
   617
        z += i
5cc71484ee9c merge: increase safety of parallel updating/removing on icasefs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18985
diff changeset
   618
        repo.ui.progress(_('updating'), z, item=item, total=numupdates,
5cc71484ee9c merge: increase safety of parallel updating/removing on icasefs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18985
diff changeset
   619
                         unit=_('files'))
5cc71484ee9c merge: increase safety of parallel updating/removing on icasefs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18985
diff changeset
   620
    prog = worker.worker(repo.ui, 0.001, getremove, (repo, mctx, overwrite),
5cc71484ee9c merge: increase safety of parallel updating/removing on icasefs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18985
diff changeset
   621
                         updateactions)
18639
5774732bb5e5 merge: apply non-interactive working dir updates in parallel
Bryan O'Sullivan <bryano@fb.com>
parents: 18633
diff changeset
   622
    for i, item in prog:
18633
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   623
        z += i
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   624
        repo.ui.progress(_('updating'), z, item=item, total=numupdates,
15041
3afe5edda4e3 merge: use repo.ui directly instead local variable
Martin Geisler <mg@aragost.com>
parents: 14980
diff changeset
   625
                         unit=_('files'))
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   626
18632
3e20079117c5 merge: handle subrepo merges and .hgsubstate specially
Bryan O'Sullivan <bryano@fb.com>
parents: 18630
diff changeset
   627
    if hgsub and hgsub[0] == 'g':
3e20079117c5 merge: handle subrepo merges and .hgsubstate specially
Bryan O'Sullivan <bryano@fb.com>
parents: 18630
diff changeset
   628
        subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
3e20079117c5 merge: handle subrepo merges and .hgsubstate specially
Bryan O'Sullivan <bryano@fb.com>
parents: 18630
diff changeset
   629
18640
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   630
    _updating = _('updating')
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   631
    _files = _('files')
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   632
    progress = repo.ui.progress
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   633
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   634
    for i, a in enumerate(actions):
18541
5ed6a375e9ca merge: delay debug messages for merge actions
Mads Kiilerich <madski@unity3d.com>
parents: 18540
diff changeset
   635
        f, m, args, msg = a
18640
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   636
        progress(_updating, z + i + 1, item=f, total=numupdates, unit=_files)
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   637
        if m == "m": # merge
18780
0705ad73e878 applyupdates: assign variable before we try to use it (issue3855)
Kevin Bullock <kbullock@ringworld.org>
parents: 18778
diff changeset
   638
            f2, fd, move = args
18332
6ba58ab719e5 merge: .hgsubstate is special as merge destination, not as merge source
Mads Kiilerich <mads@kiilerich.com>
parents: 18331
diff changeset
   639
            if fd == '.hgsubstate': # subrepo states need updating
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16551
diff changeset
   640
                subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16551
diff changeset
   641
                                 overwrite)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8753
diff changeset
   642
                continue
18328
2fee5119099b merge: consistently use repo.wopener.audit instead of creating a new auditor
Mads Kiilerich <mads@kiilerich.com>
parents: 18143
diff changeset
   643
            audit(fd)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   644
            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
   645
            if r is not None and r > 0:
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
   646
                unresolved += 1
3309
e8be5942335d merge: pull file copy/move out of filemerge
Matt Mackall <mpm@selenic.com>
parents: 3308
diff changeset
   647
            else:
3400
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
   648
                if r is None:
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
   649
                    updated += 1
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
   650
                else:
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
   651
                    merged += 1
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   652
        elif m == "d": # directory rename
18540
139529b0a191 merge: make all action tuples have the same length - keep args as tuple
Mads Kiilerich <madski@unity3d.com>
parents: 18539
diff changeset
   653
            f2, fd, flags = args
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   654
            if f:
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   655
                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
   656
                audit(f)
18335
435909bf0257 merge: drop reference to file contents immediately after write
Mads Kiilerich <mads@kiilerich.com>
parents: 18334
diff changeset
   657
                repo.wwrite(fd, wctx.filectx(f).data(), flags)
13235
6bf39d88c857 rename util.unlink to unlinkpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 13162
diff changeset
   658
                util.unlinkpath(repo.wjoin(f))
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   659
            if f2:
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   660
                repo.ui.note(_("getting %s to %s\n") % (f2, fd))
18335
435909bf0257 merge: drop reference to file contents immediately after write
Mads Kiilerich <mads@kiilerich.com>
parents: 18334
diff changeset
   661
                repo.wwrite(fd, mctx.filectx(f2).data(), flags)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   662
            updated += 1
4674
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
   663
        elif m == "dr": # divergent renames
18540
139529b0a191 merge: make all action tuples have the same length - keep args as tuple
Mads Kiilerich <madski@unity3d.com>
parents: 18539
diff changeset
   664
            fl, = args
12757
62c8f7691bc3 merge: make 'diverging renames' diagnostic a more helpful note.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 12746
diff changeset
   665
            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
   666
                           "multiple times to:\n") % f)
4674
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
   667
            for nf in fl:
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
   668
                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
   669
        elif m == "rd": # rename and delete
18540
139529b0a191 merge: make all action tuples have the same length - keep args as tuple
Mads Kiilerich <madski@unity3d.com>
parents: 18539
diff changeset
   670
            fl, = args
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
   671
            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
   672
                           "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
   673
            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
   674
                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
   675
        elif m == "e": # exec
18540
139529b0a191 merge: make all action tuples have the same length - keep args as tuple
Mads Kiilerich <madski@unity3d.com>
parents: 18539
diff changeset
   676
            flags, = args
18328
2fee5119099b merge: consistently use repo.wopener.audit instead of creating a new auditor
Mads Kiilerich <mads@kiilerich.com>
parents: 18143
diff changeset
   677
            audit(f)
14232
df2399663392 rename util.set_flags to setflags
Adrian Buehlmann <adrian@cadifra.com>
parents: 14220
diff changeset
   678
            util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
18334
44bda93df90e merge: changing the mode of a file is also an update
Mads Kiilerich <mads@kiilerich.com>
parents: 18333
diff changeset
   679
            updated += 1
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
   680
    ms.commit()
18640
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   681
    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
   682
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   683
    return updated, merged, removed, unresolved
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   684
18778
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   685
def calculateupdates(repo, tctx, mctx, ancestor, branchmerge, force, partial,
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   686
                     acceptremote=False):
18035
5881d5b7552f merge: refactor action calculation into function
David Schleimer <dschleimer@fb.com>
parents: 17889
diff changeset
   687
    "Calculate the actions needed to merge mctx into tctx"
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   688
    actions = []
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   689
    actions += manifestmerge(repo, tctx, mctx,
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   690
                             ancestor,
18605
bcf29565d89f manifestmerge: pass in branchmerge and force separately
Siddharth Agarwal <sid0@fb.com>
parents: 18544
diff changeset
   691
                             branchmerge, force,
18778
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   692
                             partial, acceptremote)
18036
8b846dbc57b6 merge: support calculating merge actions against non-working contexts
David Schleimer <dschleimer@fb.com>
parents: 18035
diff changeset
   693
    if tctx.rev() is None:
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   694
        actions += _forgetremoved(tctx, mctx, branchmerge)
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   695
    return actions
18035
5881d5b7552f merge: refactor action calculation into function
David Schleimer <dschleimer@fb.com>
parents: 17889
diff changeset
   696
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   697
def recordupdates(repo, actions, branchmerge):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   698
    "record merge actions to the dirstate"
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   699
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   700
    for a in actions:
18541
5ed6a375e9ca merge: delay debug messages for merge actions
Mads Kiilerich <madski@unity3d.com>
parents: 18540
diff changeset
   701
        f, m, args, msg = a
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   702
        if m == "r": # remove
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   703
            if branchmerge:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   704
                repo.dirstate.remove(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   705
            else:
14434
cc8c09855d19 dirstate: rename forget to drop
Matt Mackall <mpm@selenic.com>
parents: 14406
diff changeset
   706
                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
   707
        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
   708
            if not branchmerge:
5bf5fd1e2a74 merge: mark kept local files as readded on linear update (issue539)
Matt Mackall <mpm@selenic.com>
parents: 7631
diff changeset
   709
                repo.dirstate.add(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   710
        elif m == "f": # forget
14434
cc8c09855d19 dirstate: rename forget to drop
Matt Mackall <mpm@selenic.com>
parents: 14406
diff changeset
   711
            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
   712
        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
   713
            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
   714
        elif m == "g": # get
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   715
            if branchmerge:
10968
7a0d096e221e dirstate: more explicit name, rename normaldirty() to otherparent()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10492
diff changeset
   716
                repo.dirstate.otherparent(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   717
            else:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   718
                repo.dirstate.normal(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   719
        elif m == "m": # merge
18540
139529b0a191 merge: make all action tuples have the same length - keep args as tuple
Mads Kiilerich <madski@unity3d.com>
parents: 18539
diff changeset
   720
            f2, fd, move = args
3251
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   721
            if branchmerge:
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   722
                # 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
   723
                # 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
   724
                repo.dirstate.merge(fd)
3372
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   725
                if f != f2: # copy/rename
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   726
                    if move:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   727
                        repo.dirstate.remove(f)
3372
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   728
                    if f != fd:
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   729
                        repo.dirstate.copy(f, fd)
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   730
                    else:
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
   731
                        repo.dirstate.copy(f2, fd)
3251
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   732
            else:
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   733
                # We've update-merged a locally modified file, so
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   734
                # we set the dirstate to emulate a normal checkout
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   735
                # 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
   736
                # merge will appear as a normal local file
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
   737
                # modification.
11178
21a7ae13208f merge: avoid to break the dirstate copy status on moved files
Gilles Moris <gilles.moris@free.fr>
parents: 11101
diff changeset
   738
                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
   739
                    repo.dirstate.normallookup(fd)
3308
ecc1bf27378c merge: unify merge and copy actions
Matt Mackall <mpm@selenic.com>
parents: 3307
diff changeset
   740
                if move:
14434
cc8c09855d19 dirstate: rename forget to drop
Matt Mackall <mpm@selenic.com>
parents: 14406
diff changeset
   741
                    repo.dirstate.drop(f)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   742
        elif m == "d": # directory rename
18540
139529b0a191 merge: make all action tuples have the same length - keep args as tuple
Mads Kiilerich <madski@unity3d.com>
parents: 18539
diff changeset
   743
            f2, fd, flag = args
4819
9797124581c9 merge: fix adding untracked files on directory rename (issue612)
Matt Mackall <mpm@selenic.com>
parents: 4748
diff changeset
   744
            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
   745
                # untracked file moved
9797124581c9 merge: fix adding untracked files on directory rename (issue612)
Matt Mackall <mpm@selenic.com>
parents: 4748
diff changeset
   746
                continue
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   747
            if branchmerge:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   748
                repo.dirstate.add(fd)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   749
                if f:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   750
                    repo.dirstate.remove(f)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   751
                    repo.dirstate.copy(f, fd)
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   752
                if f2:
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   753
                    repo.dirstate.copy(f2, fd)
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   754
            else:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
   755
                repo.dirstate.normal(fd)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
   756
                if f:
14434
cc8c09855d19 dirstate: rename forget to drop
Matt Mackall <mpm@selenic.com>
parents: 14406
diff changeset
   757
                    repo.dirstate.drop(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   758
16696
d1afbf03e69a rebase: allow collapsing branches in place (issue3111)
Patrick Mezard <patrick@mezard.eu>
parents: 16683
diff changeset
   759
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
   760
           mergeancestor=False):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   761
    """
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   762
    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
   763
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   764
    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
   765
    branchmerge = whether to merge between branches
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   766
    force = whether to force branch merging or file overwriting
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   767
    partial = a function to filter file lists (dirstate not updated)
18778
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   768
    mergeancestor = whether it is merging with an ancestor. If true,
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   769
      we should accept the incoming changes for any prompts that occur.
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   770
      If false, merging with an ancestor (fast-forward) is only allowed
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   771
      between different named branches. This flag is used by rebase extension
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   772
      as a temporary fix and should be 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
   773
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   774
    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
   775
    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
   776
    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
   777
    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
   778
    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
   779
12279
28e2e3804f2e combine tests
Adrian Buehlmann <adrian@cadifra.com>
parents: 12032
diff changeset
   780
    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
   781
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   782
    -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
   783
     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
   784
     n   n    n     y   |    ok     ok     ok
19799
ab3e42225dbc update: add error message for dirty non-linear update with no rev
Siddharth Agarwal <sid0@fb.com>
parents: 19798
diff changeset
   785
     n   n    y     n   |   merge   (2)    (2)
ab3e42225dbc update: add error message for dirty non-linear update with no rev
Siddharth Agarwal <sid0@fb.com>
parents: 19798
diff changeset
   786
     n   n    y     y   |   merge   (3)    (3)
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   787
     n   y    *     *   |    ---  discard  ---
19799
ab3e42225dbc update: add error message for dirty non-linear update with no rev
Siddharth Agarwal <sid0@fb.com>
parents: 19798
diff changeset
   788
     y   n    y     *   |    ---    (4)    ---
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   789
     y   n    n     *   |    ---    ok     ---
19799
ab3e42225dbc update: add error message for dirty non-linear update with no rev
Siddharth Agarwal <sid0@fb.com>
parents: 19798
diff changeset
   790
     y   y    *     *   |    ---    (5)    ---
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   791
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   792
    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
   793
    * = don't-care
19798
76df01e56e7f update: improve error message for clean non-linear update
Siddharth Agarwal <sid0@fb.com>
parents: 19482
diff changeset
   794
    1 = abort: not a linear update (merge or update --check to force update)
19800
4894e0d9462d update: improve error message for dirty non-linear update with rev
Siddharth Agarwal <sid0@fb.com>
parents: 19799
diff changeset
   795
    2 = abort: uncommitted changes (commit and merge, or update --clean to
4894e0d9462d update: improve error message for dirty non-linear update with rev
Siddharth Agarwal <sid0@fb.com>
parents: 19799
diff changeset
   796
                 discard changes)
19799
ab3e42225dbc update: add error message for dirty non-linear update with no rev
Siddharth Agarwal <sid0@fb.com>
parents: 19798
diff changeset
   797
    3 = abort: uncommitted changes (commit or update --clean to discard changes)
19801
41abe2e3e3b7 update: standardize error message for dirty update --check
Siddharth Agarwal <sid0@fb.com>
parents: 19800
diff changeset
   798
    4 = abort: uncommitted changes (checked in commands.py)
19799
ab3e42225dbc update: add error message for dirty non-linear update with no rev
Siddharth Agarwal <sid0@fb.com>
parents: 19798
diff changeset
   799
    5 = incompatible options (checked in commands.py)
13162
115a9760c382 merge: document some internal return values.
Greg Ward <greg-hg@gerg.ca>
parents: 13158
diff changeset
   800
115a9760c382 merge: document some internal return values.
Greg Ward <greg-hg@gerg.ca>
parents: 13158
diff changeset
   801
    Return the same tuple as applyupdates().
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   802
    """
2815
4870f795f681 Merge: combine force and forcemerge arguments
Matt Mackall <mpm@selenic.com>
parents: 2814
diff changeset
   803
9717
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   804
    onode = node
4917
126f527b3ba3 Make repo locks recursive, eliminate all passing of lock/wlock
Matt Mackall <mpm@selenic.com>
parents: 4915
diff changeset
   805
    wlock = repo.wlock()
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   806
    try:
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6746
diff changeset
   807
        wc = repo[None]
20279
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
   808
        pl = wc.parents()
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
   809
        p1 = pl[0]
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
   810
        pa = None
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
   811
        if ancestor:
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
   812
            pa = repo[ancestor]
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
   813
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   814
        if node is None:
20278
20ef533ffb01 merge: update comment for future devs
Sean Farley <sean.michael.farley@gmail.com>
parents: 19987
diff changeset
   815
            # Here is where we should consider bookmarks, divergent bookmarks,
20ef533ffb01 merge: update comment for future devs
Sean Farley <sean.michael.farley@gmail.com>
parents: 19987
diff changeset
   816
            # foreground changesets (successors), and tip of current branch;
20ef533ffb01 merge: update comment for future devs
Sean Farley <sean.michael.farley@gmail.com>
parents: 19987
diff changeset
   817
            # but currently we are only checking the branch tips.
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   818
            try:
16719
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16696
diff changeset
   819
                node = repo.branchtip(wc.branch())
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16696
diff changeset
   820
            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
   821
                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
   822
                    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
   823
                else:
78a6b985882f update: default to tipmost branch if default branch doesn't exist
Matt Mackall <mpm@selenic.com>
parents: 5489
diff changeset
   824
                    raise util.Abort(_("branch %s not found") % wc.branch())
20280
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   825
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   826
            if p1.obsolete() and not p1.children():
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   827
                # allow updating to successors
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   828
                successors = obsolete.successorssets(repo, p1.node())
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   829
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   830
                # behavior of certain cases is as follows,
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   831
                #
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   832
                # divergent changesets: update to highest rev, similar to what
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   833
                #     is currently done when there are more than one head
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   834
                #     (i.e. 'tip')
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   835
                #
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   836
                # replaced changesets: same as divergent except we know there
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   837
                # is no conflict
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   838
                #
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   839
                # pruned changeset: no update is done; though, we could
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   840
                #     consider updating to the first non-obsolete parent,
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   841
                #     similar to what is current done for 'hg prune'
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   842
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   843
                if successors:
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   844
                    # flatten the list here handles both divergent (len > 1)
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   845
                    # and the usual case (len = 1)
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   846
                    successors = [n for sub in successors for n in sub]
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   847
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   848
                    # get the max revision for the given successors set,
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   849
                    # i.e. the 'tip' of a set
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   850
                    node = repo.revs("max(%ln)", successors)[0]
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   851
                    pa = p1
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
   852
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   853
        overwrite = force and not branchmerge
20279
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
   854
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
   855
        p2 = repo[node]
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
   856
        if pa is None:
13874
9d67277c9204 merge: add ancestor to the update function
Matt Mackall <mpm@selenic.com>
parents: 13728
diff changeset
   857
            pa = p1.ancestor(p2)
9d67277c9204 merge: add ancestor to the update function
Matt Mackall <mpm@selenic.com>
parents: 13728
diff changeset
   858
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   859
        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
   860
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   861
        ### check phase
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   862
        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
   863
            raise util.Abort(_("outstanding uncommitted merges"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   864
        if branchmerge:
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   865
            if pa == p2:
11417
6f1d1ed3e19a merge: improve merge with ancestor message
Matt Mackall <mpm@selenic.com>
parents: 11178
diff changeset
   866
                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
   867
                                   " has no effect"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   868
            elif pa == p1:
16696
d1afbf03e69a rebase: allow collapsing branches in place (issue3111)
Patrick Mezard <patrick@mezard.eu>
parents: 16683
diff changeset
   869
                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
   870
                    raise util.Abort(_("nothing to merge"),
6c8573dd1b6b merge: make 'nothing to merge' aborts consistent
Kevin Bullock <kbullock@ringworld.org>
parents: 15538
diff changeset
   871
                                     hint=_("use 'hg update' "
6c8573dd1b6b merge: make 'nothing to merge' aborts consistent
Kevin Bullock <kbullock@ringworld.org>
parents: 15538
diff changeset
   872
                                            "or check 'hg heads'"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   873
            if not force and (wc.files() or wc.deleted()):
19802
94c394653b2a merge: standardize error message for dirty working dir
Siddharth Agarwal <sid0@fb.com>
parents: 19801
diff changeset
   874
                raise util.Abort(_("uncommitted changes"),
15619
6c8573dd1b6b merge: make 'nothing to merge' aborts consistent
Kevin Bullock <kbullock@ringworld.org>
parents: 15538
diff changeset
   875
                                 hint=_("use 'hg status' to list changes"))
18364
6252b4f1c4b4 subrepos: process subrepos in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 18360
diff changeset
   876
            for s in sorted(wc.substate):
13437
6169493ac3f9 Do not allow merging with uncommitted changes in a subrepo
Oleg Stepanov <oleg.stepanov@jetbrains.com>
parents: 13400
diff changeset
   877
                if wc.sub(s).dirty():
19803
0f64af33fb63 merge: standardize error message for dirty subrepo
Siddharth Agarwal <sid0@fb.com>
parents: 19802
diff changeset
   878
                    raise util.Abort(_("uncommitted changes in "
13437
6169493ac3f9 Do not allow merging with uncommitted changes in a subrepo
Oleg Stepanov <oleg.stepanov@jetbrains.com>
parents: 13400
diff changeset
   879
                                       "subrepository '%s'") % s)
6169493ac3f9 Do not allow merging with uncommitted changes in a subrepo
Oleg Stepanov <oleg.stepanov@jetbrains.com>
parents: 13400
diff changeset
   880
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
   881
        elif not overwrite:
19929
ab2362e1672e merge: exit early during a no-op update (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 19803
diff changeset
   882
            if p1 == p2: # no-op update
ab2362e1672e merge: exit early during a no-op update (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 19803
diff changeset
   883
                # call the hooks and exit early
ab2362e1672e merge: exit early during a no-op update (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 19803
diff changeset
   884
                repo.hook('preupdate', throw=True, parent1=xp2, parent2='')
ab2362e1672e merge: exit early during a no-op update (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 19803
diff changeset
   885
                repo.hook('update', parent1=xp2, parent2='', error=0)
ab2362e1672e merge: exit early during a no-op update (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 19803
diff changeset
   886
                return 0, 0, 0, 0
ab2362e1672e merge: exit early during a no-op update (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 19803
diff changeset
   887
19951
d51c4d85ec23 spelling: random spell checker fixes
Mads Kiilerich <madski@unity3d.com>
parents: 19929
diff changeset
   888
            if pa not in (p1, p2):  # nonlinear
18985
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
   889
                dirty = wc.dirty(missing=True)
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
   890
                if dirty or onode is None:
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
   891
                    # Branching is a bit strange to ensure we do the minimal
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
   892
                    # amount of call to obsolete.background.
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
   893
                    foreground = obsolete.foreground(repo, [p1.node()])
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
   894
                    # note: the <node> variable contains a random identifier
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
   895
                    if repo[node].node() in foreground:
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
   896
                        pa = p1  # allow updating to successors
19799
ab3e42225dbc update: add error message for dirty non-linear update with no rev
Siddharth Agarwal <sid0@fb.com>
parents: 19798
diff changeset
   897
                    elif dirty:
ab3e42225dbc update: add error message for dirty non-linear update with no rev
Siddharth Agarwal <sid0@fb.com>
parents: 19798
diff changeset
   898
                        msg = _("uncommitted changes")
19800
4894e0d9462d update: improve error message for dirty non-linear update with rev
Siddharth Agarwal <sid0@fb.com>
parents: 19799
diff changeset
   899
                        if onode is None:
4894e0d9462d update: improve error message for dirty non-linear update with rev
Siddharth Agarwal <sid0@fb.com>
parents: 19799
diff changeset
   900
                            hint = _("commit and merge, or update --clean to"
4894e0d9462d update: improve error message for dirty non-linear update with rev
Siddharth Agarwal <sid0@fb.com>
parents: 19799
diff changeset
   901
                                     " discard changes")
4894e0d9462d update: improve error message for dirty non-linear update with rev
Siddharth Agarwal <sid0@fb.com>
parents: 19799
diff changeset
   902
                        else:
4894e0d9462d update: improve error message for dirty non-linear update with rev
Siddharth Agarwal <sid0@fb.com>
parents: 19799
diff changeset
   903
                            hint = _("commit or update --clean to discard"
4894e0d9462d update: improve error message for dirty non-linear update with rev
Siddharth Agarwal <sid0@fb.com>
parents: 19799
diff changeset
   904
                                     " changes")
19799
ab3e42225dbc update: add error message for dirty non-linear update with no rev
Siddharth Agarwal <sid0@fb.com>
parents: 19798
diff changeset
   905
                        raise util.Abort(msg, hint=hint)
18985
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
   906
                    else:  # node is none
19798
76df01e56e7f update: improve error message for clean non-linear update
Siddharth Agarwal <sid0@fb.com>
parents: 19482
diff changeset
   907
                        msg = _("not a linear update")
76df01e56e7f update: improve error message for clean non-linear update
Siddharth Agarwal <sid0@fb.com>
parents: 19482
diff changeset
   908
                        hint = _("merge or update --check to force update")
76df01e56e7f update: improve error message for clean non-linear update
Siddharth Agarwal <sid0@fb.com>
parents: 19482
diff changeset
   909
                        raise util.Abort(msg, hint=hint)
18985
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
   910
                else:
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
   911
                    # Allow jumping branches if clean and specific rev given
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
   912
                    pa = p1
2814
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
   913
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   914
        ### calculate phase
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   915
        actions = calculateupdates(repo, wc, p2, pa,
18778
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   916
                                   branchmerge, force, partial, mergeancestor)
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   917
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   918
        ### apply phase
13550
1792b8a9422b merge: back out single-parent fast-forward merge
Matt Mackall <mpm@selenic.com>
parents: 13536
diff changeset
   919
        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
   920
            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
   921
        if not partial:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   922
            repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
19482
499fc471296b update: add tracking of interrupted updates (issue3113)
Matt Mackall <mpm@selenic.com>
parents: 19285
diff changeset
   923
            # note that we're in the middle of an update
499fc471296b update: add tracking of interrupted updates (issue3113)
Matt Mackall <mpm@selenic.com>
parents: 19285
diff changeset
   924
            repo.vfs.write('updatestate', p2.hex())
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   925
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   926
        stats = applyupdates(repo, actions, wc, p2, pa, overwrite)
2899
8743188f4d2e merge: consolidate dirstate updates
Matt Mackall <mpm@selenic.com>
parents: 2898
diff changeset
   927
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   928
        if not partial:
16551
ebf6d38c9063 localrepo: add setparents() to adjust dirstate copies (issue3407)
Patrick Mezard <patrick@mezard.eu>
parents: 16534
diff changeset
   929
            repo.setparents(fp1, fp2)
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   930
            recordupdates(repo, actions, branchmerge)
19482
499fc471296b update: add tracking of interrupted updates (issue3113)
Matt Mackall <mpm@selenic.com>
parents: 19285
diff changeset
   931
            # update completed, clear state
499fc471296b update: add tracking of interrupted updates (issue3113)
Matt Mackall <mpm@selenic.com>
parents: 19285
diff changeset
   932
            util.unlink(repo.join('updatestate'))
499fc471296b update: add tracking of interrupted updates (issue3113)
Matt Mackall <mpm@selenic.com>
parents: 19285
diff changeset
   933
13561
0ab0ceefddf2 merge: remove last traces of fastforward merging
Mads Kiilerich <mads@kiilerich.com>
parents: 13550
diff changeset
   934
            if not branchmerge:
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   935
                repo.dirstate.setbranch(p2.branch())
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   936
    finally:
8109
496ae1ea4698 switch lock releasing in the core from gc to explicit
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7848
diff changeset
   937
        wlock.release()
10492
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
   938
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
   939
    if not partial:
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
   940
        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
   941
    return stats