hgext/absorb.py
author Simon Sapin <simon.sapin@octobus.net>
Wed, 13 Oct 2021 15:58:14 +0200
changeset 48263 83d0bd45b662
parent 47012 d55b71393907
child 48875 6000f5b25c9b
permissions -rw-r--r--
dirstate-v2: actually use sub-second mtime precision Instead of zero, set the nanoseconds field to its correct value whenever possible and preserve it across serialization+parsing. Differential Revision: https://phab.mercurial-scm.org/D11702
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     1
# absorb.py
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     2
#
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     3
# Copyright 2016 Facebook, Inc.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     4
#
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     7
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     8
"""apply working directory changes to changesets (EXPERIMENTAL)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
     9
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    10
The absorb extension provides a command to use annotate information to
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    11
amend modified chunks into the corresponding non-public changesets.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    12
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    13
::
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    14
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    15
    [absorb]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    16
    # only check 50 recent non-public changesets at most
38961
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
    17
    max-stack-size = 50
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    18
    # whether to add noise to new commits to avoid obsolescence cycle
38961
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
    19
    add-noise = 1
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    20
    # make `amend --correlated` a shortcut to the main command
38961
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
    21
    amend-flag = correlated
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    22
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    23
    [color]
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
    24
    absorb.description = yellow
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    25
    absorb.node = blue bold
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    26
    absorb.path = bold
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    27
"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    28
38922
ec0697f4f9c9 absorb: note some TODOs from the code review
Augie Fackler <augie@google.com>
parents: 38921
diff changeset
    29
# TODO:
ec0697f4f9c9 absorb: note some TODOs from the code review
Augie Fackler <augie@google.com>
parents: 38921
diff changeset
    30
#  * Rename config items to [commands] namespace
ec0697f4f9c9 absorb: note some TODOs from the code review
Augie Fackler <augie@google.com>
parents: 38921
diff changeset
    31
#  * Converge getdraftstack() with other code in core
ec0697f4f9c9 absorb: note some TODOs from the code review
Augie Fackler <augie@google.com>
parents: 38921
diff changeset
    32
#  * move many attributes on fixupstate to be private
ec0697f4f9c9 absorb: note some TODOs from the code review
Augie Fackler <augie@google.com>
parents: 38921
diff changeset
    33
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    34
from __future__ import absolute_import
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    35
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    36
import collections
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    37
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    38
from mercurial.i18n import _
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45878
diff changeset
    39
from mercurial.node import (
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45878
diff changeset
    40
    hex,
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45878
diff changeset
    41
    short,
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45878
diff changeset
    42
)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    43
from mercurial import (
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    44
    cmdutil,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    45
    commands,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    46
    context,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    47
    crecord,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    48
    error,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    49
    linelog,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    50
    mdiff,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    51
    obsolete,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    52
    patch,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    53
    phases,
38920
a5c8c5476339 absorb: use pycompat to get xrange
Augie Fackler <augie@google.com>
parents: 38919
diff changeset
    54
    pycompat,
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    55
    registrar,
45124
3ee8e2d5c0d8 absorb: consider rewrite.empty-successor configuration
Manuel Jacob <me@manueljacob.de>
parents: 44991
diff changeset
    56
    rewriteutil,
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    57
    scmutil,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    58
    util,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    59
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
    60
from mercurial.utils import stringutil
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    61
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    62
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    63
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    64
# be specifying the version(s) of Mercurial they are tested with, or
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    65
# leave the attribute unspecified.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    66
testedwith = b'ships-with-hg-core'
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    67
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    68
cmdtable = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    69
command = registrar.command(cmdtable)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    70
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    71
configtable = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    72
configitem = registrar.configitem(configtable)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    73
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    74
configitem(b'absorb', b'add-noise', default=True)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    75
configitem(b'absorb', b'amend-flag', default=None)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    76
configitem(b'absorb', b'max-stack-size', default=50)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    77
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    78
colortable = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    79
    b'absorb.description': b'yellow',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    80
    b'absorb.node': b'blue bold',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    81
    b'absorb.path': b'bold',
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    82
}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    83
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    84
defaultdict = collections.defaultdict
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    85
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
    86
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    87
class nullui(object):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    88
    """blank ui object doing nothing"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
    89
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    90
    debugflag = False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    91
    verbose = False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    92
    quiet = True
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    93
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    94
    def __getitem__(name):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    95
        def nullfunc(*args, **kwds):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    96
            return
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
    97
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    98
        return nullfunc
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
    99
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   100
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   101
class emptyfilecontext(object):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   102
    """minimal filecontext representing an empty file"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   103
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46113
diff changeset
   104
    def __init__(self, repo):
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46113
diff changeset
   105
        self._repo = repo
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46113
diff changeset
   106
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   107
    def data(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   108
        return b''
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   109
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   110
    def node(self):
47012
d55b71393907 node: replace nullid and friends with nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46780
diff changeset
   111
        return self._repo.nullid
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   112
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   113
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   114
def uniq(lst):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   115
    """list -> list. remove duplicated items without changing the order"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   116
    seen = set()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   117
    result = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   118
    for x in lst:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   119
        if x not in seen:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   120
            seen.add(x)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   121
            result.append(x)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   122
    return result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   123
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   124
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   125
def getdraftstack(headctx, limit=None):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   126
    """(ctx, int?) -> [ctx]. get a linear stack of non-public changesets.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   127
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   128
    changesets are sorted in topo order, oldest first.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   129
    return at most limit items, if limit is a positive number.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   130
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   131
    merges are considered as non-draft as well. i.e. every commit
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   132
    returned has and only has 1 parent.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   133
    """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   134
    ctx = headctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   135
    result = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   136
    while ctx.phase() != phases.public:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   137
        if limit and len(result) >= limit:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   138
            break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   139
        parents = ctx.parents()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   140
        if len(parents) != 1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   141
            break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   142
        result.append(ctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   143
        ctx = parents[0]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   144
    result.reverse()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   145
    return result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   146
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   147
38918
2ac40e86f604 absorb: avoid mutable default arg
Augie Fackler <augie@google.com>
parents: 38917
diff changeset
   148
def getfilestack(stack, path, seenfctxs=None):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   149
    """([ctx], str, set) -> [fctx], {ctx: fctx}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   150
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   151
    stack is a list of contexts, from old to new. usually they are what
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   152
    "getdraftstack" returns.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   153
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   154
    follows renames, but not copies.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   155
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   156
    seenfctxs is a set of filecontexts that will be considered "immutable".
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   157
    they are usually what this function returned in earlier calls, useful
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   158
    to avoid issues that a file was "moved" to multiple places and was then
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   159
    modified differently, like: "a" was copied to "b", "a" was also copied to
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   160
    "c" and then "a" was deleted, then both "b" and "c" were "moved" from "a"
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   161
    and we enforce only one of them to be able to affect "a"'s content.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   162
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   163
    return an empty list and an empty dict, if the specified path does not
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   164
    exist in stack[-1] (the top of the stack).
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   165
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   166
    otherwise, return a list of de-duplicated filecontexts, and the map to
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   167
    convert ctx in the stack to fctx, for possible mutable fctxs. the first item
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   168
    of the list would be outside the stack and should be considered immutable.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   169
    the remaining items are within the stack.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   170
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   171
    for example, given the following changelog and corresponding filelog
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   172
    revisions:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   173
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   174
      changelog: 3----4----5----6----7
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   175
      filelog:   x    0----1----1----2 (x: no such file yet)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   176
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   177
    - if stack = [5, 6, 7], returns ([0, 1, 2], {5: 1, 6: 1, 7: 2})
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   178
    - if stack = [3, 4, 5], returns ([e, 0, 1], {4: 0, 5: 1}), where "e" is a
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   179
      dummy empty filecontext.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   180
    - if stack = [2], returns ([], {})
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   181
    - if stack = [7], returns ([1, 2], {7: 2})
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   182
    - if stack = [6, 7], returns ([1, 2], {6: 1, 7: 2}), although {6: 1} can be
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   183
      removed, since 1 is immutable.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   184
    """
38918
2ac40e86f604 absorb: avoid mutable default arg
Augie Fackler <augie@google.com>
parents: 38917
diff changeset
   185
    if seenfctxs is None:
2ac40e86f604 absorb: avoid mutable default arg
Augie Fackler <augie@google.com>
parents: 38917
diff changeset
   186
        seenfctxs = set()
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   187
    assert stack
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   188
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   189
    if path not in stack[-1]:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   190
        return [], {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   191
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   192
    fctxs = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   193
    fctxmap = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   194
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   195
    pctx = stack[0].p1()  # the public (immutable) ctx we stop at
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   196
    for ctx in reversed(stack):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   197
        if path not in ctx:  # the file is added in the next commit
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   198
            pctx = ctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   199
            break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   200
        fctx = ctx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   201
        fctxs.append(fctx)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   202
        if fctx in seenfctxs:  # treat fctx as the immutable one
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   203
            pctx = None  # do not add another immutable fctx
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   204
            break
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   205
        fctxmap[ctx] = fctx  # only for mutable fctxs
41778
8843bc1fc14d absorb: migrate to new method for getting copy info
Martin von Zweigbergk <martinvonz@google.com>
parents: 41365
diff changeset
   206
        copy = fctx.copysource()
8843bc1fc14d absorb: migrate to new method for getting copy info
Martin von Zweigbergk <martinvonz@google.com>
parents: 41365
diff changeset
   207
        if copy:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   208
            path = copy  # follow rename
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   209
            if path in ctx:  # but do not follow copy
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   210
                pctx = ctx.p1()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   211
                break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   212
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   213
    if pctx is not None:  # need an extra immutable fctx
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   214
        if path in pctx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   215
            fctxs.append(pctx[path])
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   216
        else:
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46113
diff changeset
   217
            fctxs.append(emptyfilecontext(pctx.repo()))
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   218
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   219
    fctxs.reverse()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   220
    # note: we rely on a property of hg: filerev is not reused for linear
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   221
    # history. i.e. it's impossible to have:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   222
    #   changelog:  4----5----6 (linear, no merges)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   223
    #   filelog:    1----2----1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   224
    #                         ^ reuse filerev (impossible)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   225
    # because parents are part of the hash. if that's not true, we need to
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   226
    # remove uniq and find a different way to identify fctxs.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   227
    return uniq(fctxs), fctxmap
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   228
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   229
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   230
class overlaystore(patch.filestore):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   231
    """read-only, hybrid store based on a dict and ctx.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   232
    memworkingcopy: {path: content}, overrides file contents.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   233
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   234
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   235
    def __init__(self, basectx, memworkingcopy):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   236
        self.basectx = basectx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   237
        self.memworkingcopy = memworkingcopy
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   238
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   239
    def getfile(self, path):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   240
        """comply with mercurial.patch.filestore.getfile"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   241
        if path not in self.basectx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   242
            return None, None, None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   243
        fctx = self.basectx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   244
        if path in self.memworkingcopy:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   245
            content = self.memworkingcopy[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   246
        else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   247
            content = fctx.data()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   248
        mode = (fctx.islink(), fctx.isexec())
41778
8843bc1fc14d absorb: migrate to new method for getting copy info
Martin von Zweigbergk <martinvonz@google.com>
parents: 41365
diff changeset
   249
        copy = fctx.copysource()
8843bc1fc14d absorb: migrate to new method for getting copy info
Martin von Zweigbergk <martinvonz@google.com>
parents: 41365
diff changeset
   250
        return content, mode, copy
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   251
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   252
45712
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   253
def overlaycontext(memworkingcopy, ctx, parents=None, extra=None, desc=None):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   254
    """({path: content}, ctx, (p1node, p2node)?, {}?) -> memctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   255
    memworkingcopy overrides file contents.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   256
    """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   257
    # parents must contain 2 items: (node1, node2)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   258
    if parents is None:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   259
        parents = ctx.repo().changelog.parents(ctx.node())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   260
    if extra is None:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   261
        extra = ctx.extra()
45712
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   262
    if desc is None:
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   263
        desc = ctx.description()
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   264
    date = ctx.date()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   265
    user = ctx.user()
38987
9204445ad54c absorb: port partway to Python 3
Augie Fackler <augie@google.com>
parents: 38961
diff changeset
   266
    files = set(ctx.files()).union(memworkingcopy)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   267
    store = overlaystore(ctx, memworkingcopy)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   268
    return context.memctx(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   269
        repo=ctx.repo(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   270
        parents=parents,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   271
        text=desc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   272
        files=files,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   273
        filectxfn=store,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   274
        user=user,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   275
        date=date,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   276
        branch=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   277
        extra=extra,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   278
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   279
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   280
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   281
class filefixupstate(object):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   282
    """state needed to apply fixups to a single file
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   283
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   284
    internally, it keeps file contents of several revisions and a linelog.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   285
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   286
    the linelog uses odd revision numbers for original contents (fctxs passed
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   287
    to __init__), and even revision numbers for fixups, like:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   288
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   289
        linelog rev 1: self.fctxs[0] (from an immutable "public" changeset)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   290
        linelog rev 2: fixups made to self.fctxs[0]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   291
        linelog rev 3: self.fctxs[1] (a child of fctxs[0])
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   292
        linelog rev 4: fixups made to self.fctxs[1]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   293
        ...
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   294
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   295
    a typical use is like:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   296
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   297
        1. call diffwith, to calculate self.fixups
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   298
        2. (optionally), present self.fixups to the user, or change it
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   299
        3. call apply, to apply changes
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   300
        4. read results from "finalcontents", or call getfinalcontent
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   301
    """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   302
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   303
    def __init__(self, fctxs, path, ui=None, opts=None):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   304
        """([fctx], ui or None) -> None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   305
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   306
        fctxs should be linear, and sorted by topo order - oldest first.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   307
        fctxs[0] will be considered as "immutable" and will not be changed.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   308
        """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   309
        self.fctxs = fctxs
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   310
        self.path = path
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   311
        self.ui = ui or nullui()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   312
        self.opts = opts or {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   313
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   314
        # following fields are built from fctxs. they exist for perf reason
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   315
        self.contents = [f.data() for f in fctxs]
38987
9204445ad54c absorb: port partway to Python 3
Augie Fackler <augie@google.com>
parents: 38961
diff changeset
   316
        self.contentlines = pycompat.maplist(mdiff.splitnewlines, self.contents)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   317
        self.linelog = self._buildlinelog()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   318
        if self.ui.debugflag:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   319
            assert self._checkoutlinelog() == self.contents
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   320
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   321
        # following fields will be filled later
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   322
        self.chunkstats = [0, 0]  # [adopted, total : int]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   323
        self.targetlines = []  # [str]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   324
        self.fixups = []  # [(linelog rev, a1, a2, b1, b2)]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   325
        self.finalcontents = []  # [str]
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
   326
        self.ctxaffected = set()
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   327
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   328
    def diffwith(self, targetfctx, fm=None):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   329
        """calculate fixups needed by examining the differences between
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   330
        self.fctxs[-1] and targetfctx, chunk by chunk.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   331
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   332
        targetfctx is the target state we move towards. we may or may not be
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   333
        able to get there because not all modified chunks can be amended into
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   334
        a non-public fctx unambiguously.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   335
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   336
        call this only once, before apply().
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   337
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   338
        update self.fixups, self.chunkstats, and self.targetlines.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   339
        """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   340
        a = self.contents[-1]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   341
        alines = self.contentlines[-1]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   342
        b = targetfctx.data()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   343
        blines = mdiff.splitnewlines(b)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   344
        self.targetlines = blines
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   345
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   346
        self.linelog.annotate(self.linelog.maxrev)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   347
        annotated = self.linelog.annotateresult  # [(linelog rev, linenum)]
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   348
        assert len(annotated) == len(alines)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   349
        # add a dummy end line to make insertion at the end easier
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   350
        if annotated:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   351
            dummyendline = (annotated[-1][0], annotated[-1][1] + 1)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   352
            annotated.append(dummyendline)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   353
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   354
        # analyse diff blocks
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   355
        for chunk in self._alldiffchunks(a, b, alines, blines):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   356
            newfixups = self._analysediffchunk(chunk, annotated)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   357
            self.chunkstats[0] += bool(newfixups)  # 1 or 0
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   358
            self.chunkstats[1] += 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   359
            self.fixups += newfixups
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   360
            if fm is not None:
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   361
                self._showchanges(fm, alines, blines, chunk, newfixups)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   362
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   363
    def apply(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   364
        """apply self.fixups. update self.linelog, self.finalcontents.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   365
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   366
        call this only once, before getfinalcontent(), after diffwith().
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   367
        """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   368
        # the following is unnecessary, as it's done by "diffwith":
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   369
        #   self.linelog.annotate(self.linelog.maxrev)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   370
        for rev, a1, a2, b1, b2 in reversed(self.fixups):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   371
            blines = self.targetlines[b1:b2]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   372
            if self.ui.debugflag:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   373
                idx = (max(rev - 1, 0)) // 2
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   374
                self.ui.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   375
                    _(b'%s: chunk %d:%d -> %d lines\n')
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45878
diff changeset
   376
                    % (short(self.fctxs[idx].node()), a1, a2, len(blines))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   377
                )
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   378
            self.linelog.replacelines(rev, a1, a2, b1, b2)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   379
        if self.opts.get(b'edit_lines', False):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   380
            self.finalcontents = self._checkoutlinelogwithedits()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   381
        else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   382
            self.finalcontents = self._checkoutlinelog()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   383
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   384
    def getfinalcontent(self, fctx):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   385
        """(fctx) -> str. get modified file content for a given filecontext"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   386
        idx = self.fctxs.index(fctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   387
        return self.finalcontents[idx]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   388
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   389
    def _analysediffchunk(self, chunk, annotated):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   390
        """analyse a different chunk and return new fixups found
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   391
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   392
        return [] if no lines from the chunk can be safely applied.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   393
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   394
        the chunk (or lines) cannot be safely applied, if, for example:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   395
          - the modified (deleted) lines belong to a public changeset
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   396
            (self.fctxs[0])
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   397
          - the chunk is a pure insertion and the adjacent lines (at most 2
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   398
            lines) belong to different non-public changesets, or do not belong
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   399
            to any non-public changesets.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   400
          - the chunk is modifying lines from different changesets.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   401
            in this case, if the number of lines deleted equals to the number
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   402
            of lines added, assume it's a simple 1:1 map (could be wrong).
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   403
            otherwise, give up.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   404
          - the chunk is modifying lines from a single non-public changeset,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   405
            but other revisions touch the area as well. i.e. the lines are
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   406
            not continuous as seen from the linelog.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   407
        """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   408
        a1, a2, b1, b2 = chunk
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   409
        # find involved indexes from annotate result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   410
        involved = annotated[a1:a2]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   411
        if not involved and annotated:  # a1 == a2 and a is not empty
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   412
            # pure insertion, check nearby lines. ignore lines belong
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   413
            # to the public (first) changeset (i.e. annotated[i][0] == 1)
38919
dc4750b2a04e absorb: use set literal to avoid intermediate list
Augie Fackler <augie@google.com>
parents: 38918
diff changeset
   414
            nearbylinenums = {a2, max(0, a1 - 1)}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   415
            involved = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   416
                annotated[i] for i in nearbylinenums if annotated[i][0] != 1
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   417
            ]
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 44236
diff changeset
   418
        involvedrevs = list({r for r, l in involved})
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   419
        newfixups = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   420
        if len(involvedrevs) == 1 and self._iscontinuous(a1, a2 - 1, True):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   421
            # chunk belongs to a single revision
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   422
            rev = involvedrevs[0]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   423
            if rev > 1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   424
                fixuprev = rev + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   425
                newfixups.append((fixuprev, a1, a2, b1, b2))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   426
        elif a2 - a1 == b2 - b1 or b1 == b2:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   427
            # 1:1 line mapping, or chunk was deleted
38920
a5c8c5476339 absorb: use pycompat to get xrange
Augie Fackler <augie@google.com>
parents: 38919
diff changeset
   428
            for i in pycompat.xrange(a1, a2):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   429
                rev, linenum = annotated[i]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   430
                if rev > 1:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   431
                    if b1 == b2:  # deletion, simply remove that single line
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   432
                        nb1 = nb2 = 0
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   433
                    else:  # 1:1 line mapping, change the corresponding rev
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   434
                        nb1 = b1 + i - a1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   435
                        nb2 = nb1 + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   436
                    fixuprev = rev + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   437
                    newfixups.append((fixuprev, i, i + 1, nb1, nb2))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   438
        return self._optimizefixups(newfixups)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   439
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   440
    @staticmethod
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   441
    def _alldiffchunks(a, b, alines, blines):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   442
        """like mdiff.allblocks, but only care about differences"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   443
        blocks = mdiff.allblocks(a, b, lines1=alines, lines2=blines)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   444
        for chunk, btype in blocks:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   445
            if btype != b'!':
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   446
                continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   447
            yield chunk
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   448
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   449
    def _buildlinelog(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   450
        """calculate the initial linelog based on self.content{,line}s.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   451
        this is similar to running a partial "annotate".
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   452
        """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   453
        llog = linelog.linelog()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   454
        a, alines = b'', []
38920
a5c8c5476339 absorb: use pycompat to get xrange
Augie Fackler <augie@google.com>
parents: 38919
diff changeset
   455
        for i in pycompat.xrange(len(self.contents)):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   456
            b, blines = self.contents[i], self.contentlines[i]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   457
            llrev = i * 2 + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   458
            chunks = self._alldiffchunks(a, b, alines, blines)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   459
            for a1, a2, b1, b2 in reversed(list(chunks)):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   460
                llog.replacelines(llrev, a1, a2, b1, b2)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   461
            a, alines = b, blines
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   462
        return llog
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   463
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   464
    def _checkoutlinelog(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   465
        """() -> [str]. check out file contents from linelog"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   466
        contents = []
38920
a5c8c5476339 absorb: use pycompat to get xrange
Augie Fackler <augie@google.com>
parents: 38919
diff changeset
   467
        for i in pycompat.xrange(len(self.contents)):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   468
            rev = (i + 1) * 2
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   469
            self.linelog.annotate(rev)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   470
            content = b''.join(map(self._getline, self.linelog.annotateresult))
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   471
            contents.append(content)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   472
        return contents
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   473
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   474
    def _checkoutlinelogwithedits(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   475
        """() -> [str]. prompt all lines for edit"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   476
        alllines = self.linelog.getalllines()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   477
        # header
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   478
        editortext = (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   479
            _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   480
                b'HG: editing %s\nHG: "y" means the line to the right '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   481
                b'exists in the changeset to the top\nHG:\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   482
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   483
            % self.fctxs[-1].path()
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   484
        )
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   485
        # [(idx, fctx)]. hide the dummy emptyfilecontext
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   486
        visiblefctxs = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   487
            (i, f)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   488
            for i, f in enumerate(self.fctxs)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   489
            if not isinstance(f, emptyfilecontext)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   490
        ]
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   491
        for i, (j, f) in enumerate(visiblefctxs):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   492
            editortext += _(b'HG: %s/%s %s %s\n') % (
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   493
                b'|' * i,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   494
                b'-' * (len(visiblefctxs) - i + 1),
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45878
diff changeset
   495
                short(f.node()),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   496
                f.description().split(b'\n', 1)[0],
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   497
            )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   498
        editortext += _(b'HG: %s\n') % (b'|' * len(visiblefctxs))
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   499
        # figure out the lifetime of a line, this is relatively inefficient,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   500
        # but probably fine
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   501
        lineset = defaultdict(lambda: set())  # {(llrev, linenum): {llrev}}
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   502
        for i, f in visiblefctxs:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   503
            self.linelog.annotate((i + 1) * 2)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   504
            for l in self.linelog.annotateresult:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   505
                lineset[l].add(i)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   506
        # append lines
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   507
        for l in alllines:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   508
            editortext += b'    %s : %s' % (
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   509
                b''.join(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   510
                    [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   511
                        (b'y' if i in lineset[l] else b' ')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   512
                        for i, _f in visiblefctxs
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   513
                    ]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   514
                ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   515
                self._getline(l),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   516
            )
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   517
        # run editor
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   518
        editedtext = self.ui.edit(editortext, b'', action=b'absorb')
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   519
        if not editedtext:
45878
f4a218331ff4 errors: raise InputError in `hg absorb`
Martin von Zweigbergk <martinvonz@google.com>
parents: 45877
diff changeset
   520
            raise error.InputError(_(b'empty editor text'))
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   521
        # parse edited result
43983
236cec445be2 absorb: avoid using a list comprehension to fill a list with fixed values
Matt Harbison <matt_harbison@yahoo.com>
parents: 43115
diff changeset
   522
        contents = [b''] * len(self.fctxs)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   523
        leftpadpos = 4
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   524
        colonpos = leftpadpos + len(visiblefctxs) + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   525
        for l in mdiff.splitnewlines(editedtext):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   526
            if l.startswith(b'HG:'):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   527
                continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   528
            if l[colonpos - 1 : colonpos + 2] != b' : ':
45878
f4a218331ff4 errors: raise InputError in `hg absorb`
Martin von Zweigbergk <martinvonz@google.com>
parents: 45877
diff changeset
   529
                raise error.InputError(_(b'malformed line: %s') % l)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   530
            linecontent = l[colonpos + 2 :]
41260
c146651a78e1 absorb: add a pycompat.bytestr() to fix --edit-lines functionality on Python 3
Augie Fackler <augie@google.com>
parents: 40951
diff changeset
   531
            for i, ch in enumerate(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   532
                pycompat.bytestr(l[leftpadpos : colonpos - 1])
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   533
            ):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   534
                if ch == b'y':
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   535
                    contents[visiblefctxs[i][0]] += linecontent
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   536
        # chunkstats is hard to calculate if anything changes, therefore
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   537
        # set them to just a simple value (1, 1).
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   538
        if editedtext != editortext:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   539
            self.chunkstats = [1, 1]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   540
        return contents
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   541
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   542
    def _getline(self, lineinfo):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   543
        """((rev, linenum)) -> str. convert rev+line number to line content"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   544
        rev, linenum = lineinfo
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   545
        if rev & 1:  # odd: original line taken from fctxs
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   546
            return self.contentlines[rev // 2][linenum]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   547
        else:  # even: fixup line from targetfctx
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   548
            return self.targetlines[linenum]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   549
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   550
    def _iscontinuous(self, a1, a2, closedinterval=False):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   551
        """(a1, a2 : int) -> bool
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   552
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   553
        check if these lines are continuous. i.e. no other insertions or
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   554
        deletions (from other revisions) among these lines.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   555
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   556
        closedinterval decides whether a2 should be included or not. i.e. is
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   557
        it [a1, a2), or [a1, a2] ?
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   558
        """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   559
        if a1 >= a2:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   560
            return True
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   561
        llog = self.linelog
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   562
        offset1 = llog.getoffset(a1)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   563
        offset2 = llog.getoffset(a2) + int(closedinterval)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   564
        linesinbetween = llog.getalllines(offset1, offset2)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   565
        return len(linesinbetween) == a2 - a1 + int(closedinterval)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   566
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   567
    def _optimizefixups(self, fixups):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   568
        """[(rev, a1, a2, b1, b2)] -> [(rev, a1, a2, b1, b2)].
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   569
        merge adjacent fixups to make them less fragmented.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   570
        """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   571
        result = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   572
        pcurrentchunk = [[-1, -1, -1, -1, -1]]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   573
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   574
        def pushchunk():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   575
            if pcurrentchunk[0][0] != -1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   576
                result.append(tuple(pcurrentchunk[0]))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   577
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   578
        for i, chunk in enumerate(fixups):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   579
            rev, a1, a2, b1, b2 = chunk
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   580
            lastrev = pcurrentchunk[0][0]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   581
            lasta2 = pcurrentchunk[0][2]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   582
            lastb2 = pcurrentchunk[0][4]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   583
            if (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   584
                a1 == lasta2
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   585
                and b1 == lastb2
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   586
                and rev == lastrev
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   587
                and self._iscontinuous(max(a1 - 1, 0), a1)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   588
            ):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   589
                # merge into currentchunk
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   590
                pcurrentchunk[0][2] = a2
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   591
                pcurrentchunk[0][4] = b2
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   592
            else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   593
                pushchunk()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   594
                pcurrentchunk[0] = list(chunk)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   595
        pushchunk()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   596
        return result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   597
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   598
    def _showchanges(self, fm, alines, blines, chunk, fixups):
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   599
        def trim(line):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   600
            if line.endswith(b'\n'):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   601
                line = line[:-1]
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   602
            return line
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   603
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   604
        # this is not optimized for perf but _showchanges only gets executed
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   605
        # with an extra command-line flag.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   606
        a1, a2, b1, b2 = chunk
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   607
        aidxs, bidxs = [0] * (a2 - a1), [0] * (b2 - b1)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   608
        for idx, fa1, fa2, fb1, fb2 in fixups:
38920
a5c8c5476339 absorb: use pycompat to get xrange
Augie Fackler <augie@google.com>
parents: 38919
diff changeset
   609
            for i in pycompat.xrange(fa1, fa2):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   610
                aidxs[i - a1] = (max(idx, 1) - 1) // 2
38920
a5c8c5476339 absorb: use pycompat to get xrange
Augie Fackler <augie@google.com>
parents: 38919
diff changeset
   611
            for i in pycompat.xrange(fb1, fb2):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   612
                bidxs[i - b1] = (max(idx, 1) - 1) // 2
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   613
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   614
        fm.startitem()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   615
        fm.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   616
            b'hunk',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   617
            b'        %s\n',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   618
            b'@@ -%d,%d +%d,%d @@' % (a1, a2 - a1, b1, b2 - b1),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   619
            label=b'diff.hunk',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   620
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   621
        fm.data(path=self.path, linetype=b'hunk')
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   622
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   623
        def writeline(idx, diffchar, line, linetype, linelabel):
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   624
            fm.startitem()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   625
            node = b''
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   626
            if idx:
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   627
                ctx = self.fctxs[idx]
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   628
                fm.context(fctx=ctx)
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   629
                node = ctx.hex()
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
   630
                self.ctxaffected.add(ctx.changectx())
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   631
            fm.write(b'node', b'%-7.7s ', node, label=b'absorb.node')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   632
            fm.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   633
                b'diffchar ' + linetype,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   634
                b'%s%s\n',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   635
                diffchar,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   636
                line,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   637
                label=linelabel,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   638
            )
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   639
            fm.data(path=self.path, linetype=linetype)
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   640
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   641
        for i in pycompat.xrange(a1, a2):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   642
            writeline(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   643
                aidxs[i - a1],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   644
                b'-',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   645
                trim(alines[i]),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   646
                b'deleted',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   647
                b'diff.deleted',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   648
            )
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   649
        for i in pycompat.xrange(b1, b2):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   650
            writeline(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   651
                bidxs[i - b1],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   652
                b'+',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   653
                trim(blines[i]),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   654
                b'inserted',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   655
                b'diff.inserted',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   656
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   657
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   658
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   659
class fixupstate(object):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   660
    """state needed to run absorb
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   661
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   662
    internally, it keeps paths and filefixupstates.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   663
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   664
    a typical use is like filefixupstates:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   665
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   666
        1. call diffwith, to calculate fixups
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   667
        2. (optionally), present fixups to the user, or edit fixups
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   668
        3. call apply, to apply changes to memory
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   669
        4. call commit, to commit changes to hg database
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   670
    """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   671
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   672
    def __init__(self, stack, ui=None, opts=None):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   673
        """([ctx], ui or None) -> None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   674
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   675
        stack: should be linear, and sorted by topo order - oldest first.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   676
        all commits in stack are considered mutable.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   677
        """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   678
        assert stack
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   679
        self.ui = ui or nullui()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   680
        self.opts = opts or {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   681
        self.stack = stack
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   682
        self.repo = stack[-1].repo().unfiltered()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   683
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   684
        # following fields will be filled later
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   685
        self.paths = []  # [str]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   686
        self.status = None  # ctx.status output
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   687
        self.fctxmap = {}  # {path: {ctx: fctx}}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   688
        self.fixupmap = {}  # {path: filefixupstate}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   689
        self.replacemap = {}  # {oldnode: newnode or None}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   690
        self.finalnode = None  # head after all fixups
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   691
        self.ctxaffected = set()  # ctx that will be absorbed into
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   692
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   693
    def diffwith(self, targetctx, match=None, fm=None):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   694
        """diff and prepare fixups. update self.fixupmap, self.paths"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   695
        # only care about modified files
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   696
        self.status = self.stack[-1].status(targetctx, match)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   697
        self.paths = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   698
        # but if --edit-lines is used, the user may want to edit files
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   699
        # even if they are not modified
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   700
        editopt = self.opts.get(b'edit_lines')
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   701
        if not self.status.modified and editopt and match:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   702
            interestingpaths = match.files()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   703
        else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   704
            interestingpaths = self.status.modified
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   705
        # prepare the filefixupstate
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   706
        seenfctxs = set()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   707
        # sorting is necessary to eliminate ambiguity for the "double move"
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   708
        # case: "hg cp A B; hg cp A C; hg rm A", then only "B" can affect "A".
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   709
        for path in sorted(interestingpaths):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   710
            self.ui.debug(b'calculating fixups for %s\n' % path)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   711
            targetfctx = targetctx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   712
            fctxs, ctx2fctx = getfilestack(self.stack, path, seenfctxs)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   713
            # ignore symbolic links or binary, or unchanged files
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   714
            if any(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   715
                f.islink() or stringutil.binary(f.data())
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   716
                for f in [targetfctx] + fctxs
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   717
                if not isinstance(f, emptyfilecontext)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   718
            ):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   719
                continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   720
            if targetfctx.data() == fctxs[-1].data() and not editopt:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   721
                continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   722
            seenfctxs.update(fctxs[1:])
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   723
            self.fctxmap[path] = ctx2fctx
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   724
            fstate = filefixupstate(fctxs, path, ui=self.ui, opts=self.opts)
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   725
            if fm is not None:
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   726
                fm.startitem()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   727
                fm.plain(b'showing changes for ')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   728
                fm.write(b'path', b'%s\n', path, label=b'absorb.path')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   729
                fm.data(linetype=b'path')
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
   730
            fstate.diffwith(targetfctx, fm)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   731
            self.fixupmap[path] = fstate
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   732
            self.paths.append(path)
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
   733
            self.ctxaffected.update(fstate.ctxaffected)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   734
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   735
    def apply(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   736
        """apply fixups to individual filefixupstates"""
43105
649d3ac37a12 py3: define and use pycompat.iteritems() for hgext/
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
   737
        for path, state in pycompat.iteritems(self.fixupmap):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   738
            if self.ui.debugflag:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   739
                self.ui.write(_(b'applying fixups to %s\n') % path)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   740
            state.apply()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   741
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   742
    @property
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   743
    def chunkstats(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   744
        """-> {path: chunkstats}. collect chunkstats from filefixupstates"""
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 44236
diff changeset
   745
        return {
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 44236
diff changeset
   746
            path: state.chunkstats
43105
649d3ac37a12 py3: define and use pycompat.iteritems() for hgext/
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
   747
            for path, state in pycompat.iteritems(self.fixupmap)
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 44236
diff changeset
   748
        }
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   749
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   750
    def commit(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   751
        """commit changes. update self.finalnode, self.replacemap"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   752
        with self.repo.transaction(b'absorb') as tr:
42128
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
   753
            self._commitstack()
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
   754
            self._movebookmarks(tr)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   755
            if self.repo[b'.'].node() in self.replacemap:
42128
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
   756
                self._moveworkingdirectoryparent()
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
   757
            self._cleanupoldcommits()
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   758
        return self.finalnode
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   759
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   760
    def printchunkstats(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   761
        """print things like '1 of 2 chunk(s) applied'"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   762
        ui = self.ui
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   763
        chunkstats = self.chunkstats
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   764
        if ui.verbose:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   765
            # chunkstats for each file
43105
649d3ac37a12 py3: define and use pycompat.iteritems() for hgext/
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
   766
            for path, stat in pycompat.iteritems(chunkstats):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   767
                if stat[0]:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   768
                    ui.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   769
                        _(b'%s: %d of %d chunk(s) applied\n')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   770
                        % (path, stat[0], stat[1])
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   771
                    )
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   772
        elif not ui.quiet:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   773
            # a summary for all files
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   774
            stats = chunkstats.values()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   775
            applied, total = (sum(s[i] for s in stats) for i in (0, 1))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   776
            ui.write(_(b'%d of %d chunk(s) applied\n') % (applied, total))
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   777
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   778
    def _commitstack(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   779
        """make new commits. update self.finalnode, self.replacemap.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   780
        it is splitted from "commit" to avoid too much indentation.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   781
        """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   782
        # last node (20-char) committed by us
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   783
        lastcommitted = None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   784
        # p1 which overrides the parent of the next commit, "None" means use
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   785
        # the original parent unchanged
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   786
        nextp1 = None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   787
        for ctx in self.stack:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   788
            memworkingcopy = self._getnewfilecontents(ctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   789
            if not memworkingcopy and not lastcommitted:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   790
                # nothing changed, nothing commited
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   791
                nextp1 = ctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   792
                continue
45125
f55099982bc5 absorb: make it explicit if empty changeset was created
Manuel Jacob <me@manueljacob.de>
parents: 45124
diff changeset
   793
            willbecomenoop = ctx.files() and self._willbecomenoop(
f55099982bc5 absorb: make it explicit if empty changeset was created
Manuel Jacob <me@manueljacob.de>
parents: 45124
diff changeset
   794
                memworkingcopy, ctx, nextp1
f55099982bc5 absorb: make it explicit if empty changeset was created
Manuel Jacob <me@manueljacob.de>
parents: 45124
diff changeset
   795
            )
f55099982bc5 absorb: make it explicit if empty changeset was created
Manuel Jacob <me@manueljacob.de>
parents: 45124
diff changeset
   796
            if self.skip_empty_successor and willbecomenoop:
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   797
                # changeset is no longer necessary
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   798
                self.replacemap[ctx.node()] = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   799
                msg = _(b'became empty and was dropped')
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   800
            else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   801
                # changeset needs re-commit
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   802
                nodestr = self._commitsingle(memworkingcopy, ctx, p1=nextp1)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   803
                lastcommitted = self.repo[nodestr]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   804
                nextp1 = lastcommitted
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   805
                self.replacemap[ctx.node()] = lastcommitted.node()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   806
                if memworkingcopy:
45125
f55099982bc5 absorb: make it explicit if empty changeset was created
Manuel Jacob <me@manueljacob.de>
parents: 45124
diff changeset
   807
                    if willbecomenoop:
45170
c87bd1fe3da2 absorb: improve message for the case when changeset became empty
Manuel Jacob <me@manueljacob.de>
parents: 45125
diff changeset
   808
                        msg = _(b'%d file(s) changed, became empty as %s')
45125
f55099982bc5 absorb: make it explicit if empty changeset was created
Manuel Jacob <me@manueljacob.de>
parents: 45124
diff changeset
   809
                    else:
f55099982bc5 absorb: make it explicit if empty changeset was created
Manuel Jacob <me@manueljacob.de>
parents: 45124
diff changeset
   810
                        msg = _(b'%d file(s) changed, became %s')
f55099982bc5 absorb: make it explicit if empty changeset was created
Manuel Jacob <me@manueljacob.de>
parents: 45124
diff changeset
   811
                    msg = msg % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   812
                        len(memworkingcopy),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   813
                        self._ctx2str(lastcommitted),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   814
                    )
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   815
                else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   816
                    msg = _(b'became %s') % self._ctx2str(lastcommitted)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   817
            if self.ui.verbose and msg:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   818
                self.ui.write(_(b'%s: %s\n') % (self._ctx2str(ctx), msg))
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   819
        self.finalnode = lastcommitted and lastcommitted.node()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   820
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   821
    def _ctx2str(self, ctx):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   822
        if self.ui.debugflag:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   823
            return b'%d:%s' % (ctx.rev(), ctx.hex())
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   824
        else:
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45878
diff changeset
   825
            return b'%d:%s' % (ctx.rev(), short(ctx.node()))
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   826
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   827
    def _getnewfilecontents(self, ctx):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   828
        """(ctx) -> {path: str}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   829
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   830
        fetch file contents from filefixupstates.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   831
        return the working copy overrides - files different from ctx.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   832
        """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   833
        result = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   834
        for path in self.paths:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   835
            ctx2fctx = self.fctxmap[path]  # {ctx: fctx}
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   836
            if ctx not in ctx2fctx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   837
                continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   838
            fctx = ctx2fctx[ctx]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   839
            content = fctx.data()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   840
            newcontent = self.fixupmap[path].getfinalcontent(fctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   841
            if content != newcontent:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   842
                result[fctx.path()] = newcontent
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   843
        return result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   844
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   845
    def _movebookmarks(self, tr):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   846
        repo = self.repo
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   847
        needupdate = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   848
            (name, self.replacemap[hsh])
43105
649d3ac37a12 py3: define and use pycompat.iteritems() for hgext/
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
   849
            for name, hsh in pycompat.iteritems(repo._bookmarks)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   850
            if hsh in self.replacemap
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   851
        ]
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   852
        changes = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   853
        for name, hsh in needupdate:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   854
            if hsh:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   855
                changes.append((name, hsh))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   856
                if self.ui.verbose:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   857
                    self.ui.write(
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45878
diff changeset
   858
                        _(b'moving bookmark %s to %s\n') % (name, hex(hsh))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   859
                    )
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   860
            else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   861
                changes.append((name, None))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   862
                if self.ui.verbose:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   863
                    self.ui.write(_(b'deleting bookmark %s\n') % name)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   864
        repo._bookmarks.applychanges(repo, tr, changes)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   865
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   866
    def _moveworkingdirectoryparent(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   867
        if not self.finalnode:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   868
            # Find the latest not-{obsoleted,stripped} parent.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   869
            revs = self.repo.revs(b'max(::. - %ln)', self.replacemap.keys())
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   870
            ctx = self.repo[revs.first()]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   871
            self.finalnode = ctx.node()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   872
        else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   873
            ctx = self.repo[self.finalnode]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   874
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   875
        dirstate = self.repo.dirstate
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   876
        # dirstate.rebuild invalidates fsmonitorstate, causing "hg status" to
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   877
        # be slow. in absorb's case, no need to invalidate fsmonitorstate.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   878
        noop = lambda: 0
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   879
        restore = noop
43115
4aa72cdf616f py3: delete b'' prefix from safehasattr arguments
Martin von Zweigbergk <martinvonz@google.com>
parents: 43105
diff changeset
   880
        if util.safehasattr(dirstate, '_fsmonitorstate'):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   881
            bak = dirstate._fsmonitorstate.invalidate
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   882
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   883
            def restore():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   884
                dirstate._fsmonitorstate.invalidate = bak
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   885
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   886
            dirstate._fsmonitorstate.invalidate = noop
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   887
        try:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   888
            with dirstate.parentchange():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   889
                dirstate.rebuild(ctx.node(), ctx.manifest(), self.paths)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   890
        finally:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   891
            restore()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   892
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   893
    @staticmethod
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   894
    def _willbecomenoop(memworkingcopy, ctx, pctx=None):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   895
        """({path: content}, ctx, ctx) -> bool. test if a commit will be noop
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   896
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   897
        if it will become an empty commit (does not change anything, after the
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   898
        memworkingcopy overrides), return True. otherwise return False.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   899
        """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   900
        if not pctx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   901
            parents = ctx.parents()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   902
            if len(parents) != 1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   903
                return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   904
            pctx = parents[0]
44983
1b757f385549 absorb: preserve branch-changing changesets even if empty
Manuel Jacob <me@manueljacob.de>
parents: 44452
diff changeset
   905
        if ctx.branch() != pctx.branch():
1b757f385549 absorb: preserve branch-changing changesets even if empty
Manuel Jacob <me@manueljacob.de>
parents: 44452
diff changeset
   906
            return False
44984
bfef35bb4ecb absorb: preserve branch-closing changesets even if empty
Manuel Jacob <me@manueljacob.de>
parents: 44983
diff changeset
   907
        if ctx.extra().get(b'close'):
bfef35bb4ecb absorb: preserve branch-closing changesets even if empty
Manuel Jacob <me@manueljacob.de>
parents: 44983
diff changeset
   908
            return False
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   909
        # ctx changes more files (not a subset of memworkingcopy)
38987
9204445ad54c absorb: port partway to Python 3
Augie Fackler <augie@google.com>
parents: 38961
diff changeset
   910
        if not set(ctx.files()).issubset(set(memworkingcopy)):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   911
            return False
43105
649d3ac37a12 py3: define and use pycompat.iteritems() for hgext/
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
   912
        for path, content in pycompat.iteritems(memworkingcopy):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   913
            if path not in pctx or path not in ctx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   914
                return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   915
            fctx = ctx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   916
            pfctx = pctx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   917
            if pfctx.flags() != fctx.flags():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   918
                return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   919
            if pfctx.data() != content:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   920
                return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   921
        return True
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   922
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   923
    def _commitsingle(self, memworkingcopy, ctx, p1=None):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   924
        """(ctx, {path: content}, node) -> node. make a single commit
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   925
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   926
        the commit is a clone from ctx, with a (optionally) different p1, and
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   927
        different file contents replaced by memworkingcopy.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   928
        """
47012
d55b71393907 node: replace nullid and friends with nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46780
diff changeset
   929
        parents = p1 and (p1, self.repo.nullid)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   930
        extra = ctx.extra()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   931
        if self._useobsolete and self.ui.configbool(b'absorb', b'add-noise'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   932
            extra[b'absorb_source'] = ctx.hex()
45712
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   933
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   934
        desc = rewriteutil.update_hash_refs(
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   935
            ctx.repo(),
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   936
            ctx.description(),
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   937
            {
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   938
                oldnode: [newnode]
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   939
                for oldnode, newnode in self.replacemap.items()
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   940
            },
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   941
        )
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   942
        mctx = overlaycontext(
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   943
            memworkingcopy, ctx, parents, extra=extra, desc=desc
0a330055340c absorb: update commit hash references in the new commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 45170
diff changeset
   944
        )
41813
b38c7304974f absorb: let scmutil.cleanupnodes() take care of setting phase
Martin von Zweigbergk <martinvonz@google.com>
parents: 41812
diff changeset
   945
        return mctx.commit()
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   946
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   947
    @util.propertycache
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   948
    def _useobsolete(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   949
        """() -> bool"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   950
        return obsolete.isenabled(self.repo, obsolete.createmarkersopt)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   951
41812
c91321e86071 absorb: use scmutil.cleanupnodes() also when obsmarkers are disabled
Martin von Zweigbergk <martinvonz@google.com>
parents: 41811
diff changeset
   952
    def _cleanupoldcommits(self):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   953
        replacements = {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   954
            k: ([v] if v is not None else [])
43105
649d3ac37a12 py3: define and use pycompat.iteritems() for hgext/
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
   955
            for k, v in pycompat.iteritems(self.replacemap)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   956
        }
41811
a008e0af892e absorb: use scmutil.cleanupnodes() so operation gets set
Martin von Zweigbergk <martinvonz@google.com>
parents: 41778
diff changeset
   957
        if replacements:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   958
            scmutil.cleanupnodes(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   959
                self.repo, replacements, operation=b'absorb', fixphase=True
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   960
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   961
45124
3ee8e2d5c0d8 absorb: consider rewrite.empty-successor configuration
Manuel Jacob <me@manueljacob.de>
parents: 44991
diff changeset
   962
    @util.propertycache
3ee8e2d5c0d8 absorb: consider rewrite.empty-successor configuration
Manuel Jacob <me@manueljacob.de>
parents: 44991
diff changeset
   963
    def skip_empty_successor(self):
3ee8e2d5c0d8 absorb: consider rewrite.empty-successor configuration
Manuel Jacob <me@manueljacob.de>
parents: 44991
diff changeset
   964
        return rewriteutil.skip_empty_successor(self.ui, b'absorb')
3ee8e2d5c0d8 absorb: consider rewrite.empty-successor configuration
Manuel Jacob <me@manueljacob.de>
parents: 44991
diff changeset
   965
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   966
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   967
def _parsechunk(hunk):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   968
    """(crecord.uihunk or patch.recordhunk) -> (path, (a1, a2, [bline]))"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   969
    if type(hunk) not in (crecord.uihunk, patch.recordhunk):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   970
        return None, None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   971
    path = hunk.header.filename()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   972
    a1 = hunk.fromline + len(hunk.before) - 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   973
    # remove before and after context
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   974
    hunk.before = hunk.after = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   975
    buf = util.stringio()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   976
    hunk.write(buf)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   977
    patchlines = mdiff.splitnewlines(buf.getvalue())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   978
    # hunk.prettystr() will update hunk.removed
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   979
    a2 = a1 + hunk.removed
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   980
    blines = [l[1:] for l in patchlines[1:] if not l.startswith(b'-')]
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   981
    return path, (a1, a2, blines)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   982
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   983
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   984
def overlaydiffcontext(ctx, chunks):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   985
    """(ctx, [crecord.uihunk]) -> memctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   986
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   987
    return a memctx with some [1] patches (chunks) applied to ctx.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   988
    [1]: modifications are handled. renames, mode changes, etc. are ignored.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   989
    """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   990
    # sadly the applying-patch logic is hardly reusable, and messy:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   991
    # 1. the core logic "_applydiff" is too heavy - it writes .rej files, it
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   992
    #    needs a file stream of a patch and will re-parse it, while we have
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   993
    #    structured hunk objects at hand.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   994
    # 2. a lot of different implementations about "chunk" (patch.hunk,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   995
    #    patch.recordhunk, crecord.uihunk)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   996
    # as we only care about applying changes to modified files, no mode
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   997
    # change, no binary diff, and no renames, it's probably okay to
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
   998
    # re-invent the logic using much simpler code here.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
   999
    memworkingcopy = {}  # {path: content}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1000
    patchmap = defaultdict(lambda: [])  # {path: [(a1, a2, [bline])]}
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1001
    for path, info in map(_parsechunk, chunks):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1002
        if not path or not info:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1003
            continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1004
        patchmap[path].append(info)
43105
649d3ac37a12 py3: define and use pycompat.iteritems() for hgext/
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
  1005
    for path, patches in pycompat.iteritems(patchmap):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1006
        if path not in ctx or not patches:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1007
            continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1008
        patches.sort(reverse=True)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1009
        lines = mdiff.splitnewlines(ctx[path].data())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1010
        for a1, a2, blines in patches:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1011
            lines[a1:a2] = blines
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1012
        memworkingcopy[path] = b''.join(lines)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1013
    return overlaycontext(memworkingcopy, ctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1014
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1015
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1016
def absorb(ui, repo, stack=None, targetctx=None, pats=None, opts=None):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1017
    """pick fixup chunks from targetctx, apply them to stack.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1018
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1019
    if targetctx is None, the working copy context will be used.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1020
    if stack is None, the current draft stack will be used.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1021
    return fixupstate.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1022
    """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1023
    if stack is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1024
        limit = ui.configint(b'absorb', b'max-stack-size')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1025
        headctx = repo[b'.']
42266
b3fc78c028ef absorb: be more specific when erroring out on merge commit
Martin von Zweigbergk <martinvonz@google.com>
parents: 42128
diff changeset
  1026
        if len(headctx.parents()) > 1:
45878
f4a218331ff4 errors: raise InputError in `hg absorb`
Martin von Zweigbergk <martinvonz@google.com>
parents: 45877
diff changeset
  1027
            raise error.InputError(_(b'cannot absorb into a merge'))
42266
b3fc78c028ef absorb: be more specific when erroring out on merge commit
Martin von Zweigbergk <martinvonz@google.com>
parents: 42128
diff changeset
  1028
        stack = getdraftstack(headctx, limit)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1029
        if limit and len(stack) >= limit:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1030
            ui.warn(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1031
                _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1032
                    b'absorb: only the recent %d changesets will '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1033
                    b'be analysed\n'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1034
                )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1035
                % limit
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1036
            )
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1037
    if not stack:
45878
f4a218331ff4 errors: raise InputError in `hg absorb`
Martin von Zweigbergk <martinvonz@google.com>
parents: 45877
diff changeset
  1038
        raise error.InputError(_(b'no mutable changeset to change'))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1039
    if targetctx is None:  # default to working copy
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1040
        targetctx = repo[None]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1041
    if pats is None:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1042
        pats = ()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1043
    if opts is None:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1044
        opts = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1045
    state = fixupstate(stack, ui=ui, opts=opts)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1046
    matcher = scmutil.match(targetctx, pats, opts)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1047
    if opts.get(b'interactive'):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1048
        diff = patch.diff(repo, stack[-1].node(), targetctx.node(), matcher)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1049
        origchunks = patch.parsepatch(diff)
42351
86f17fc31aa8 absorb: fix interactive mode I didn't know existed
Augie Fackler <augie@google.com>
parents: 42266
diff changeset
  1050
        chunks = cmdutil.recordfilter(ui, origchunks, matcher)[0]
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1051
        targetctx = overlaydiffcontext(stack[-1], chunks)
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
  1052
    fm = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1053
    if opts.get(b'print_changes') or not opts.get(b'apply_changes'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1054
        fm = ui.formatter(b'absorb', opts)
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
  1055
    state.diffwith(targetctx, matcher, fm)
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
  1056
    if fm is not None:
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
  1057
        fm.startitem()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1058
        fm.write(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1059
            b"count", b"\n%d changesets affected\n", len(state.ctxaffected)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1060
        )
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1061
        fm.data(linetype=b'summary')
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
  1062
        for ctx in reversed(stack):
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
  1063
            if ctx not in state.ctxaffected:
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
  1064
                continue
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
  1065
            fm.startitem()
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
  1066
            fm.context(ctx=ctx)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1067
            fm.data(linetype=b'changeset')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1068
            fm.write(b'node', b'%-7.7s ', ctx.hex(), label=b'absorb.node')
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
  1069
            descfirstline = ctx.description().splitlines()[0]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1070
            fm.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1071
                b'descfirstline',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1072
                b'%s\n',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1073
                descfirstline,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1074
                label=b'absorb.description',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1075
            )
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
  1076
        fm.end()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1077
    if not opts.get(b'dry_run'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1078
        if (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1079
            not opts.get(b'apply_changes')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1080
            and state.ctxaffected
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1081
            and ui.promptchoice(
44991
65d19d9c8e76 absorb: make it clear what happens when no input
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 44985
diff changeset
  1082
                b"apply changes (y/N)? $$ &Yes $$ &No", default=1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1083
            )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1084
        ):
45877
ac362d5a7893 errors: introduce CanceledError and use it in a few places
Martin von Zweigbergk <martinvonz@google.com>
parents: 45712
diff changeset
  1085
            raise error.CanceledError(_(b'absorb cancelled\n'))
40190
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
  1086
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1087
        state.apply()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1088
        if state.commit():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1089
            state.printchunkstats()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1090
        elif not ui.quiet:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1091
            ui.write(_(b'nothing applied\n'))
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1092
    return state
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1093
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1094
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1095
@command(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1096
    b'absorb',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1097
    [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1098
        (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1099
            b'a',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1100
            b'apply-changes',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1101
            None,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1102
            _(b'apply changes without prompting for confirmation'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1103
        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1104
        (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1105
            b'p',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1106
            b'print-changes',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1107
            None,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1108
            _(b'always print which changesets are modified by which changes'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1109
        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1110
        (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1111
            b'i',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1112
            b'interactive',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1113
            None,
44236
e1ecfc7c84be absorb: graduate -i flag from experimental
Martin von Zweigbergk <martinvonz@google.com>
parents: 43983
diff changeset
  1114
            _(b'interactively select which chunks to apply'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1115
        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1116
        (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1117
            b'e',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1118
            b'edit-lines',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1119
            None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1120
            _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1121
                b'edit what lines belong to which changesets before commit '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1122
                b'(EXPERIMENTAL)'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1123
            ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1124
        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1125
    ]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1126
    + commands.dryrunopts
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1127
    + commands.templateopts
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1128
    + commands.walkopts,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1129
    _(b'hg absorb [OPTION] [FILE]...'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1130
    helpcategory=command.CATEGORY_COMMITTING,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1131
    helpbasic=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42442
diff changeset
  1132
)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1133
def absorbcmd(ui, repo, *pats, **opts):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1134
    """incorporate corrections into the stack of draft changesets
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1135
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1136
    absorb analyzes each change in your working directory and attempts to
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1137
    amend the changed lines into the changesets in your stack that first
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1138
    introduced those lines.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1139
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1140
    If absorb cannot find an unambiguous changeset to amend for a change,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1141
    that change will be left in the working directory, untouched. They can be
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1142
    observed by :hg:`status` or :hg:`diff` afterwards. In other words,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1143
    absorb does not write to the working directory.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1144
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1145
    Changesets outside the revset `::. and not public() and not merge()` will
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1146
    not be changed.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1147
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1148
    Changesets that become empty after applying the changes will be deleted.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1149
40210
8f192f2c4a1e absorb: update help text
Mark Thomas <mbthomas@fb.com>
parents: 40190
diff changeset
  1150
    By default, absorb will show what it plans to do and prompt for
8f192f2c4a1e absorb: update help text
Mark Thomas <mbthomas@fb.com>
parents: 40190
diff changeset
  1151
    confirmation.  If you are confident that the changes will be absorbed
8f192f2c4a1e absorb: update help text
Mark Thomas <mbthomas@fb.com>
parents: 40190
diff changeset
  1152
    to the correct place, run :hg:`absorb -a` to apply the changes
8f192f2c4a1e absorb: update help text
Mark Thomas <mbthomas@fb.com>
parents: 40190
diff changeset
  1153
    immediately.
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1154
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1155
    Returns 0 on success, 1 if all chunks were ignored and nothing amended.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
  1156
    """
39786
d50125dec2c1 py3: fix kwargs handling in hgext/absorb.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39453
diff changeset
  1157
    opts = pycompat.byteskwargs(opts)
42128
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
  1158
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
  1159
    with repo.wlock(), repo.lock():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1160
        if not opts[b'dry_run']:
42128
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
  1161
            cmdutil.checkunfinished(repo)
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
  1162
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
  1163
        state = absorb(ui, repo, pats=pats, opts=opts)
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
  1164
        if sum(s[0] for s in state.chunkstats.values()) == 0:
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
  1165
            return 1