mercurial/merge.py
author Siddharth Agarwal <sid0@fb.com>
Sun, 11 Oct 2015 12:56:21 -0700
changeset 26606 2a405d307f8c
parent 26587 56b2bcea2529
child 26611 a5ff66e6d77a
permissions -rw-r--r--
filemerge: also return whether the merge is complete In future patches, we'll pause merges after the premerge step. After the premerge step we'll return complete = False.
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
25959
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
     8
from __future__ import absolute_import
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
     9
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    10
import errno
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    11
import os
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    12
import shutil
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    13
import struct
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    14
25959
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    15
from .i18n import _
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    16
from .node import (
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    17
    bin,
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    18
    hex,
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    19
    nullid,
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    20
    nullrev,
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    21
)
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    22
from . import (
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    23
    copies,
26570
c8b332b1eb1f merge: get the default update destination from the function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26534
diff changeset
    24
    destutil,
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26570
diff changeset
    25
    error,
25959
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    26
    filemerge,
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    27
    obsolete,
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    28
    subrepo,
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    29
    util,
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    30
    worker,
892d601f0d44 merge: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25844
diff changeset
    31
)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    32
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    33
_pack = struct.pack
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    34
_unpack = struct.unpack
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    35
20593
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    36
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
    37
    # used for compatibility for v1
23380
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
    38
    bits = data.split('\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
    39
    bits = bits[:-2] + bits[-1:]
23380
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
    40
    return '\0'.join(bits)
20593
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
    41
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    42
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
    43
    '''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
    44
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    45
    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
    46
    format, one with a new format. Both contains similar data, but the new
26361
6b4a0c602bec merge: fix mergestate comment
timeless@mozdev.org
parents: 26318
diff changeset
    47
    format can store new kinds of field.
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    48
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    49
    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
    50
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    51
        [type][length][content]
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    52
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    53
    Type is a single character, length is a 4 bytes integer, content is an
20607
abd448767465 merge: fix spelling of length
Olle Lundberg <geek@nerd.sh>
parents: 20594
diff changeset
    54
    arbitrary suites of bytes of length `length`.
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    55
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    56
    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
    57
    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
    58
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    59
    Currently known record:
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    60
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
    61
    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
    62
    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
    63
    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
    64
    '''
23380
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
    65
    statepathv1 = 'merge/state'
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
    66
    statepathv2 = 'merge/state2'
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
    67
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    68
    def __init__(self, repo):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    69
        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
    70
        self._dirty = False
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    71
        self._read()
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
    72
20591
02c60e380fd0 merge: record the "other" node in merge state
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20590
diff changeset
    73
    def reset(self, node=None, other=None):
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
    74
        self._state = {}
21261
6ca05c46aa95 mergestate: consistently set variables to None
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21203
diff changeset
    75
        self._local = None
6ca05c46aa95 mergestate: consistently set variables to None
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21203
diff changeset
    76
        self._other = None
7848
89e05c02a4af resolve: move reset to localrepo.commit
Matt Mackall <mpm@selenic.com>
parents: 7768
diff changeset
    77
        if node:
89e05c02a4af resolve: move reset to localrepo.commit
Matt Mackall <mpm@selenic.com>
parents: 7768
diff changeset
    78
            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
    79
            self._other = other
23380
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
    80
        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
    81
        self._dirty = False
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
    82
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    83
    def _read(self):
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
    84
        """Analyse each record content to restore a serialized state from disk
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
    85
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
    86
        This function process "record" entry produced by the de-serialization
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
    87
        of on disk file.
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
    88
        """
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
    89
        self._state = {}
21261
6ca05c46aa95 mergestate: consistently set variables to None
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21203
diff changeset
    90
        self._local = None
6ca05c46aa95 mergestate: consistently set variables to None
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21203
diff changeset
    91
        self._other = None
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
    92
        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
    93
        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
    94
            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
    95
                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
    96
            elif rtype == 'O':
02c60e380fd0 merge: record the "other" node in merge state
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20590
diff changeset
    97
                self._other = bin(record)
23380
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
    98
            elif rtype == 'F':
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
    99
                bits = record.split('\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
   100
                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
   101
            elif not rtype.islower():
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26570
diff changeset
   102
                raise error.Abort(_('unsupported merge state record: %s')
20868
5db105f216c3 i18n: fix "% inside _()" problems
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20867
diff changeset
   103
                                   % rtype)
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
   104
        self._dirty = False
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   105
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
   106
    def _readrecords(self):
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   107
        """Read merge state from disk and return a list of record (TYPE, data)
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   108
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20945
diff changeset
   109
        We read data from both v1 and v2 files and decide which one to use.
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   110
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20945
diff changeset
   111
        V1 has been used by version prior to 2.9.1 and contains less data than
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20945
diff changeset
   112
        v2. We read both versions and check if no data in v2 contradicts
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   113
        v1. If there is not contradiction we can safely assume that both v1
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   114
        and v2 were written at the same time and use the extract data in v2. If
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   115
        there is contradiction we ignore v2 content as we assume an old version
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20945
diff changeset
   116
        of Mercurial has overwritten the mergestate file and left an old v2
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   117
        file around.
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   118
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   119
        returns list of record [(TYPE, data), ...]"""
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   120
        v1records = self._readrecordsv1()
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   121
        v2records = self._readrecordsv2()
26500
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   122
        if self._v1v2match(v1records, v2records):
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   123
            return v2records
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   124
        else:
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   125
            # v1 file is newer than v2 file, use it
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   126
            # we have to infer the "other" changeset of the merge
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   127
            # we cannot do better than that with v1 of the format
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   128
            mctx = self._repo[None].parents()[-1]
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   129
            v1records.append(('O', mctx.hex()))
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   130
            # add place holder "other" file node information
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   131
            # nobody is using it yet so we do no need to fetch the data
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   132
            # if mctx was wrong `mctx[bits[-2]]` may fails.
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   133
            for idx, r in enumerate(v1records):
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   134
                if r[0] == 'F':
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   135
                    bits = r[1].split('\0')
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   136
                    bits.insert(-2, '')
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   137
                    v1records[idx] = (r[0], '\0'.join(bits))
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   138
            return v1records
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   139
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   140
    def _v1v2match(self, v1records, v2records):
20593
3678707e4017 merge: add "other" file node in the merge state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20592
diff changeset
   141
        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
   142
        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
   143
            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
   144
                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
   145
            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
   146
                # 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
   147
                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
   148
        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
   149
            if rec not in oldv2:
26500
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   150
                return False
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   151
        else:
26500
5bd7c4c07f6d merge.mergestate: factor out code to validate v1/v2 records
Siddharth Agarwal <sid0@fb.com>
parents: 26361
diff changeset
   152
            return True
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   153
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   154
    def _readrecordsv1(self):
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   155
        """read on disk merge state for version 1 file
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   156
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   157
        returns list of record [(TYPE, data), ...]
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   158
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   159
        Note: the "F" data from this file are one entry short
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   160
              (no "other file node" entry)
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   161
        """
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
   162
        records = []
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   163
        try:
23877
7cc77030c557 localrepo: remove all external users of localrepo.opener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23656
diff changeset
   164
            f = self._repo.vfs(self.statepathv1)
6530
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
   165
            for i, l in enumerate(f):
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
   166
                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
   167
                    records.append(('L', l[:-1]))
6530
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
   168
                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
   169
                    records.append(('F', l[:-1]))
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13323
diff changeset
   170
            f.close()
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25151
diff changeset
   171
        except IOError as err:
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   172
            if err.errno != errno.ENOENT:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   173
                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
   174
        return records
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   175
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   176
    def _readrecordsv2(self):
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   177
        """read on disk merge state for version 2 file
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   178
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   179
        returns list of record [(TYPE, data), ...]
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   180
        """
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   181
        records = []
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   182
        try:
23877
7cc77030c557 localrepo: remove all external users of localrepo.opener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23656
diff changeset
   183
            f = self._repo.vfs(self.statepathv2)
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   184
            data = f.read()
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   185
            off = 0
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   186
            end = len(data)
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   187
            while off < end:
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   188
                rtype = data[off]
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   189
                off += 1
20607
abd448767465 merge: fix spelling of length
Olle Lundberg <geek@nerd.sh>
parents: 20594
diff changeset
   190
                length = _unpack('>I', data[off:(off + 4)])[0]
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   191
                off += 4
20607
abd448767465 merge: fix spelling of length
Olle Lundberg <geek@nerd.sh>
parents: 20594
diff changeset
   192
                record = data[off:(off + length)]
abd448767465 merge: fix spelling of length
Olle Lundberg <geek@nerd.sh>
parents: 20594
diff changeset
   193
                off += length
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   194
                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
   195
            f.close()
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25151
diff changeset
   196
        except IOError as err:
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   197
            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
   198
                raise
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   199
        return records
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   200
21264
4e932dc5c113 resolve: abort when not applicable (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21261
diff changeset
   201
    def active(self):
4e932dc5c113 resolve: abort when not applicable (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21261
diff changeset
   202
        """Whether mergestate is active.
4e932dc5c113 resolve: abort when not applicable (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21261
diff changeset
   203
4e932dc5c113 resolve: abort when not applicable (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21261
diff changeset
   204
        Returns True if there appears to be mergestate. This is a rough proxy
4e932dc5c113 resolve: abort when not applicable (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21261
diff changeset
   205
        for "is a merge in progress."
4e932dc5c113 resolve: abort when not applicable (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21261
diff changeset
   206
        """
4e932dc5c113 resolve: abort when not applicable (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21261
diff changeset
   207
        # Check local variables before looking at filesystem for performance
4e932dc5c113 resolve: abort when not applicable (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21261
diff changeset
   208
        # reasons.
4e932dc5c113 resolve: abort when not applicable (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21261
diff changeset
   209
        return bool(self._local) or bool(self._state) or \
23877
7cc77030c557 localrepo: remove all external users of localrepo.opener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23656
diff changeset
   210
               self._repo.vfs.exists(self.statepathv1) or \
7cc77030c557 localrepo: remove all external users of localrepo.opener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23656
diff changeset
   211
               self._repo.vfs.exists(self.statepathv2)
21264
4e932dc5c113 resolve: abort when not applicable (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21261
diff changeset
   212
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
   213
    def commit(self):
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   214
        """Write current state on disk (if necessary)"""
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
   215
        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
   216
            records = []
23380
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
   217
            records.append(('L', hex(self._local)))
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
   218
            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
   219
            for d, v in self._state.iteritems():
23380
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
   220
                records.append(('F', '\0'.join([d] + v)))
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
   221
            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
   222
            self._dirty = False
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   223
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
   224
    def _writerecords(self, records):
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   225
        """Write current state on disk (both v1 and v2)"""
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   226
        self._writerecordsv1(records)
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   227
        self._writerecordsv2(records)
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   228
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   229
    def _writerecordsv1(self, records):
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   230
        """Write current state on disk in a version 1 file"""
23877
7cc77030c557 localrepo: remove all external users of localrepo.opener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23656
diff changeset
   231
        f = self._repo.vfs(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
   232
        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
   233
        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
   234
        assert lrecords[0] == 'L'
23380
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
   235
        f.write(hex(self._local) + '\n')
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
   236
        for rtype, data in irecords:
23380
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
   237
            if rtype == 'F':
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
   238
                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
   239
        f.close()
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   240
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   241
    def _writerecordsv2(self, records):
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   242
        """Write current state on disk in a version 2 file"""
23877
7cc77030c557 localrepo: remove all external users of localrepo.opener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23656
diff changeset
   243
        f = self._repo.vfs(self.statepathv2, 'w')
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   244
        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
   245
            assert len(key) == 1
23380
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
   246
            format = '>sI%is' % len(data)
20590
2b7d54e929b4 merge: introduce new format for the state file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20589
diff changeset
   247
            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
   248
        f.close()
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   249
18338
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   250
    def add(self, fcl, fco, fca, fd):
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   251
        """add a new (potentially?) conflicting file the merge state
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   252
        fcl: file context for local,
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   253
        fco: file context for remote,
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   254
        fca: file context for ancestors,
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   255
        fd:  file path of the resulting merge.
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   256
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   257
        note: also write the local version to the `.hg/merge` directory.
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   258
        """
6517
fcfb6a0a0a84 python-2.6: use sha wrapper from util for new merge code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6512
diff changeset
   259
        hash = util.sha1(fcl.path()).hexdigest()
23877
7cc77030c557 localrepo: remove all external users of localrepo.opener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23656
diff changeset
   260
        self._repo.vfs.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
   261
        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
   262
                           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
   263
                           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
   264
                           fcl.flags()]
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
   265
        self._dirty = True
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   266
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   267
    def __contains__(self, dfile):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   268
        return dfile in self._state
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   269
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   270
    def __getitem__(self, dfile):
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   271
        return self._state[dfile][0]
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   272
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   273
    def __iter__(self):
21268
a0b8a912ec81 merge: simplify mergestate iter
Mads Kiilerich <mads@kiilerich.com>
parents: 21266
diff changeset
   274
        return iter(sorted(self._state))
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   275
19285
feaf5749d7a4 merge: add a files method to the mergestate class
Bryan O'Sullivan <bryano@fb.com>
parents: 19226
diff changeset
   276
    def files(self):
feaf5749d7a4 merge: add a files method to the mergestate class
Bryan O'Sullivan <bryano@fb.com>
parents: 19226
diff changeset
   277
        return self._state.keys()
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   278
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   279
    def mark(self, dfile, state):
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
   280
        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
   281
        self._dirty = True
20651
c1a52dd56eb4 merge: add blank line between mergestate's method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20642
diff changeset
   282
21266
19d6fec60b81 resolve: print message when no unresolved files remain (issue4214)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21264
diff changeset
   283
    def unresolved(self):
19d6fec60b81 resolve: print message when no unresolved files remain (issue4214)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21264
diff changeset
   284
        """Obtain the paths of unresolved files."""
19d6fec60b81 resolve: print message when no unresolved files remain (issue4214)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21264
diff changeset
   285
19d6fec60b81 resolve: print message when no unresolved files remain (issue4214)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21264
diff changeset
   286
        for f, entry in self._state.items():
19d6fec60b81 resolve: print message when no unresolved files remain (issue4214)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21264
diff changeset
   287
            if entry[0] == 'u':
19d6fec60b81 resolve: print message when no unresolved files remain (issue4214)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21264
diff changeset
   288
                yield f
19d6fec60b81 resolve: print message when no unresolved files remain (issue4214)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21264
diff changeset
   289
21524
47b97d9af27e merge: add labels parameter from merge.update to filemerge
Durham Goode <durham@fb.com>
parents: 21392
diff changeset
   290
    def resolve(self, dfile, wctx, labels=None):
20652
2a4871c2511d merge: adds documentation to the mergestate class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20651
diff changeset
   291
        """rerun merge process for file path `dfile`"""
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   292
        if self[dfile] == 'r':
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   293
            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
   294
        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
   295
        state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
20594
ba619c50a355 resolve: use "other" changeset from merge state (issue4163)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20593
diff changeset
   296
        octx = self._repo[self._other]
18338
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   297
        fcd = wctx[dfile]
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   298
        fco = octx[ofile]
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   299
        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
   300
        # "premerge" x flags
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   301
        flo = fco.flags()
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   302
        fla = fca.flags()
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   303
        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
   304
            if fca.node() == nullid:
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   305
                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
   306
                                   afile)
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   307
            elif flags == fla:
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   308
                flags = flo
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   309
        # restore local
23877
7cc77030c557 localrepo: remove all external users of localrepo.opener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23656
diff changeset
   310
        f = self._repo.vfs('merge/' + hash)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   311
        self._repo.wwrite(dfile, f.read(), flags)
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13323
diff changeset
   312
        f.close()
26606
2a405d307f8c filemerge: also return whether the merge is complete
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
   313
        complete, r = filemerge.filemerge(self._repo, self._local, lfile, fcd,
2a405d307f8c filemerge: also return whether the merge is complete
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
   314
                                          fco, fca, labels=labels)
13536
fac040b7e822 merge: drop resolve state for mergers with identical contents (issue2680)
Matt Mackall <mpm@selenic.com>
parents: 13437
diff changeset
   315
        if r is None:
fac040b7e822 merge: drop resolve state for mergers with identical contents (issue2680)
Matt Mackall <mpm@selenic.com>
parents: 13437
diff changeset
   316
            # no real conflict
fac040b7e822 merge: drop resolve state for mergers with identical contents (issue2680)
Matt Mackall <mpm@selenic.com>
parents: 13437
diff changeset
   317
            del self._state[dfile]
20792
89059c450c56 merge: mark mergestate as dirty when resolve changes _state
Mads Kiilerich <madski@unity3d.com>
parents: 20652
diff changeset
   318
            self._dirty = True
13536
fac040b7e822 merge: drop resolve state for mergers with identical contents (issue2680)
Matt Mackall <mpm@selenic.com>
parents: 13437
diff changeset
   319
        elif not r:
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   320
            self.mark(dfile, 'r')
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   321
        return r
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   322
23653
0297d8469350 merge: don't overwrite untracked file at directory rename target
Martin von Zweigbergk <martinvonz@google.com>
parents: 23652
diff changeset
   323
def _checkunknownfile(repo, wctx, mctx, f, f2=None):
0297d8469350 merge: don't overwrite untracked file at directory rename target
Martin von Zweigbergk <martinvonz@google.com>
parents: 23652
diff changeset
   324
    if f2 is None:
0297d8469350 merge: don't overwrite untracked file at directory rename target
Martin von Zweigbergk <martinvonz@google.com>
parents: 23652
diff changeset
   325
        f2 = f
23478
30b602168c3b update: don't overwrite untracked ignored files on update
Martin von Zweigbergk <martinvonz@google.com>
parents: 23420
diff changeset
   326
    return (os.path.isfile(repo.wjoin(f))
23879
b88278a308c6 localrepo: remove all external users of localrepo.wopener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23877
diff changeset
   327
        and repo.wvfs.audit.check(f)
16284
2b0a406d3043 merge: fix unknown file merge detection for case-folding systems
Matt Mackall <mpm@selenic.com>
parents: 16261
diff changeset
   328
        and repo.dirstate.normalize(f) not in repo.dirstate
23653
0297d8469350 merge: don't overwrite untracked file at directory rename target
Martin von Zweigbergk <martinvonz@google.com>
parents: 23652
diff changeset
   329
        and mctx[f2].cmp(wctx[f]))
16093
7e30f5f2285f merge: refactor unknown file conflict checking
Matt Mackall <mpm@selenic.com>
parents: 16092
diff changeset
   330
23655
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   331
def _checkunknownfiles(repo, wctx, mctx, force, actions):
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   332
    """
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   333
    Considers any actions that care about the presence of conflicting unknown
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   334
    files. For some actions, the result is to abort; for others, it is to
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   335
    choose a different action.
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   336
    """
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   337
    aborts = []
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   338
    if not force:
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   339
        for f, (m, args, msg) in actions.iteritems():
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   340
            if m in ('c', 'dc'):
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   341
                if _checkunknownfile(repo, wctx, mctx, f):
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   342
                    aborts.append(f)
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   343
            elif m == 'dg':
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   344
                if _checkunknownfile(repo, wctx, mctx, f, args[0]):
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   345
                    aborts.append(f)
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   346
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   347
    for f in sorted(aborts):
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   348
        repo.ui.warn(_("%s: untracked file differs\n") % f)
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   349
    if aborts:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26570
diff changeset
   350
        raise error.Abort(_("untracked files in working directory differ "
23655
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   351
                           "from files in requested revision"))
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   352
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   353
    for f, (m, args, msg) in actions.iteritems():
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   354
        if m == 'c':
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   355
            actions[f] = ('g', args, msg)
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   356
        elif m == 'cm':
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   357
            fl2, anc = args
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   358
            different = _checkunknownfile(repo, wctx, mctx, f)
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   359
            if different:
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   360
                actions[f] = ('m', (f, f, None, False, anc),
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   361
                              "remote differs from untracked local")
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   362
            else:
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   363
                actions[f] = ('g', (fl2,), "remote created")
79235b46062c merge: extract method for checking for conflicting untracked file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23654
diff changeset
   364
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
   365
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
   366
    """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   367
    Forget removed files
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   368
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   369
    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
   370
    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
   371
    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
   372
    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
   373
    manifest.
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   374
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   375
    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
   376
    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
   377
    as removed.
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   378
    """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   379
23640
b46b9865dd08 merge: let _forgetremoved() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23639
diff changeset
   380
    actions = {}
b46b9865dd08 merge: let _forgetremoved() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23639
diff changeset
   381
    m = 'f'
21545
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   382
    if branchmerge:
23640
b46b9865dd08 merge: let _forgetremoved() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23639
diff changeset
   383
        m = 'r'
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   384
    for f in wctx.deleted():
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
   385
        if f not in mctx:
23640
b46b9865dd08 merge: let _forgetremoved() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23639
diff changeset
   386
            actions[f] = m, None, "forget deleted"
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   387
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   388
    if not branchmerge:
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
   389
        for f in wctx.removed():
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
   390
            if f not in mctx:
23640
b46b9865dd08 merge: let _forgetremoved() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23639
diff changeset
   391
                actions[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
   392
23640
b46b9865dd08 merge: let _forgetremoved() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23639
diff changeset
   393
    return actions
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
   394
20640
52929dcdd512 merge: handle create+delete prompts in calculateupdates
Mads Kiilerich <madski@unity3d.com>
parents: 20639
diff changeset
   395
def _checkcollision(repo, wmf, actions):
19105
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   396
    # build provisional merged manifest up
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   397
    pmmf = set(wmf)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   398
21545
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   399
    if actions:
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   400
        # k, dr, e and rd are no-op
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   401
        for m in 'a', 'f', 'g', 'cd', 'dc':
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   402
            for f, args, msg in actions[m]:
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   403
                pmmf.add(f)
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   404
        for f, args, msg in actions['r']:
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   405
            pmmf.discard(f)
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   406
        for f, args, msg in actions['dm']:
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   407
            f2, flags = args
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   408
            pmmf.discard(f2)
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   409
            pmmf.add(f)
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   410
        for f, args, msg in actions['dg']:
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   411
            pmmf.add(f)
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   412
        for f, args, msg in actions['m']:
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   413
            f1, f2, fa, move, anc = args
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   414
            if move:
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   415
                pmmf.discard(f1)
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   416
            pmmf.add(f)
19105
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   417
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   418
    # 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
   419
    foldmap = {}
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   420
    for f in sorted(pmmf):
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   421
        fold = util.normcase(f)
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   422
        if fold in foldmap:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26570
diff changeset
   423
            raise error.Abort(_("case-folding collision between %s and %s")
19105
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   424
                             % (f, foldmap[fold]))
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   425
        foldmap[fold] = f
c60a7f5a741f icasefs: rewrite case-folding collision detection (issue3452)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19095
diff changeset
   426
18778
1ef89df2c248 rebase: fix --collapse when a file was added then removed
Durham Goode <durham@fb.com>
parents: 18651
diff changeset
   427
def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial,
21080
04540a8499a3 merge: move ancestor selection tweaking from manifestmerge to update function
Mads Kiilerich <madski@unity3d.com>
parents: 21024
diff changeset
   428
                  acceptremote, followcopies):
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   429
    """
11817
d12fe809e1ee merge: fix typo in docstring
Alecs King <alecsk@gmail.com>
parents: 11759
diff changeset
   430
    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
   431
18605
bcf29565d89f manifestmerge: pass in branchmerge and force separately
Siddharth Agarwal <sid0@fb.com>
parents: 18544
diff changeset
   432
    branchmerge and force are as passed in to update
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   433
    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
   434
    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
   435
    """
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   436
23526
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   437
    copy, movewithdir, diverge, renamedelete = {}, {}, {}, {}
8753
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   438
18651
e556659340f0 manifestmerge: fix order in which manifests are fetched
Siddharth Agarwal <sid0@fb.com>
parents: 18650
diff changeset
   439
    # 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
   440
    [x.manifest() for x in
e556659340f0 manifestmerge: fix order in which manifests are fetched
Siddharth Agarwal <sid0@fb.com>
parents: 18650
diff changeset
   441
     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
   442
e556659340f0 manifestmerge: fix order in which manifests are fetched
Siddharth Agarwal <sid0@fb.com>
parents: 18650
diff changeset
   443
    if followcopies:
18611
18c2184c27dc merge: rename p1 to wctx in manifestmerge
Bryan O'Sullivan <bryano@fb.com>
parents: 18606
diff changeset
   444
        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
   445
        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
   446
af5f099d932b merge: refactor manifestmerge init to better report effective ancestor
Matt Mackall <mpm@selenic.com>
parents: 8752
diff changeset
   447
    repo.ui.note(_("resolving manifests\n"))
18605
bcf29565d89f manifestmerge: pass in branchmerge and force separately
Siddharth Agarwal <sid0@fb.com>
parents: 18544
diff changeset
   448
    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
   449
                  % (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
   450
    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
   451
18611
18c2184c27dc merge: rename p1 to wctx in manifestmerge
Bryan O'Sullivan <bryano@fb.com>
parents: 18606
diff changeset
   452
    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
   453
    copied = set(copy.values())
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 18042
diff changeset
   454
    copied.update(movewithdir.values())
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
   455
11470
34e33d50c26b subrepo: correctly handle update -C with modified subrepos (issue2022)
Matt Mackall <mpm@selenic.com>
parents: 11466
diff changeset
   456
    if '.hgsubstate' in m1:
9783
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   457
        # 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
   458
        for s in sorted(wctx.substate):
18c2184c27dc merge: rename p1 to wctx in manifestmerge
Bryan O'Sullivan <bryano@fb.com>
parents: 18606
diff changeset
   459
            if wctx.sub(s).dirty():
23380
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
   460
                m1['.hgsubstate'] += '+'
9783
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   461
                break
ee00ef6f9be7 submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   462
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   463
    # Compare manifests
22964
2793ecb1522d manifest: repurpose flagsdiff() into (node-and-flag)diff()
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22902
diff changeset
   464
    diff = m1.diff(m2)
18822
381c0ef72a56 manifestmerge: use dicthelpers.diff and join
Siddharth Agarwal <sid0@fb.com>
parents: 18818
diff changeset
   465
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   466
    actions = {}
22966
ff93aa006e6a manifest: transpose pair of pairs from diff()
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22965
diff changeset
   467
    for f, ((n1, fl1), (n2, fl2)) in diff.iteritems():
3248
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   468
        if partial and not partial(f):
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
   469
            continue
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   470
        if n1 and n2: # file exists on both local and remote side
23396
6a254a2dd37c merge: separate out "both created" cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23395
diff changeset
   471
            if f not in ma:
23397
c7c95838be9a merge: break out "both renamed a -> b" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 23396
diff changeset
   472
                fa = copy.get(f, None)
c7c95838be9a merge: break out "both renamed a -> b" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 23396
diff changeset
   473
                if fa is not None:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   474
                    actions[f] = ('m', (f, f, fa, False, pa.node()),
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   475
                                  "both renamed from " + fa)
18338
384df4db6520 merge: merge file flags together with file content
Mads Kiilerich <mads@kiilerich.com>
parents: 18336
diff changeset
   476
                else:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   477
                    actions[f] = ('m', (f, f, None, False, pa.node()),
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   478
                                  "both created")
16094
0776a6cababe merge: don't use unknown()
Matt Mackall <mpm@selenic.com>
parents: 16093
diff changeset
   479
            else:
23396
6a254a2dd37c merge: separate out "both created" cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23395
diff changeset
   480
                a = ma[f]
6a254a2dd37c merge: separate out "both created" cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23395
diff changeset
   481
                fla = ma.flags(f)
23395
d9ebb475eede merge: indent to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23387
diff changeset
   482
                nol = 'l' not in fl1 + fl2 + fla
d9ebb475eede merge: indent to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23387
diff changeset
   483
                if n2 == a and fl2 == fla:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   484
                    actions[f] = ('k' , (), "remote unchanged")
23395
d9ebb475eede merge: indent to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23387
diff changeset
   485
                elif n1 == a and fl1 == fla: # local unchanged - use remote
d9ebb475eede merge: indent to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23387
diff changeset
   486
                    if n1 == n2: # optimization: keep local content
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   487
                        actions[f] = ('e', (fl2,), "update permissions")
23395
d9ebb475eede merge: indent to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23387
diff changeset
   488
                    else:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   489
                        actions[f] = ('g', (fl2,), "remote is newer")
23395
d9ebb475eede merge: indent to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23387
diff changeset
   490
                elif nol and n2 == a: # remote only changed 'x'
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   491
                    actions[f] = ('e', (fl2,), "update permissions")
23395
d9ebb475eede merge: indent to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23387
diff changeset
   492
                elif nol and n1 == a: # local only changed 'x'
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   493
                    actions[f] = ('g', (fl1,), "remote is newer")
23395
d9ebb475eede merge: indent to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23387
diff changeset
   494
                else: # both changed something
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   495
                    actions[f] = ('m', (f, f, f, False, pa.node()),
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   496
                                   "versions differ")
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   497
        elif n1: # file exists only on local side
23474
9f4ac44a7273 merge: duplicate 'if f in copied' into each branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23473
diff changeset
   498
            if f in copied:
9f4ac44a7273 merge: duplicate 'if f in copied' into each branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23473
diff changeset
   499
                pass # we'll deal with it on m2 side
9f4ac44a7273 merge: duplicate 'if f in copied' into each branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23473
diff changeset
   500
            elif f in movewithdir: # directory rename, move local
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   501
                f2 = movewithdir[f]
23475
67f1d68861fb merge: don't ignore conflicting file in remote renamed directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 23474
diff changeset
   502
                if f2 in m2:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   503
                    actions[f2] = ('m', (f, f2, None, True, pa.node()),
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   504
                                   "remote directory rename, both created")
23475
67f1d68861fb merge: don't ignore conflicting file in remote renamed directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 23474
diff changeset
   505
                else:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   506
                    actions[f2] = ('dm', (f, fl1),
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   507
                                   "remote directory rename - move from " + f)
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   508
            elif f in copy:
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   509
                f2 = copy[f]
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   510
                actions[f] = ('m', (f, f2, f2, False, pa.node()),
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   511
                              "local copied/moved from " + f2)
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   512
            elif f in ma: # clean, a different, no remote
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   513
                if n1 != ma[f]:
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   514
                    if acceptremote:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   515
                        actions[f] = ('r', None, "remote delete")
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   516
                    else:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   517
                        actions[f] = ('cd', None,  "prompt changed/deleted")
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   518
                elif n1[20:] == 'a':
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   519
                    # This extra 'a' is added by working copy manifest to mark
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   520
                    # the file as locally added. We should forget it instead of
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   521
                    # deleting it.
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   522
                    actions[f] = ('f', None, "remote deleted")
20639
1df033640a8e merge: handle acceptremove of create+delete early in manifest merge
Mads Kiilerich <madski@unity3d.com>
parents: 20620
diff changeset
   523
                else:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   524
                    actions[f] = ('r', None, "other deleted")
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   525
        elif n2: # file exists only on remote side
23474
9f4ac44a7273 merge: duplicate 'if f in copied' into each branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23473
diff changeset
   526
            if f in copied:
9f4ac44a7273 merge: duplicate 'if f in copied' into each branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23473
diff changeset
   527
                pass # we'll deal with it on m1 side
9f4ac44a7273 merge: duplicate 'if f in copied' into each branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 23473
diff changeset
   528
            elif f in movewithdir:
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   529
                f2 = movewithdir[f]
23476
39a12719ec65 merge: don't overwrite conflicting file in locally renamed directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 23475
diff changeset
   530
                if f2 in m1:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   531
                    actions[f2] = ('m', (f2, f, None, False, pa.node()),
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   532
                                   "local directory rename, both created")
23476
39a12719ec65 merge: don't overwrite conflicting file in locally renamed directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 23475
diff changeset
   533
                else:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   534
                    actions[f2] = ('dg', (f, fl2),
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   535
                                   "local directory rename - get from " + f)
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   536
            elif f in copy:
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   537
                f2 = copy[f]
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   538
                if f2 in m2:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   539
                    actions[f] = ('m', (f2, f, f2, False, pa.node()),
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   540
                                  "remote copied from " + f2)
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   541
                else:
23637
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   542
                    actions[f] = ('m', (f2, f, f2, True, pa.node()),
13f53a2aa342 merge: write manifestmerge() using dictionary with entry per file
Martin von Zweigbergk <martinvonz@google.com>
parents: 23544
diff changeset
   543
                                  "remote moved from " + f2)
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   544
            elif f not in ma:
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   545
                # local unknown, remote created: the logic is described by the
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   546
                # following table:
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   547
                #
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   548
                # force  branchmerge  different  |  action
23651
72da02d7f126 merge: collect checking for unknown files at end of manifestmerge()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23650
diff changeset
   549
                #   n         *           *      |   create
23650
b85c548ab14d merge: introduce 'c' action like 'g', but with additional safety
Martin von Zweigbergk <martinvonz@google.com>
parents: 23649
diff changeset
   550
                #   y         n           *      |   create
b85c548ab14d merge: introduce 'c' action like 'g', but with additional safety
Martin von Zweigbergk <martinvonz@google.com>
parents: 23649
diff changeset
   551
                #   y         y           n      |   create
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   552
                #   y         y           y      |   merge
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   553
                #
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   554
                # Checking whether the files are different is expensive, so we
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   555
                # don't do that when we can avoid it.
23649
18ab5e5955df merge: structure 'remote created' code to match table
Martin von Zweigbergk <martinvonz@google.com>
parents: 23641
diff changeset
   556
                if not force:
23651
72da02d7f126 merge: collect checking for unknown files at end of manifestmerge()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23650
diff changeset
   557
                    actions[f] = ('c', (fl2,), "remote created")
23649
18ab5e5955df merge: structure 'remote created' code to match table
Martin von Zweigbergk <martinvonz@google.com>
parents: 23641
diff changeset
   558
                elif not branchmerge:
23650
b85c548ab14d merge: introduce 'c' action like 'g', but with additional safety
Martin von Zweigbergk <martinvonz@google.com>
parents: 23649
diff changeset
   559
                    actions[f] = ('c', (fl2,), "remote created")
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   560
                else:
23654
9d56be47b5d6 merge: create 'cm' action for 'get or merge' case
Martin von Zweigbergk <martinvonz@google.com>
parents: 23653
diff changeset
   561
                    actions[f] = ('cm', (fl2, pa.node()),
9d56be47b5d6 merge: create 'cm' action for 'get or merge' case
Martin von Zweigbergk <martinvonz@google.com>
parents: 23653
diff changeset
   562
                                  "remote created, get or merge")
23473
922b10c870c5 merge: branch code into {n1 and n2, n1, n2} top-level cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 23448
diff changeset
   563
            elif n2 != ma[f]:
23651
72da02d7f126 merge: collect checking for unknown files at end of manifestmerge()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23650
diff changeset
   564
                if acceptremote:
72da02d7f126 merge: collect checking for unknown files at end of manifestmerge()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23650
diff changeset
   565
                    actions[f] = ('c', (fl2,), "remote recreating")
18606
95773237df7f manifestmerge: handle abort on local unknown, remote created files
Siddharth Agarwal <sid0@fb.com>
parents: 18605
diff changeset
   566
                else:
23651
72da02d7f126 merge: collect checking for unknown files at end of manifestmerge()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23650
diff changeset
   567
                    actions[f] = ('dc', (fl2,), "prompt deleted/changed")
72da02d7f126 merge: collect checking for unknown files at end of manifestmerge()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23650
diff changeset
   568
23526
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   569
    return actions, diverge, renamedelete
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
   570
23531
416c133145ee merge: extract _resolvetrivial() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 23526
diff changeset
   571
def _resolvetrivial(repo, wctx, mctx, ancestor, actions):
416c133145ee merge: extract _resolvetrivial() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 23526
diff changeset
   572
    """Resolves false conflicts where the nodeid changed but the content
416c133145ee merge: extract _resolvetrivial() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 23526
diff changeset
   573
       remained the same."""
416c133145ee merge: extract _resolvetrivial() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 23526
diff changeset
   574
23639
35c724903157 merge: let _resolvetrivial() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23638
diff changeset
   575
    for f, (m, args, msg) in actions.items():
35c724903157 merge: let _resolvetrivial() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23638
diff changeset
   576
        if m == 'cd' and f in ancestor and not wctx[f].cmp(ancestor[f]):
23531
416c133145ee merge: extract _resolvetrivial() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 23526
diff changeset
   577
            # local did change but ended up with same content
23639
35c724903157 merge: let _resolvetrivial() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23638
diff changeset
   578
            actions[f] = 'r', None, "prompt same"
35c724903157 merge: let _resolvetrivial() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23638
diff changeset
   579
        elif m == 'dc' and f in ancestor and not mctx[f].cmp(ancestor[f]):
23531
416c133145ee merge: extract _resolvetrivial() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 23526
diff changeset
   580
            # remote did change but ended up with same content
23639
35c724903157 merge: let _resolvetrivial() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23638
diff changeset
   581
            del actions[f] # don't get = keep local deleted
23531
416c133145ee merge: extract _resolvetrivial() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 23526
diff changeset
   582
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   583
def calculateupdates(repo, wctx, mctx, ancestors, branchmerge, force, partial,
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   584
                     acceptremote, followcopies):
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   585
    "Calculate the actions needed to merge mctx into wctx using ancestors"
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   586
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   587
    if len(ancestors) == 1: # default
23526
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   588
        actions, diverge, renamedelete = manifestmerge(
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   589
            repo, wctx, mctx, ancestors[0], branchmerge, force, partial,
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   590
            acceptremote, followcopies)
23656
d3e137c91f94 merge: move checking of unknown files out of manifestmerge()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23655
diff changeset
   591
        _checkunknownfiles(repo, wctx, mctx, force, actions)
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   592
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   593
    else: # only when merge.preferancestor=* - the default
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   594
        repo.ui.note(
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   595
            _("note: merging %s and %s using bids from ancestors %s\n") %
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   596
            (wctx, mctx, _(' and ').join(str(anc) for anc in ancestors)))
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   597
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   598
        # Call for bids
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   599
        fbids = {} # mapping filename to bids (action method to list af actions)
23526
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   600
        diverge, renamedelete = None, None
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   601
        for ancestor in ancestors:
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   602
            repo.ui.note(_('\ncalculating bids for ancestor %s\n') % ancestor)
23526
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   603
            actions, diverge1, renamedelete1 = manifestmerge(
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   604
                repo, wctx, mctx, ancestor, branchmerge, force, partial,
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   605
                acceptremote, followcopies)
23656
d3e137c91f94 merge: move checking of unknown files out of manifestmerge()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23655
diff changeset
   606
            _checkunknownfiles(repo, wctx, mctx, force, actions)
26318
d3bd6cefd742 bidmerge: choose shortest list of diverge and rename/delete warnings
Matt Mackall <mpm@selenic.com>
parents: 26304
diff changeset
   607
d3bd6cefd742 bidmerge: choose shortest list of diverge and rename/delete warnings
Matt Mackall <mpm@selenic.com>
parents: 26304
diff changeset
   608
            # Track the shortest set of warning on the theory that bid
d3bd6cefd742 bidmerge: choose shortest list of diverge and rename/delete warnings
Matt Mackall <mpm@selenic.com>
parents: 26304
diff changeset
   609
            # merge will correctly incorporate more information
d3bd6cefd742 bidmerge: choose shortest list of diverge and rename/delete warnings
Matt Mackall <mpm@selenic.com>
parents: 26304
diff changeset
   610
            if diverge is None or len(diverge1) < len(diverge):
23526
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   611
                diverge = diverge1
26318
d3bd6cefd742 bidmerge: choose shortest list of diverge and rename/delete warnings
Matt Mackall <mpm@selenic.com>
parents: 26304
diff changeset
   612
            if renamedelete is None or len(renamedelete) < len(renamedelete1):
23526
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   613
                renamedelete = renamedelete1
26318
d3bd6cefd742 bidmerge: choose shortest list of diverge and rename/delete warnings
Matt Mackall <mpm@selenic.com>
parents: 26304
diff changeset
   614
23638
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   615
            for f, a in sorted(actions.iteritems()):
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   616
                m, args, msg = a
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   617
                repo.ui.debug(' %s: %s -> %s\n' % (f, msg, m))
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   618
                if f in fbids:
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   619
                    d = fbids[f]
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   620
                    if m in d:
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   621
                        d[m].append(a)
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   622
                    else:
23638
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   623
                        d[m] = [a]
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   624
                else:
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   625
                    fbids[f] = {m: [a]}
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   626
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   627
        # Pick the best bid for each file
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   628
        repo.ui.note(_('\nauction for merging merge bids\n'))
23638
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   629
        actions = {}
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   630
        for f, bids in sorted(fbids.items()):
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   631
            # bids is a mapping from action method to list af actions
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   632
            # Consensus?
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   633
            if len(bids) == 1: # all bids are the same kind of method
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   634
                m, l = bids.items()[0]
25151
6eb4bdad198f cleanup: use __builtins__.all instead of util.all
Augie Fackler <augie@google.com>
parents: 24881
diff changeset
   635
                if all(a == l[0] for a in l[1:]): # len(bids) is > 1
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   636
                    repo.ui.note(" %s: consensus for %s\n" % (f, m))
23638
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   637
                    actions[f] = l[0]
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   638
                    continue
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   639
            # If keep is an option, just do it.
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   640
            if 'k' in bids:
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   641
                repo.ui.note(" %s: picking 'keep' action\n" % f)
23638
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   642
                actions[f] = bids['k'][0]
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   643
                continue
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   644
            # If there are gets and they all agree [how could they not?], do it.
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   645
            if 'g' in bids:
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   646
                ga0 = bids['g'][0]
25151
6eb4bdad198f cleanup: use __builtins__.all instead of util.all
Augie Fackler <augie@google.com>
parents: 24881
diff changeset
   647
                if all(a == ga0 for a in bids['g'][1:]):
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   648
                    repo.ui.note(" %s: picking 'get' action\n" % f)
23638
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   649
                    actions[f] = ga0
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   650
                    continue
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   651
            # TODO: Consider other simple actions such as mode changes
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   652
            # Handle inefficient democrazy.
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   653
            repo.ui.note(_(' %s: multiple bids for merge action:\n') % f)
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   654
            for m, l in sorted(bids.items()):
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   655
                for _f, args, msg in l:
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   656
                    repo.ui.note('  %s -> %s\n' % (msg, m))
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   657
            # Pick random action. TODO: Instead, prompt user when resolving
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   658
            m, l = bids.items()[0]
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   659
            repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') %
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   660
                         (f, m))
23638
09be050ca98c merge: let bid merge work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23637
diff changeset
   661
            actions[f] = l[0]
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   662
            continue
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   663
        repo.ui.note(_('end of auction\n\n'))
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   664
23639
35c724903157 merge: let _resolvetrivial() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23638
diff changeset
   665
    _resolvetrivial(repo, wctx, mctx, ancestors[0], actions)
35c724903157 merge: let _resolvetrivial() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23638
diff changeset
   666
23640
b46b9865dd08 merge: let _forgetremoved() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23639
diff changeset
   667
    if wctx.rev() is None:
b46b9865dd08 merge: let _forgetremoved() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23639
diff changeset
   668
        fractions = _forgetremoved(wctx, mctx, branchmerge)
b46b9865dd08 merge: let _forgetremoved() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23639
diff changeset
   669
        actions.update(fractions)
b46b9865dd08 merge: let _forgetremoved() work on the file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23639
diff changeset
   670
23526
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   671
    return actions, diverge, renamedelete
23385
91c24457c16a merge: move calculateupdates() before applyupdated()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23384
diff changeset
   672
21392
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   673
def batchremove(repo, actions):
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   674
    """apply removes to the working directory
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   675
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   676
    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
   677
    """
18640
a8648f32b8ed merge: don't fiddle with name lookups or i18n in hot loops
Bryan O'Sullivan <bryano@fb.com>
parents: 18639
diff changeset
   678
    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
   679
    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
   680
    wjoin = repo.wjoin
23879
b88278a308c6 localrepo: remove all external users of localrepo.wopener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23877
diff changeset
   681
    audit = repo.wvfs.audit
18633
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   682
    i = 0
21545
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   683
    for f, args, msg in actions:
21392
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   684
        repo.ui.debug(" %s: %s -> r\n" % (f, msg))
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   685
        if verbose:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   686
            repo.ui.note(_("removing %s\n") % f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   687
        audit(f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   688
        try:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   689
            unlink(wjoin(f), ignoremissing=True)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25151
diff changeset
   690
        except OSError as inst:
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   691
            repo.ui.warn(_("update failed to remove %s: %s!\n") %
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   692
                         (f, inst.strerror))
21392
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   693
        if i == 100:
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   694
            yield i, f
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   695
            i = 0
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   696
        i += 1
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   697
    if i > 0:
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   698
        yield i, f
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   699
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   700
def batchget(repo, mctx, actions):
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   701
    """apply gets to the working directory
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   702
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   703
    mctx is the context to get from
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   704
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   705
    yields tuples for progress updates
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   706
    """
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   707
    verbose = repo.ui.verbose
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   708
    fctx = mctx.filectx
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   709
    wwrite = repo.wwrite
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   710
    i = 0
21545
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   711
    for f, args, msg in actions:
21392
b1ce47dadbdf merge: separate worker functions for batch remove and batch get
Mads Kiilerich <madski@unity3d.com>
parents: 21391
diff changeset
   712
        repo.ui.debug(" %s: %s -> g\n" % (f, msg))
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   713
        if verbose:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   714
            repo.ui.note(_("getting %s\n") % f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   715
        wwrite(f, fctx(f).data(), args[0])
18633
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   716
        if i == 100:
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   717
            yield i, f
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   718
            i = 0
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   719
        i += 1
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   720
    if i > 0:
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   721
        yield i, f
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   722
21524
47b97d9af27e merge: add labels parameter from merge.update to filemerge
Durham Goode <durham@fb.com>
parents: 21392
diff changeset
   723
def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None):
11454
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   724
    """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
   725
9b0406b23be0 merge: pass constant cset ancestor to fctx.ancestor
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 11451
diff changeset
   726
    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
   727
    mctx is the context to be merged into the working copy
13162
115a9760c382 merge: document some internal return values.
Greg Ward <greg-hg@gerg.ca>
parents: 13158
diff changeset
   728
115a9760c382 merge: document some internal return values.
Greg Ward <greg-hg@gerg.ca>
parents: 13158
diff changeset
   729
    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
   730
    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
   731
    """
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   732
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   733
    updated, merged, removed, unresolved = 0, 0, 0, 0
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   734
    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
   735
    ms.reset(wctx.p1().node(), mctx.node())
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   736
    moves = []
21545
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   737
    for m, l in actions.items():
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   738
        l.sort()
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   739
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   740
    # prescan for merges
21545
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   741
    for f, args, msg in actions['m']:
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   742
        f1, f2, fa, move, anc = args
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   743
        if f == '.hgsubstate': # merged internally
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   744
            continue
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   745
        repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f))
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   746
        fcl = wctx[f1]
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   747
        fco = mctx[f2]
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   748
        actx = repo[anc]
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   749
        if fa in actx:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   750
            fca = actx[fa]
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   751
        else:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   752
            fca = repo.filectx(f1, fileid=nullrev)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   753
        ms.add(fcl, fco, fca, f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   754
        if f1 != f and move:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   755
            moves.append(f1)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   756
23879
b88278a308c6 localrepo: remove all external users of localrepo.wopener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23877
diff changeset
   757
    audit = repo.wvfs.audit
21390
26b84128c54d merge: move constant assignments a bit and use them more
Mads Kiilerich <madski@unity3d.com>
parents: 21389
diff changeset
   758
    _updating = _('updating')
26b84128c54d merge: move constant assignments a bit and use them more
Mads Kiilerich <madski@unity3d.com>
parents: 21389
diff changeset
   759
    _files = _('files')
26b84128c54d merge: move constant assignments a bit and use them more
Mads Kiilerich <madski@unity3d.com>
parents: 21389
diff changeset
   760
    progress = repo.ui.progress
14398
ae1f7a5373e8 applyupdates: audit unlinking of renamed files and directories
Adrian Buehlmann <adrian@cadifra.com>
parents: 14232
diff changeset
   761
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   762
    # remove renamed files after safely stored
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
   763
    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
   764
        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
   765
            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
   766
            audit(f)
18333
f6f23ecafc9b merge: use util.unlinkpath for removing moved files
Mads Kiilerich <mads@kiilerich.com>
parents: 18332
diff changeset
   767
            util.unlinkpath(repo.wjoin(f))
5042
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
   768
23526
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
   769
    numupdates = sum(len(l) for m, l in actions.items() if m != 'k')
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   770
21545
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   771
    if [a for a in actions['r'] if a[0] == '.hgsubstate']:
18632
3e20079117c5 merge: handle subrepo merges and .hgsubstate specially
Bryan O'Sullivan <bryano@fb.com>
parents: 18630
diff changeset
   772
        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
   773
21390
26b84128c54d merge: move constant assignments a bit and use them more
Mads Kiilerich <madski@unity3d.com>
parents: 21389
diff changeset
   774
    # remove in parallel (must come first)
18633
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   775
    z = 0
21545
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   776
    prog = worker.worker(repo.ui, 0.001, batchremove, (repo,), actions['r'])
19095
5cc71484ee9c merge: increase safety of parallel updating/removing on icasefs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18985
diff changeset
   777
    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
   778
        z += i
21390
26b84128c54d merge: move constant assignments a bit and use them more
Mads Kiilerich <madski@unity3d.com>
parents: 21389
diff changeset
   779
        progress(_updating, z, item=item, total=numupdates, unit=_files)
21545
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   780
    removed = len(actions['r'])
21390
26b84128c54d merge: move constant assignments a bit and use them more
Mads Kiilerich <madski@unity3d.com>
parents: 21389
diff changeset
   781
26b84128c54d merge: move constant assignments a bit and use them more
Mads Kiilerich <madski@unity3d.com>
parents: 21389
diff changeset
   782
    # get in parallel
21545
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   783
    prog = worker.worker(repo.ui, 0.001, batchget, (repo, mctx), actions['g'])
18639
5774732bb5e5 merge: apply non-interactive working dir updates in parallel
Bryan O'Sullivan <bryano@fb.com>
parents: 18633
diff changeset
   784
    for i, item in prog:
18633
6390dd22b12f merge: report non-interactive progress in chunks
Bryan O'Sullivan <bryano@fb.com>
parents: 18632
diff changeset
   785
        z += i
21390
26b84128c54d merge: move constant assignments a bit and use them more
Mads Kiilerich <madski@unity3d.com>
parents: 21389
diff changeset
   786
        progress(_updating, z, item=item, total=numupdates, unit=_files)
21545
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   787
    updated = len(actions['g'])
18630
9b9e2d9e83a1 merge: split out mostly-non-interactive working dir updates
Bryan O'Sullivan <bryano@fb.com>
parents: 18612
diff changeset
   788
21545
43eecb4e23f8 merge: use separate lists for each action type
Mads Kiilerich <madski@unity3d.com>
parents: 21524
diff changeset
   789
    if [a for a in actions['g'] if a[0] == '.hgsubstate']:
18632
3e20079117c5 merge: handle subrepo merges and .hgsubstate specially
Bryan O'Sullivan <bryano@fb.com>
parents: 18630
diff changeset
   790
        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
   791
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   792
    # forget (manifest only, just log it) (must come first)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   793
    for f, args, msg in actions['f']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   794
        repo.ui.debug(" %s: %s -> f\n" % (f, msg))
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   795
        z += 1
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   796
        progress(_updating, z, item=f, total=numupdates, unit=_files)
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   797
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   798
    # re-add (manifest only, just log it)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   799
    for f, args, msg in actions['a']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   800
        repo.ui.debug(" %s: %s -> a\n" % (f, msg))
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   801
        z += 1
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   802
        progress(_updating, z, item=f, total=numupdates, unit=_files)
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   803
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   804
    # keep (noop, just log it)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   805
    for f, args, msg in actions['k']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   806
        repo.ui.debug(" %s: %s -> k\n" % (f, msg))
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   807
        # no progress
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   808
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   809
    # directory rename, move local
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   810
    for f, args, msg in actions['dm']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   811
        repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   812
        z += 1
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   813
        progress(_updating, z, item=f, total=numupdates, unit=_files)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   814
        f0, flags = args
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   815
        repo.ui.note(_("moving %s to %s\n") % (f0, f))
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   816
        audit(f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   817
        repo.wwrite(f, wctx.filectx(f0).data(), flags)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   818
        util.unlinkpath(repo.wjoin(f0))
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   819
        updated += 1
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   820
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   821
    # local directory rename, get
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   822
    for f, args, msg in actions['dg']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   823
        repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   824
        z += 1
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   825
        progress(_updating, z, item=f, total=numupdates, unit=_files)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   826
        f0, flags = args
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   827
        repo.ui.note(_("getting %s to %s\n") % (f0, f))
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   828
        repo.wwrite(f, mctx.filectx(f0).data(), flags)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   829
        updated += 1
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   830
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   831
    # exec
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   832
    for f, args, msg in actions['e']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   833
        repo.ui.debug(" %s: %s -> e\n" % (f, msg))
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   834
        z += 1
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   835
        progress(_updating, z, item=f, total=numupdates, unit=_files)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   836
        flags, = args
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   837
        audit(f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   838
        util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   839
        updated += 1
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   840
26292
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   841
    # merge
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   842
    for f, args, msg in actions['m']:
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   843
        repo.ui.debug(" %s: %s -> m\n" % (f, msg))
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   844
        z += 1
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   845
        progress(_updating, z, item=f, total=numupdates, unit=_files)
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   846
        if f == '.hgsubstate': # subrepo states need updating
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   847
            subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   848
                             overwrite)
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   849
            continue
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   850
        audit(f)
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   851
        r = ms.resolve(f, wctx, labels=labels)
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   852
        if r is not None and r > 0:
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   853
            unresolved += 1
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   854
        else:
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   855
            if r is None:
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   856
                updated += 1
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   857
            else:
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   858
                merged += 1
007ac1acfcac merge: move merge step to the end
Siddharth Agarwal <sid0@fb.com>
parents: 25959
diff changeset
   859
12369
6f0d9d79111f merge: delay writing the mergestate during until commit is called
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 12279
diff changeset
   860
    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
   861
    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
   862
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   863
    return updated, merged, removed, unresolved
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   864
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
   865
def recordupdates(repo, actions, branchmerge):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   866
    "record merge actions to the dirstate"
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   867
    # remove (must come first)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   868
    for f, args, msg in actions['r']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   869
        if branchmerge:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   870
            repo.dirstate.remove(f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   871
        else:
21389
e741972017d9 merge: change priority / ordering of merge actions
Mads Kiilerich <madski@unity3d.com>
parents: 21269
diff changeset
   872
            repo.dirstate.drop(f)
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   873
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   874
    # forget (must come first)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   875
    for f, args, msg in actions['f']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   876
        repo.dirstate.drop(f)
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   877
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   878
    # re-add
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   879
    for f, args, msg in actions['a']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   880
        if not branchmerge:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   881
            repo.dirstate.add(f)
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   882
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   883
    # exec change
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   884
    for f, args, msg in actions['e']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   885
        repo.dirstate.normallookup(f)
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   886
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   887
    # keep
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   888
    for f, args, msg in actions['k']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   889
        pass
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   890
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   891
    # get
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   892
    for f, args, msg in actions['g']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   893
        if branchmerge:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   894
            repo.dirstate.otherparent(f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   895
        else:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   896
            repo.dirstate.normal(f)
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   897
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   898
    # merge
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   899
    for f, args, msg in actions['m']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   900
        f1, f2, fa, move, anc = args
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   901
        if branchmerge:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   902
            # We've done a branch merge, mark this file as merged
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   903
            # so that we properly record the merger later
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   904
            repo.dirstate.merge(f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   905
            if f1 != f2: # copy/rename
3308
ecc1bf27378c merge: unify merge and copy actions
Matt Mackall <mpm@selenic.com>
parents: 3307
diff changeset
   906
                if move:
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   907
                    repo.dirstate.remove(f1)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   908
                if f1 != f:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   909
                    repo.dirstate.copy(f1, f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   910
                else:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   911
                    repo.dirstate.copy(f2, f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   912
        else:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   913
            # We've update-merged a locally modified file, so
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   914
            # we set the dirstate to emulate a normal checkout
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   915
            # of that file some time in the past. Thus our
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   916
            # merge will appear as a normal local file
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   917
            # modification.
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   918
            if f2 == f: # file not locally copied/moved
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   919
                repo.dirstate.normallookup(f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   920
            if move:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   921
                repo.dirstate.drop(f1)
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   922
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   923
    # directory rename, move local
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   924
    for f, args, msg in actions['dm']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   925
        f0, flag = args
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   926
        if branchmerge:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   927
            repo.dirstate.add(f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   928
            repo.dirstate.remove(f0)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   929
            repo.dirstate.copy(f0, f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   930
        else:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   931
            repo.dirstate.normal(f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   932
            repo.dirstate.drop(f0)
21391
cb15835456cb merge: change debug logging - test output changes but no real changes
Mads Kiilerich <madski@unity3d.com>
parents: 21390
diff changeset
   933
21551
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   934
    # directory rename, get
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   935
    for f, args, msg in actions['dg']:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   936
        f0, flag = args
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   937
        if branchmerge:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   938
            repo.dirstate.add(f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   939
            repo.dirstate.copy(f0, f)
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   940
        else:
bde505f47141 merge: fix stupid indentation left over from previous refactorings
Mads Kiilerich <madski@unity3d.com>
parents: 21545
diff changeset
   941
            repo.dirstate.normal(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
   942
16696
d1afbf03e69a rebase: allow collapsing branches in place (issue3111)
Patrick Mezard <patrick@mezard.eu>
parents: 16683
diff changeset
   943
def update(repo, node, branchmerge, force, partial, ancestor=None,
21524
47b97d9af27e merge: add labels parameter from merge.update to filemerge
Durham Goode <durham@fb.com>
parents: 21392
diff changeset
   944
           mergeancestor=False, labels=None):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   945
    """
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   946
    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
   947
9716
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   948
    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
   949
    branchmerge = whether to merge between branches
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   950
    force = whether to force branch merging or file overwriting
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   951
    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
   952
    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
   953
      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
   954
      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
   955
      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
   956
      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
   957
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   958
    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
   959
    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
   960
    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
   961
    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
   962
    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
   963
12279
28e2e3804f2e combine tests
Adrian Buehlmann <adrian@cadifra.com>
parents: 12032
diff changeset
   964
    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
   965
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   966
    -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
   967
     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
   968
     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
   969
     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
   970
     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
   971
     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
   972
     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
   973
     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
   974
     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
   975
ea8c207a0f78 update: add comments and test cases for updating across branches
Stuart W Marks <smarks@smarks.org>
parents: 9467
diff changeset
   976
    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
   977
    * = don't-care
19798
76df01e56e7f update: improve error message for clean non-linear update
Siddharth Agarwal <sid0@fb.com>
parents: 19482
diff changeset
   978
    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
   979
    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
   980
                 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
   981
    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
   982
    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
   983
    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
   984
115a9760c382 merge: document some internal return values.
Greg Ward <greg-hg@gerg.ca>
parents: 13158
diff changeset
   985
    Return the same tuple as applyupdates().
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
   986
    """
2815
4870f795f681 Merge: combine force and forcemerge arguments
Matt Mackall <mpm@selenic.com>
parents: 2814
diff changeset
   987
9717
68a1b9d0663e update: allow branch crossing without -c or -C, with no uncommitted changes
Stuart W Marks <smarks@smarks.org>
parents: 9716
diff changeset
   988
    onode = node
4917
126f527b3ba3 Make repo locks recursive, eliminate all passing of lock/wlock
Matt Mackall <mpm@selenic.com>
parents: 4915
diff changeset
   989
    wlock = repo.wlock()
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   990
    try:
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6746
diff changeset
   991
        wc = repo[None]
20279
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
   992
        pl = wc.parents()
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
   993
        p1 = pl[0]
21081
ffd7b6ce46ff merge: pass merge ancestor to calculateupdates as a list
Mads Kiilerich <madski@unity3d.com>
parents: 21080
diff changeset
   994
        pas = [None]
23405
2a038deeac9a merge: 0 is a valid ancestor different from None
Mads Kiilerich <madski@unity3d.com>
parents: 23398
diff changeset
   995
        if ancestor is not None:
21081
ffd7b6ce46ff merge: pass merge ancestor to calculateupdates as a list
Mads Kiilerich <madski@unity3d.com>
parents: 21080
diff changeset
   996
            pas = [repo[ancestor]]
20279
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
   997
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
   998
        if node is None:
26570
c8b332b1eb1f merge: get the default update destination from the function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26534
diff changeset
   999
            node = repo[destutil.destupdate(repo)].node()
20280
95b9c6149e17 merge: consider successor changesets for a bare update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20279
diff changeset
  1000
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
  1001
        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
  1002
5b4f963d21cc merge: refactor initialization of variables in update
Sean Farley <sean.michael.farley@gmail.com>
parents: 20278
diff changeset
  1003
        p2 = repo[node]
21081
ffd7b6ce46ff merge: pass merge ancestor to calculateupdates as a list
Mads Kiilerich <madski@unity3d.com>
parents: 21080
diff changeset
  1004
        if pas[0] is None:
25844
18541e9510c5 merge: make merge.preferancestor type and default consistent
Matt Mackall <mpm@selenic.com>
parents: 25843
diff changeset
  1005
            if repo.ui.configlist('merge', 'preferancestor', ['*']) == ['*']:
21128
f4014f646f71 merge: with merge.preferancestor=*, run an auction with bids from ancestors
Mads Kiilerich <madski@unity3d.com>
parents: 21082
diff changeset
  1006
                cahs = repo.changelog.commonancestorsheads(p1.node(), p2.node())
f4014f646f71 merge: with merge.preferancestor=*, run an auction with bids from ancestors
Mads Kiilerich <madski@unity3d.com>
parents: 21082
diff changeset
  1007
                pas = [repo[anc] for anc in (sorted(cahs) or [nullid])]
f4014f646f71 merge: with merge.preferancestor=*, run an auction with bids from ancestors
Mads Kiilerich <madski@unity3d.com>
parents: 21082
diff changeset
  1008
            else:
22179
46308fadaa15 merge: show the scary multiple ancestor hint for merges only, not for updates
Mads Kiilerich <madski@unity3d.com>
parents: 21551
diff changeset
  1009
                pas = [p1.ancestor(p2, warn=branchmerge)]
13874
9d67277c9204 merge: add ancestor to the update function
Matt Mackall <mpm@selenic.com>
parents: 13728
diff changeset
  1010
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
  1011
        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
  1012
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
  1013
        ### check phase
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
  1014
        if not overwrite and len(pl) > 1:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26570
diff changeset
  1015
            raise error.Abort(_("outstanding uncommitted merge"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
  1016
        if branchmerge:
21081
ffd7b6ce46ff merge: pass merge ancestor to calculateupdates as a list
Mads Kiilerich <madski@unity3d.com>
parents: 21080
diff changeset
  1017
            if pas == [p2]:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26570
diff changeset
  1018
                raise error.Abort(_("merging with a working directory ancestor"
11417
6f1d1ed3e19a merge: improve merge with ancestor message
Matt Mackall <mpm@selenic.com>
parents: 11178
diff changeset
  1019
                                   " has no effect"))
21081
ffd7b6ce46ff merge: pass merge ancestor to calculateupdates as a list
Mads Kiilerich <madski@unity3d.com>
parents: 21080
diff changeset
  1020
            elif pas == [p1]:
16696
d1afbf03e69a rebase: allow collapsing branches in place (issue3111)
Patrick Mezard <patrick@mezard.eu>
parents: 16683
diff changeset
  1021
                if not mergeancestor and p1.branch() == p2.branch():
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26570
diff changeset
  1022
                    raise error.Abort(_("nothing to merge"),
15619
6c8573dd1b6b merge: make 'nothing to merge' aborts consistent
Kevin Bullock <kbullock@ringworld.org>
parents: 15538
diff changeset
  1023
                                     hint=_("use 'hg update' "
6c8573dd1b6b merge: make 'nothing to merge' aborts consistent
Kevin Bullock <kbullock@ringworld.org>
parents: 15538
diff changeset
  1024
                                            "or check 'hg heads'"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
  1025
            if not force and (wc.files() or wc.deleted()):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26570
diff changeset
  1026
                raise error.Abort(_("uncommitted changes"),
15619
6c8573dd1b6b merge: make 'nothing to merge' aborts consistent
Kevin Bullock <kbullock@ringworld.org>
parents: 15538
diff changeset
  1027
                                 hint=_("use 'hg status' to list changes"))
18364
6252b4f1c4b4 subrepos: process subrepos in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 18360
diff changeset
  1028
            for s in sorted(wc.substate):
24471
1ff35d76421c subrepo: add bailifchanged to centralize raising Abort if subrepo is dirty
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23971
diff changeset
  1029
                wc.sub(s).bailifchanged()
13437
6169493ac3f9 Do not allow merging with uncommitted changes in a subrepo
Oleg Stepanov <oleg.stepanov@jetbrains.com>
parents: 13400
diff changeset
  1030
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
  1031
        elif not overwrite:
19929
ab2362e1672e merge: exit early during a no-op update (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 19803
diff changeset
  1032
            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
  1033
                # 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
  1034
                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
  1035
                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
  1036
                return 0, 0, 0, 0
ab2362e1672e merge: exit early during a no-op update (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 19803
diff changeset
  1037
21081
ffd7b6ce46ff merge: pass merge ancestor to calculateupdates as a list
Mads Kiilerich <madski@unity3d.com>
parents: 21080
diff changeset
  1038
            if pas 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
  1039
                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
  1040
                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
  1041
                    # 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
  1042
                    # 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
  1043
                    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
  1044
                    # 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
  1045
                    if repo[node].node() in foreground:
21081
ffd7b6ce46ff merge: pass merge ancestor to calculateupdates as a list
Mads Kiilerich <madski@unity3d.com>
parents: 21080
diff changeset
  1046
                        pas = [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
  1047
                    elif dirty:
ab3e42225dbc update: add error message for dirty non-linear update with no rev
Siddharth Agarwal <sid0@fb.com>
parents: 19798
diff changeset
  1048
                        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
  1049
                        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
  1050
                            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
  1051
                                     " discard changes")
4894e0d9462d update: improve error message for dirty non-linear update with rev
Siddharth Agarwal <sid0@fb.com>
parents: 19799
diff changeset
  1052
                        else:
4894e0d9462d update: improve error message for dirty non-linear update with rev
Siddharth Agarwal <sid0@fb.com>
parents: 19799
diff changeset
  1053
                            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
  1054
                                     " changes")
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26570
diff changeset
  1055
                        raise error.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
  1056
                    else:  # node is none
19798
76df01e56e7f update: improve error message for clean non-linear update
Siddharth Agarwal <sid0@fb.com>
parents: 19482
diff changeset
  1057
                        msg = _("not a linear update")
76df01e56e7f update: improve error message for clean non-linear update
Siddharth Agarwal <sid0@fb.com>
parents: 19482
diff changeset
  1058
                        hint = _("merge or update --check to force update")
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26570
diff changeset
  1059
                        raise error.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
  1060
                else:
a59e575c6ff8 update: allow dirty update to foreground (successors)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18895
diff changeset
  1061
                    # Allow jumping branches if clean and specific rev given
21081
ffd7b6ce46ff merge: pass merge ancestor to calculateupdates as a list
Mads Kiilerich <madski@unity3d.com>
parents: 21080
diff changeset
  1062
                    pas = [p1]
2814
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
  1063
25843
bf9ea348b487 merge: mark ancient debugging option
Matt Mackall <mpm@selenic.com>
parents: 25754
diff changeset
  1064
        # deprecated config: merge.followcopies
21080
04540a8499a3 merge: move ancestor selection tweaking from manifestmerge to update function
Mads Kiilerich <madski@unity3d.com>
parents: 21024
diff changeset
  1065
        followcopies = False
04540a8499a3 merge: move ancestor selection tweaking from manifestmerge to update function
Mads Kiilerich <madski@unity3d.com>
parents: 21024
diff changeset
  1066
        if overwrite:
21081
ffd7b6ce46ff merge: pass merge ancestor to calculateupdates as a list
Mads Kiilerich <madski@unity3d.com>
parents: 21080
diff changeset
  1067
            pas = [wc]
ffd7b6ce46ff merge: pass merge ancestor to calculateupdates as a list
Mads Kiilerich <madski@unity3d.com>
parents: 21080
diff changeset
  1068
        elif pas == [p2]: # backwards
ffd7b6ce46ff merge: pass merge ancestor to calculateupdates as a list
Mads Kiilerich <madski@unity3d.com>
parents: 21080
diff changeset
  1069
            pas = [wc.p1()]
21080
04540a8499a3 merge: move ancestor selection tweaking from manifestmerge to update function
Mads Kiilerich <madski@unity3d.com>
parents: 21024
diff changeset
  1070
        elif not branchmerge and not wc.dirty(missing=True):
04540a8499a3 merge: move ancestor selection tweaking from manifestmerge to update function
Mads Kiilerich <madski@unity3d.com>
parents: 21024
diff changeset
  1071
            pass
23380
90cc552ceed5 merge: consistently use single quotes for non-user-facing strings
Martin von Zweigbergk <martinvonz@google.com>
parents: 23362
diff changeset
  1072
        elif pas[0] and repo.ui.configbool('merge', 'followcopies', True):
21080
04540a8499a3 merge: move ancestor selection tweaking from manifestmerge to update function
Mads Kiilerich <madski@unity3d.com>
parents: 21024
diff changeset
  1073
            followcopies = True
04540a8499a3 merge: move ancestor selection tweaking from manifestmerge to update function
Mads Kiilerich <madski@unity3d.com>
parents: 21024
diff changeset
  1074
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
  1075
        ### calculate phase
23641
a7a0f32a383f merge: make calculateupdates() return file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23640
diff changeset
  1076
        actionbyfile, diverge, renamedelete = calculateupdates(
23526
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
  1077
            repo, wc, p2, pas, branchmerge, force, partial, mergeancestor,
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
  1078
            followcopies)
23641
a7a0f32a383f merge: make calculateupdates() return file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23640
diff changeset
  1079
        # Convert to dictionary-of-lists format
a7a0f32a383f merge: make calculateupdates() return file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23640
diff changeset
  1080
        actions = dict((m, []) for m in 'a f g cd dc r dm dg m e k'.split())
a7a0f32a383f merge: make calculateupdates() return file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23640
diff changeset
  1081
        for f, (m, args, msg) in actionbyfile.iteritems():
a7a0f32a383f merge: make calculateupdates() return file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23640
diff changeset
  1082
            if m not in actions:
a7a0f32a383f merge: make calculateupdates() return file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23640
diff changeset
  1083
                actions[m] = []
a7a0f32a383f merge: make calculateupdates() return file->action dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 23640
diff changeset
  1084
            actions[m].append((f, args, msg))
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1085
23544
7cc0fb0080b6 merge: perform case-collision checking on final set of actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23541
diff changeset
  1086
        if not util.checkcase(repo.path):
7cc0fb0080b6 merge: perform case-collision checking on final set of actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23541
diff changeset
  1087
            # check collision between files only in p2 for clean update
7cc0fb0080b6 merge: perform case-collision checking on final set of actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23541
diff changeset
  1088
            if (not branchmerge and
7cc0fb0080b6 merge: perform case-collision checking on final set of actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23541
diff changeset
  1089
                (force or not wc.dirty(missing=True, branch=False))):
7cc0fb0080b6 merge: perform case-collision checking on final set of actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23541
diff changeset
  1090
                _checkcollision(repo, p2.manifest(), None)
7cc0fb0080b6 merge: perform case-collision checking on final set of actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23541
diff changeset
  1091
            else:
7cc0fb0080b6 merge: perform case-collision checking on final set of actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23541
diff changeset
  1092
                _checkcollision(repo, wc.manifest(), actions)
7cc0fb0080b6 merge: perform case-collision checking on final set of actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23541
diff changeset
  1093
23541
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1094
        # Prompt and create actions. TODO: Move this towards resolve phase.
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1095
        for f, args, msg in sorted(actions['cd']):
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1096
            if repo.ui.promptchoice(
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1097
                _("local changed %s which remote deleted\n"
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1098
                  "use (c)hanged version or (d)elete?"
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1099
                  "$$ &Changed $$ &Delete") % f, 0):
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1100
                actions['r'].append((f, None, "prompt delete"))
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1101
            else:
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1102
                actions['a'].append((f, None, "prompt keep"))
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1103
        del actions['cd'][:]
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1104
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1105
        for f, args, msg in sorted(actions['dc']):
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1106
            flags, = args
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1107
            if repo.ui.promptchoice(
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1108
                _("remote changed %s which local deleted\n"
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1109
                  "use (c)hanged version or leave (d)eleted?"
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1110
                  "$$ &Changed $$ &Deleted") % f, 0) == 0:
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1111
                actions['g'].append((f, (flags,), "prompt recreating"))
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1112
        del actions['dc'][:]
495bc1b65d25 merge: move cd/dc prompts after largefiles prompts
Martin von Zweigbergk <martinvonz@google.com>
parents: 23531
diff changeset
  1113
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
  1114
        ### apply phase
13550
1792b8a9422b merge: back out single-parent fast-forward merge
Matt Mackall <mpm@selenic.com>
parents: 13536
diff changeset
  1115
        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
  1116
            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
  1117
        if not partial:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
  1118
            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
  1119
            # 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
  1120
            repo.vfs.write('updatestate', p2.hex())
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1121
21524
47b97d9af27e merge: add labels parameter from merge.update to filemerge
Durham Goode <durham@fb.com>
parents: 21392
diff changeset
  1122
        stats = applyupdates(repo, actions, wc, p2, overwrite, labels=labels)
2899
8743188f4d2e merge: consolidate dirstate updates
Matt Mackall <mpm@selenic.com>
parents: 2898
diff changeset
  1123
23525
5126d7718d7c merge: move dr/rd warning messages out of applyupdates()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23524
diff changeset
  1124
        # divergent renames
23526
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
  1125
        for f, fl in sorted(diverge.iteritems()):
23525
5126d7718d7c merge: move dr/rd warning messages out of applyupdates()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23524
diff changeset
  1126
            repo.ui.warn(_("note: possible conflict - %s was renamed "
5126d7718d7c merge: move dr/rd warning messages out of applyupdates()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23524
diff changeset
  1127
                           "multiple times to:\n") % f)
5126d7718d7c merge: move dr/rd warning messages out of applyupdates()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23524
diff changeset
  1128
            for nf in fl:
5126d7718d7c merge: move dr/rd warning messages out of applyupdates()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23524
diff changeset
  1129
                repo.ui.warn(" %s\n" % nf)
5126d7718d7c merge: move dr/rd warning messages out of applyupdates()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23524
diff changeset
  1130
5126d7718d7c merge: move dr/rd warning messages out of applyupdates()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23524
diff changeset
  1131
        # rename and delete
23526
a5887f2da5e6 merge: don't treat 'diverge' and 'renamedelete' like actions
Martin von Zweigbergk <martinvonz@google.com>
parents: 23525
diff changeset
  1132
        for f, fl in sorted(renamedelete.iteritems()):
23525
5126d7718d7c merge: move dr/rd warning messages out of applyupdates()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23524
diff changeset
  1133
            repo.ui.warn(_("note: possible conflict - %s was deleted "
5126d7718d7c merge: move dr/rd warning messages out of applyupdates()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23524
diff changeset
  1134
                           "and renamed to:\n") % f)
5126d7718d7c merge: move dr/rd warning messages out of applyupdates()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23524
diff changeset
  1135
            for nf in fl:
5126d7718d7c merge: move dr/rd warning messages out of applyupdates()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23524
diff changeset
  1136
                repo.ui.warn(" %s\n" % nf)
5126d7718d7c merge: move dr/rd warning messages out of applyupdates()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23524
diff changeset
  1137
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
  1138
        if not partial:
22405
6f63c47cbb86 dirstate: wrap setparent calls with begin/endparentchange (issue4353)
Durham Goode <durham@fb.com>
parents: 22207
diff changeset
  1139
            repo.dirstate.beginparentchange()
16551
ebf6d38c9063 localrepo: add setparents() to adjust dirstate copies (issue3407)
Patrick Mezard <patrick@mezard.eu>
parents: 16534
diff changeset
  1140
            repo.setparents(fp1, fp2)
18330
b717f49833a2 merge: rename list of actions from action to actions
Mads Kiilerich <mads@kiilerich.com>
parents: 18329
diff changeset
  1141
            recordupdates(repo, actions, branchmerge)
19482
499fc471296b update: add tracking of interrupted updates (issue3113)
Matt Mackall <mpm@selenic.com>
parents: 19285
diff changeset
  1142
            # update completed, clear state
499fc471296b update: add tracking of interrupted updates (issue3113)
Matt Mackall <mpm@selenic.com>
parents: 19285
diff changeset
  1143
            util.unlink(repo.join('updatestate'))
499fc471296b update: add tracking of interrupted updates (issue3113)
Matt Mackall <mpm@selenic.com>
parents: 19285
diff changeset
  1144
13561
0ab0ceefddf2 merge: remove last traces of fastforward merging
Mads Kiilerich <mads@kiilerich.com>
parents: 13550
diff changeset
  1145
            if not branchmerge:
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
  1146
                repo.dirstate.setbranch(p2.branch())
22405
6f63c47cbb86 dirstate: wrap setparent calls with begin/endparentchange (issue4353)
Durham Goode <durham@fb.com>
parents: 22207
diff changeset
  1147
            repo.dirstate.endparentchange()
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
  1148
    finally:
8109
496ae1ea4698 switch lock releasing in the core from gc to explicit
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7848
diff changeset
  1149
        wlock.release()
10492
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
  1150
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
  1151
    if not partial:
24881
51844b8b5017 merge: run update hook after the last wlock release
Matt Harbison <matt_harbison@yahoo.com>
parents: 24643
diff changeset
  1152
        def updatehook(parent1=xp1, parent2=xp2, error=stats[3]):
51844b8b5017 merge: run update hook after the last wlock release
Matt Harbison <matt_harbison@yahoo.com>
parents: 24643
diff changeset
  1153
            repo.hook('update', parent1=parent1, parent2=parent2, error=error)
51844b8b5017 merge: run update hook after the last wlock release
Matt Harbison <matt_harbison@yahoo.com>
parents: 24643
diff changeset
  1154
        repo._afterlock(updatehook)
10492
0e64d814d7d0 run commit and update hooks after command completion (issue1827)
Sune Foldager <cryo@cyanite.org>
parents: 10431
diff changeset
  1155
    return stats
22902
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1156
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1157
def graft(repo, ctx, pctx, labels):
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1158
    """Do a graft-like merge.
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1159
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1160
    This is a merge where the merge ancestor is chosen such that one
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1161
    or more changesets are grafted onto the current changeset. In
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1162
    addition to the merge, this fixes up the dirstate to include only
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1163
    a single parent and tries to duplicate any renames/copies
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1164
    appropriately.
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1165
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1166
    ctx - changeset to rebase
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1167
    pctx - merge base, usually ctx.p1()
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1168
    labels - merge labels eg ['local', 'graft']
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1169
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1170
    """
24643
a8e6897dffbe graft: allow creating sibling grafts
Durham Goode <durham@fb.com>
parents: 24471
diff changeset
  1171
    # If we're grafting a descendant onto an ancestor, be sure to pass
a8e6897dffbe graft: allow creating sibling grafts
Durham Goode <durham@fb.com>
parents: 24471
diff changeset
  1172
    # mergeancestor=True to update. This does two things: 1) allows the merge if
a8e6897dffbe graft: allow creating sibling grafts
Durham Goode <durham@fb.com>
parents: 24471
diff changeset
  1173
    # the destination is the same as the parent of the ctx (so we can use graft
a8e6897dffbe graft: allow creating sibling grafts
Durham Goode <durham@fb.com>
parents: 24471
diff changeset
  1174
    # to copy commits), and 2) informs update that the incoming changes are
a8e6897dffbe graft: allow creating sibling grafts
Durham Goode <durham@fb.com>
parents: 24471
diff changeset
  1175
    # newer than the destination so it doesn't prompt about "remote changed foo
a8e6897dffbe graft: allow creating sibling grafts
Durham Goode <durham@fb.com>
parents: 24471
diff changeset
  1176
    # which local deleted".
a8e6897dffbe graft: allow creating sibling grafts
Durham Goode <durham@fb.com>
parents: 24471
diff changeset
  1177
    mergeancestor = repo.changelog.isancestor(repo['.'].node(), ctx.node())
22902
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1178
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1179
    stats = update(repo, ctx.node(), True, True, False, pctx.node(),
24643
a8e6897dffbe graft: allow creating sibling grafts
Durham Goode <durham@fb.com>
parents: 24471
diff changeset
  1180
                   mergeancestor=mergeancestor, labels=labels)
a8e6897dffbe graft: allow creating sibling grafts
Durham Goode <durham@fb.com>
parents: 24471
diff changeset
  1181
22902
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1182
    # drop the second merge parent
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1183
    repo.dirstate.beginparentchange()
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1184
    repo.setparents(repo['.'].node(), nullid)
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1185
    repo.dirstate.write()
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1186
    # fix up dirstate for copies and renames
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1187
    copies.duplicatecopies(repo, ctx.rev(), pctx.rev())
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1188
    repo.dirstate.endparentchange()
ce0592328d68 merge: add merge.graft helper
Matt Mackall <mpm@selenic.com>
parents: 22841
diff changeset
  1189
    return stats