annotate hgext/absorb.py @ 42772:5c2e8a661418

rawdata: update callers in sqlitestore We update callers incrementally because this help bisecting failures. This was useful during development, so we expect it might be useful again in the future.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 07 Aug 2019 20:09:53 +0200
parents c1bf63ac30c5
children 2372284d9457
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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 _
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
39 from mercurial import (
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
40 cmdutil,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
41 commands,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
42 context,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
43 crecord,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
44 error,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
45 linelog,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
46 mdiff,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
47 node,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
48 obsolete,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
49 patch,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
50 phases,
38920
a5c8c5476339 absorb: use pycompat to get xrange
Augie Fackler <augie@google.com>
parents: 38919
diff changeset
51 pycompat,
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
52 registrar,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
53 scmutil,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
54 util,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
55 )
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
56 from mercurial.utils import (
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
57 stringutil,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
58 )
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
59
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
60 # 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
61 # 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
62 # 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
63 # leave the attribute unspecified.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
64 testedwith = 'ships-with-hg-core'
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
65
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
66 cmdtable = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
67 command = registrar.command(cmdtable)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
68
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
69 configtable = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
70 configitem = registrar.configitem(configtable)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
71
38961
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
72 configitem('absorb', 'add-noise', default=True)
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
73 configitem('absorb', 'amend-flag', default=None)
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
74 configitem('absorb', 'max-stack-size', default=50)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
75
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
76 colortable = {
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
77 'absorb.description': 'yellow',
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
78 'absorb.node': 'blue bold',
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
79 'absorb.path': 'bold',
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
80 }
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
81
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
82 defaultdict = collections.defaultdict
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 class nullui(object):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
85 """blank ui object doing nothing"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
86 debugflag = False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
87 verbose = False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
88 quiet = True
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
89
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
90 def __getitem__(name):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
91 def nullfunc(*args, **kwds):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
92 return
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
93 return nullfunc
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
94
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
95 class emptyfilecontext(object):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
96 """minimal filecontext representing an empty file"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
97 def data(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
98 return ''
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
99
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
100 def node(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
101 return node.nullid
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
102
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
103 def uniq(lst):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
104 """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
105 seen = set()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
106 result = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
107 for x in lst:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
108 if x not in seen:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
109 seen.add(x)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
110 result.append(x)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
111 return result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
112
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
113 def getdraftstack(headctx, limit=None):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
114 """(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
115
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
116 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
117 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
118
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
119 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
120 returned has and only has 1 parent.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
121 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
122 ctx = headctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
123 result = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
124 while ctx.phase() != phases.public:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
125 if limit and len(result) >= limit:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
126 break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
127 parents = ctx.parents()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
128 if len(parents) != 1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
129 break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
130 result.append(ctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
131 ctx = parents[0]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
132 result.reverse()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
133 return result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
134
38918
2ac40e86f604 absorb: avoid mutable default arg
Augie Fackler <augie@google.com>
parents: 38917
diff changeset
135 def getfilestack(stack, path, seenfctxs=None):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
136 """([ctx], str, set) -> [fctx], {ctx: fctx}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
137
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
138 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
139 "getdraftstack" returns.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
140
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
141 follows renames, but not copies.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
142
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
143 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
144 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
145 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
146 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
147 "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
148 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
149
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
150 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
151 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
152
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
153 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
154 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
155 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
156 the remaining items are within the stack.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
157
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
158 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
159 revisions:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
160
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
161 changelog: 3----4----5----6----7
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
162 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
163
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
164 - 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
165 - 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
166 dummy empty filecontext.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
167 - if stack = [2], returns ([], {})
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
168 - 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
169 - 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
170 removed, since 1 is immutable.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
171 """
38918
2ac40e86f604 absorb: avoid mutable default arg
Augie Fackler <augie@google.com>
parents: 38917
diff changeset
172 if seenfctxs is None:
2ac40e86f604 absorb: avoid mutable default arg
Augie Fackler <augie@google.com>
parents: 38917
diff changeset
173 seenfctxs = set()
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
174 assert stack
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
175
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
176 if path not in stack[-1]:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
177 return [], {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
178
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
179 fctxs = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
180 fctxmap = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
181
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
182 pctx = stack[0].p1() # the public (immutable) ctx we stop at
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
183 for ctx in reversed(stack):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
184 if path not in ctx: # the file is added in the next commit
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
185 pctx = ctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
186 break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
187 fctx = ctx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
188 fctxs.append(fctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
189 if fctx in seenfctxs: # treat fctx as the immutable one
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
190 pctx = None # do not add another immutable fctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
191 break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
192 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
193 copy = fctx.copysource()
8843bc1fc14d absorb: migrate to new method for getting copy info
Martin von Zweigbergk <martinvonz@google.com>
parents: 41365
diff changeset
194 if copy:
8843bc1fc14d absorb: migrate to new method for getting copy info
Martin von Zweigbergk <martinvonz@google.com>
parents: 41365
diff changeset
195 path = copy # follow rename
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
196 if path in ctx: # but do not follow copy
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
197 pctx = ctx.p1()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
198 break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
199
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
200 if pctx is not None: # need an extra immutable fctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
201 if path in pctx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
202 fctxs.append(pctx[path])
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
203 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
204 fctxs.append(emptyfilecontext())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
205
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
206 fctxs.reverse()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
207 # 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
208 # 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
209 # changelog: 4----5----6 (linear, no merges)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
210 # filelog: 1----2----1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
211 # ^ reuse filerev (impossible)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
212 # 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
213 # 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
214 return uniq(fctxs), fctxmap
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
215
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
216 class overlaystore(patch.filestore):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
217 """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
218 memworkingcopy: {path: content}, overrides file contents.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
219 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
220 def __init__(self, basectx, memworkingcopy):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
221 self.basectx = basectx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
222 self.memworkingcopy = memworkingcopy
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
223
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
224 def getfile(self, path):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
225 """comply with mercurial.patch.filestore.getfile"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
226 if path not in self.basectx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
227 return None, None, None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
228 fctx = self.basectx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
229 if path in self.memworkingcopy:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
230 content = self.memworkingcopy[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
231 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
232 content = fctx.data()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
233 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
234 copy = fctx.copysource()
8843bc1fc14d absorb: migrate to new method for getting copy info
Martin von Zweigbergk <martinvonz@google.com>
parents: 41365
diff changeset
235 return content, mode, copy
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
236
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
237 def overlaycontext(memworkingcopy, ctx, parents=None, extra=None):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
238 """({path: content}, ctx, (p1node, p2node)?, {}?) -> memctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
239 memworkingcopy overrides file contents.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
240 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
241 # parents must contain 2 items: (node1, node2)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
242 if parents is None:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
243 parents = ctx.repo().changelog.parents(ctx.node())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
244 if extra is None:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
245 extra = ctx.extra()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
246 date = ctx.date()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
247 desc = ctx.description()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
248 user = ctx.user()
38987
9204445ad54c absorb: port partway to Python 3
Augie Fackler <augie@google.com>
parents: 38961
diff changeset
249 files = set(ctx.files()).union(memworkingcopy)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
250 store = overlaystore(ctx, memworkingcopy)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
251 return context.memctx(
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
252 repo=ctx.repo(), parents=parents, text=desc,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
253 files=files, filectxfn=store, user=user, date=date,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
254 branch=None, extra=extra)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
255
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
256 class filefixupstate(object):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
257 """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
258
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
259 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
260
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
261 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
262 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
263
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
264 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
265 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
266 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
267 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
268 ...
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
269
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
270 a typical use is like:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
271
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
272 1. call diffwith, to calculate self.fixups
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
273 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
274 3. call apply, to apply changes
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
275 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
276 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
277
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
278 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
279 """([fctx], ui or None) -> None
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 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
282 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
283 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
284 self.fctxs = fctxs
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
285 self.path = path
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
286 self.ui = ui or nullui()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
287 self.opts = opts or {}
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 # 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
290 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
291 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
292 self.linelog = self._buildlinelog()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
293 if self.ui.debugflag:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
294 assert self._checkoutlinelog() == self.contents
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
295
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
296 # following fields will be filled later
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
297 self.chunkstats = [0, 0] # [adopted, total : int]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
298 self.targetlines = [] # [str]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
299 self.fixups = [] # [(linelog rev, a1, a2, b1, b2)]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
300 self.finalcontents = [] # [str]
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
301 self.ctxaffected = set()
38917
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 diffwith(self, targetfctx, fm=None):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
304 """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
305 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
306
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
307 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
308 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
309 a non-public fctx unambiguously.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
310
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
311 call this only once, before apply().
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
312
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
313 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
314 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
315 a = self.contents[-1]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
316 alines = self.contentlines[-1]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
317 b = targetfctx.data()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
318 blines = mdiff.splitnewlines(b)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
319 self.targetlines = blines
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 self.linelog.annotate(self.linelog.maxrev)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
322 annotated = self.linelog.annotateresult # [(linelog rev, linenum)]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
323 assert len(annotated) == len(alines)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
324 # 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
325 if annotated:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
326 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
327 annotated.append(dummyendline)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
328
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
329 # analyse diff blocks
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
330 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
331 newfixups = self._analysediffchunk(chunk, annotated)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
332 self.chunkstats[0] += bool(newfixups) # 1 or 0
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
333 self.chunkstats[1] += 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
334 self.fixups += newfixups
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
335 if fm is not None:
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
336 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
337
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
338 def apply(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
339 """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
340
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
341 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
342 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
343 # 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
344 # self.linelog.annotate(self.linelog.maxrev)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
345 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
346 blines = self.targetlines[b1:b2]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
347 if self.ui.debugflag:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
348 idx = (max(rev - 1, 0)) // 2
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
349 self.ui.write(_('%s: chunk %d:%d -> %d lines\n')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
350 % (node.short(self.fctxs[idx].node()),
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
351 a1, a2, len(blines)))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
352 self.linelog.replacelines(rev, a1, a2, b1, b2)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
353 if self.opts.get('edit_lines', False):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
354 self.finalcontents = self._checkoutlinelogwithedits()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
355 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
356 self.finalcontents = self._checkoutlinelog()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
357
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
358 def getfinalcontent(self, fctx):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
359 """(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
360 idx = self.fctxs.index(fctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
361 return self.finalcontents[idx]
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 _analysediffchunk(self, chunk, annotated):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
364 """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
365
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
366 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
367
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
368 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
369 - 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
370 (self.fctxs[0])
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
371 - 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
372 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
373 to any non-public changesets.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
374 - 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
375 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
376 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
377 otherwise, give up.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
378 - 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
379 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
380 not continuous as seen from the linelog.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
381 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
382 a1, a2, b1, b2 = chunk
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
383 # find involved indexes from annotate result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
384 involved = annotated[a1:a2]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
385 if not involved and annotated: # a1 == a2 and a is not empty
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
386 # 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
387 # 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
388 nearbylinenums = {a2, max(0, a1 - 1)}
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
389 involved = [annotated[i]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
390 for i in nearbylinenums if annotated[i][0] != 1]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
391 involvedrevs = list(set(r for r, l in involved))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
392 newfixups = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
393 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
394 # chunk belongs to a single revision
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
395 rev = involvedrevs[0]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
396 if rev > 1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
397 fixuprev = rev + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
398 newfixups.append((fixuprev, a1, a2, b1, b2))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
399 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
400 # 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
401 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
402 rev, linenum = annotated[i]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
403 if rev > 1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
404 if b1 == b2: # deletion, simply remove that single line
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
405 nb1 = nb2 = 0
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
406 else: # 1:1 line mapping, change the corresponding rev
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
407 nb1 = b1 + i - a1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
408 nb2 = nb1 + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
409 fixuprev = rev + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
410 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
411 return self._optimizefixups(newfixups)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
412
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
413 @staticmethod
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
414 def _alldiffchunks(a, b, alines, blines):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
415 """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
416 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
417 for chunk, btype in blocks:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
418 if btype != '!':
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
419 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
420 yield chunk
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
421
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
422 def _buildlinelog(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
423 """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
424 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
425 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
426 llog = linelog.linelog()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
427 a, alines = '', []
38920
a5c8c5476339 absorb: use pycompat to get xrange
Augie Fackler <augie@google.com>
parents: 38919
diff changeset
428 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
429 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
430 llrev = i * 2 + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
431 chunks = self._alldiffchunks(a, b, alines, blines)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
432 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
433 llog.replacelines(llrev, a1, a2, b1, b2)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
434 a, alines = b, blines
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
435 return llog
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
436
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
437 def _checkoutlinelog(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
438 """() -> [str]. check out file contents from linelog"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
439 contents = []
38920
a5c8c5476339 absorb: use pycompat to get xrange
Augie Fackler <augie@google.com>
parents: 38919
diff changeset
440 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
441 rev = (i + 1) * 2
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
442 self.linelog.annotate(rev)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
443 content = ''.join(map(self._getline, self.linelog.annotateresult))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
444 contents.append(content)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
445 return contents
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
446
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
447 def _checkoutlinelogwithedits(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
448 """() -> [str]. prompt all lines for edit"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
449 alllines = self.linelog.getalllines()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
450 # header
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
451 editortext = (_('HG: editing %s\nHG: "y" means the line to the right '
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
452 'exists in the changeset to the top\nHG:\n')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
453 % self.fctxs[-1].path())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
454 # [(idx, fctx)]. hide the dummy emptyfilecontext
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
455 visiblefctxs = [(i, f)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
456 for i, f in enumerate(self.fctxs)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
457 if not isinstance(f, emptyfilecontext)]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
458 for i, (j, f) in enumerate(visiblefctxs):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
459 editortext += (_('HG: %s/%s %s %s\n') %
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
460 ('|' * i, '-' * (len(visiblefctxs) - i + 1),
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
461 node.short(f.node()),
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
462 f.description().split('\n',1)[0]))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
463 editortext += _('HG: %s\n') % ('|' * len(visiblefctxs))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
464 # 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
465 # but probably fine
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
466 lineset = defaultdict(lambda: set()) # {(llrev, linenum): {llrev}}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
467 for i, f in visiblefctxs:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
468 self.linelog.annotate((i + 1) * 2)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
469 for l in self.linelog.annotateresult:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
470 lineset[l].add(i)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
471 # append lines
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
472 for l in alllines:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
473 editortext += (' %s : %s' %
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
474 (''.join([('y' if i in lineset[l] else ' ')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
475 for i, _f in visiblefctxs]),
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
476 self._getline(l)))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
477 # run editor
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
478 editedtext = self.ui.edit(editortext, '', action='absorb')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
479 if not editedtext:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
480 raise error.Abort(_('empty editor text'))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
481 # parse edited result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
482 contents = ['' for i in self.fctxs]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
483 leftpadpos = 4
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
484 colonpos = leftpadpos + len(visiblefctxs) + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
485 for l in mdiff.splitnewlines(editedtext):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
486 if l.startswith('HG:'):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
487 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
488 if l[colonpos - 1:colonpos + 2] != ' : ':
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
489 raise error.Abort(_('malformed line: %s') % l)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
490 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
491 for i, ch in enumerate(
c146651a78e1 absorb: add a pycompat.bytestr() to fix --edit-lines functionality on Python 3
Augie Fackler <augie@google.com>
parents: 40951
diff changeset
492 pycompat.bytestr(l[leftpadpos:colonpos - 1])):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
493 if ch == 'y':
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
494 contents[visiblefctxs[i][0]] += linecontent
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
495 # 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
496 # 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
497 if editedtext != editortext:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
498 self.chunkstats = [1, 1]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
499 return contents
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
500
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
501 def _getline(self, lineinfo):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
502 """((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
503 rev, linenum = lineinfo
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
504 if rev & 1: # odd: original line taken from fctxs
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
505 return self.contentlines[rev // 2][linenum]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
506 else: # even: fixup line from targetfctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
507 return self.targetlines[linenum]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
508
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
509 def _iscontinuous(self, a1, a2, closedinterval=False):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
510 """(a1, a2 : int) -> bool
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
511
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
512 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
513 deletions (from other revisions) among these lines.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
514
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
515 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
516 it [a1, a2), or [a1, a2] ?
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
517 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
518 if a1 >= a2:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
519 return True
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
520 llog = self.linelog
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
521 offset1 = llog.getoffset(a1)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
522 offset2 = llog.getoffset(a2) + int(closedinterval)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
523 linesinbetween = llog.getalllines(offset1, offset2)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
524 return len(linesinbetween) == a2 - a1 + int(closedinterval)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
525
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
526 def _optimizefixups(self, fixups):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
527 """[(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
528 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
529 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
530 result = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
531 pcurrentchunk = [[-1, -1, -1, -1, -1]]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
532
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
533 def pushchunk():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
534 if pcurrentchunk[0][0] != -1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
535 result.append(tuple(pcurrentchunk[0]))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
536
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
537 for i, chunk in enumerate(fixups):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
538 rev, a1, a2, b1, b2 = chunk
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
539 lastrev = pcurrentchunk[0][0]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
540 lasta2 = pcurrentchunk[0][2]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
541 lastb2 = pcurrentchunk[0][4]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
542 if (a1 == lasta2 and b1 == lastb2 and rev == lastrev and
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
543 self._iscontinuous(max(a1 - 1, 0), a1)):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
544 # merge into currentchunk
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
545 pcurrentchunk[0][2] = a2
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
546 pcurrentchunk[0][4] = b2
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
547 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
548 pushchunk()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
549 pcurrentchunk[0] = list(chunk)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
550 pushchunk()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
551 return result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
552
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
553 def _showchanges(self, fm, alines, blines, chunk, fixups):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
554
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
555 def trim(line):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
556 if line.endswith('\n'):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
557 line = line[:-1]
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
558 return line
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
559
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
560 # 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
561 # with an extra command-line flag.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
562 a1, a2, b1, b2 = chunk
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
563 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
564 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
565 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
566 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
567 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
568 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
569
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
570 fm.startitem()
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
571 fm.write('hunk', ' %s\n',
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
572 '@@ -%d,%d +%d,%d @@'
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
573 % (a1, a2 - a1, b1, b2 - b1), label='diff.hunk')
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
574 fm.data(path=self.path, linetype='hunk')
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
575
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
576 def writeline(idx, diffchar, line, linetype, linelabel):
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
577 fm.startitem()
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
578 node = ''
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
579 if idx:
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
580 ctx = self.fctxs[idx]
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
581 fm.context(fctx=ctx)
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
582 node = ctx.hex()
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
583 self.ctxaffected.add(ctx.changectx())
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
584 fm.write('node', '%-7.7s ', node, label='absorb.node')
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
585 fm.write('diffchar ' + linetype, '%s%s\n', diffchar, line,
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
586 label=linelabel)
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
587 fm.data(path=self.path, linetype=linetype)
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
588
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
589 for i in pycompat.xrange(a1, a2):
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
590 writeline(aidxs[i - a1], '-', trim(alines[i]), 'deleted',
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
591 'diff.deleted')
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
592 for i in pycompat.xrange(b1, b2):
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
593 writeline(bidxs[i - b1], '+', trim(blines[i]), 'inserted',
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
594 'diff.inserted')
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
595
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
596 class fixupstate(object):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
597 """state needed to run absorb
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
598
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
599 internally, it keeps paths and filefixupstates.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
600
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
601 a typical use is like filefixupstates:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
602
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
603 1. call diffwith, to calculate fixups
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
604 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
605 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
606 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
607 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
608
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
609 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
610 """([ctx], ui or None) -> None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
611
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
612 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
613 all commits in stack are considered mutable.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
614 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
615 assert stack
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
616 self.ui = ui or nullui()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
617 self.opts = opts or {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
618 self.stack = stack
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
619 self.repo = stack[-1].repo().unfiltered()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
620
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
621 # following fields will be filled later
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
622 self.paths = [] # [str]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
623 self.status = None # ctx.status output
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
624 self.fctxmap = {} # {path: {ctx: fctx}}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
625 self.fixupmap = {} # {path: filefixupstate}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
626 self.replacemap = {} # {oldnode: newnode or None}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
627 self.finalnode = None # head after all fixups
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
628 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
629
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
630 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
631 """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
632 # only care about modified files
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
633 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
634 self.paths = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
635 # 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
636 # even if they are not modified
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
637 editopt = self.opts.get('edit_lines')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
638 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
639 interestingpaths = match.files()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
640 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
641 interestingpaths = self.status.modified
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
642 # prepare the filefixupstate
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
643 seenfctxs = set()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
644 # 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
645 # 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
646 for path in sorted(interestingpaths):
38921
e930df0f9a55 absorb: use ui.debug() instead of open-coding it
Augie Fackler <augie@google.com>
parents: 38920
diff changeset
647 self.ui.debug('calculating fixups for %s\n' % path)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
648 targetfctx = targetctx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
649 fctxs, ctx2fctx = getfilestack(self.stack, path, seenfctxs)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
650 # ignore symbolic links or binary, or unchanged files
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
651 if any(f.islink() or stringutil.binary(f.data())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
652 for f in [targetfctx] + fctxs
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
653 if not isinstance(f, emptyfilecontext)):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
654 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
655 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
656 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
657 seenfctxs.update(fctxs[1:])
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
658 self.fctxmap[path] = ctx2fctx
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
659 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
660 if fm is not None:
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
661 fm.startitem()
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
662 fm.plain('showing changes for ')
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
663 fm.write('path', '%s\n', path, label='absorb.path')
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
664 fm.data(linetype='path')
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
665 fstate.diffwith(targetfctx, fm)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
666 self.fixupmap[path] = fstate
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
667 self.paths.append(path)
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
668 self.ctxaffected.update(fstate.ctxaffected)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
669
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
670 def apply(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
671 """apply fixups to individual filefixupstates"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
672 for path, state in self.fixupmap.iteritems():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
673 if self.ui.debugflag:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
674 self.ui.write(_('applying fixups to %s\n') % path)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
675 state.apply()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
676
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
677 @property
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
678 def chunkstats(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
679 """-> {path: chunkstats}. collect chunkstats from filefixupstates"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
680 return dict((path, state.chunkstats)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
681 for path, state in self.fixupmap.iteritems())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
682
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
683 def commit(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
684 """commit changes. update self.finalnode, self.replacemap"""
42128
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
685 with self.repo.transaction('absorb') as tr:
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
686 self._commitstack()
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
687 self._movebookmarks(tr)
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
688 if self.repo['.'].node() in self.replacemap:
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
689 self._moveworkingdirectoryparent()
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
690 self._cleanupoldcommits()
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
691 return self.finalnode
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
692
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
693 def printchunkstats(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
694 """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
695 ui = self.ui
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
696 chunkstats = self.chunkstats
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
697 if ui.verbose:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
698 # chunkstats for each file
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
699 for path, stat in chunkstats.iteritems():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
700 if stat[0]:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
701 ui.write(_('%s: %d of %d chunk(s) applied\n')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
702 % (path, stat[0], stat[1]))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
703 elif not ui.quiet:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
704 # a summary for all files
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
705 stats = chunkstats.values()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
706 applied, total = (sum(s[i] for s in stats) for i in (0, 1))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
707 ui.write(_('%d of %d chunk(s) applied\n') % (applied, total))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
708
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
709 def _commitstack(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
710 """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
711 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
712 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
713 # last node (20-char) committed by us
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
714 lastcommitted = None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
715 # 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
716 # the original parent unchanged
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
717 nextp1 = None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
718 for ctx in self.stack:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
719 memworkingcopy = self._getnewfilecontents(ctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
720 if not memworkingcopy and not lastcommitted:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
721 # nothing changed, nothing commited
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
722 nextp1 = ctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
723 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
724 if self._willbecomenoop(memworkingcopy, ctx, nextp1):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
725 # changeset is no longer necessary
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
726 self.replacemap[ctx.node()] = None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
727 msg = _('became empty and was dropped')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
728 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
729 # changeset needs re-commit
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
730 nodestr = self._commitsingle(memworkingcopy, ctx, p1=nextp1)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
731 lastcommitted = self.repo[nodestr]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
732 nextp1 = lastcommitted
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
733 self.replacemap[ctx.node()] = lastcommitted.node()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
734 if memworkingcopy:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
735 msg = _('%d file(s) changed, became %s') % (
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
736 len(memworkingcopy), self._ctx2str(lastcommitted))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
737 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
738 msg = _('became %s') % self._ctx2str(lastcommitted)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
739 if self.ui.verbose and msg:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
740 self.ui.write(_('%s: %s\n') % (self._ctx2str(ctx), msg))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
741 self.finalnode = lastcommitted and lastcommitted.node()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
742
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
743 def _ctx2str(self, ctx):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
744 if self.ui.debugflag:
40150
1be1689d9ce9 absorb: print '{rev}:' as a prefix to the hash
Matt Harbison <matt_harbison@yahoo.com>
parents: 39786
diff changeset
745 return '%d:%s' % (ctx.rev(), ctx.hex())
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
746 else:
40150
1be1689d9ce9 absorb: print '{rev}:' as a prefix to the hash
Matt Harbison <matt_harbison@yahoo.com>
parents: 39786
diff changeset
747 return '%d:%s' % (ctx.rev(), node.short(ctx.node()))
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
748
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
749 def _getnewfilecontents(self, ctx):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
750 """(ctx) -> {path: str}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
751
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
752 fetch file contents from filefixupstates.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
753 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
754 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
755 result = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
756 for path in self.paths:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
757 ctx2fctx = self.fctxmap[path] # {ctx: fctx}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
758 if ctx not in ctx2fctx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
759 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
760 fctx = ctx2fctx[ctx]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
761 content = fctx.data()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
762 newcontent = self.fixupmap[path].getfinalcontent(fctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
763 if content != newcontent:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
764 result[fctx.path()] = newcontent
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
765 return result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
766
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
767 def _movebookmarks(self, tr):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
768 repo = self.repo
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
769 needupdate = [(name, self.replacemap[hsh])
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
770 for name, hsh in repo._bookmarks.iteritems()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
771 if hsh in self.replacemap]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
772 changes = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
773 for name, hsh in needupdate:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
774 if hsh:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
775 changes.append((name, hsh))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
776 if self.ui.verbose:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
777 self.ui.write(_('moving bookmark %s to %s\n')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
778 % (name, node.hex(hsh)))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
779 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
780 changes.append((name, None))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
781 if self.ui.verbose:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
782 self.ui.write(_('deleting bookmark %s\n') % name)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
783 repo._bookmarks.applychanges(repo, tr, changes)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
784
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
785 def _moveworkingdirectoryparent(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
786 if not self.finalnode:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
787 # Find the latest not-{obsoleted,stripped} parent.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
788 revs = self.repo.revs('max(::. - %ln)', self.replacemap.keys())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
789 ctx = self.repo[revs.first()]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
790 self.finalnode = ctx.node()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
791 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
792 ctx = self.repo[self.finalnode]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
793
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
794 dirstate = self.repo.dirstate
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
795 # 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
796 # 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
797 noop = lambda: 0
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
798 restore = noop
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
799 if util.safehasattr(dirstate, '_fsmonitorstate'):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
800 bak = dirstate._fsmonitorstate.invalidate
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
801 def restore():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
802 dirstate._fsmonitorstate.invalidate = bak
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
803 dirstate._fsmonitorstate.invalidate = noop
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
804 try:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
805 with dirstate.parentchange():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
806 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
807 finally:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
808 restore()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
809
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
810 @staticmethod
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
811 def _willbecomenoop(memworkingcopy, ctx, pctx=None):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
812 """({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
813
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
814 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
815 memworkingcopy overrides), return True. otherwise return False.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
816 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
817 if not pctx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
818 parents = ctx.parents()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
819 if len(parents) != 1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
820 return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
821 pctx = parents[0]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
822 # 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
823 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
824 return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
825 for path, content in memworkingcopy.iteritems():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
826 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
827 return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
828 fctx = ctx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
829 pfctx = pctx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
830 if pfctx.flags() != fctx.flags():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
831 return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
832 if pfctx.data() != content:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
833 return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
834 return True
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
835
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
836 def _commitsingle(self, memworkingcopy, ctx, p1=None):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
837 """(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
838
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
839 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
840 different file contents replaced by memworkingcopy.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
841 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
842 parents = p1 and (p1, node.nullid)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
843 extra = ctx.extra()
38961
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
844 if self._useobsolete and self.ui.configbool('absorb', 'add-noise'):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
845 extra['absorb_source'] = ctx.hex()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
846 mctx = overlaycontext(memworkingcopy, ctx, parents, extra=extra)
41813
b38c7304974f absorb: let scmutil.cleanupnodes() take care of setting phase
Martin von Zweigbergk <martinvonz@google.com>
parents: 41812
diff changeset
847 return mctx.commit()
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
848
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
849 @util.propertycache
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
850 def _useobsolete(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
851 """() -> bool"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
852 return obsolete.isenabled(self.repo, obsolete.createmarkersopt)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
853
41812
c91321e86071 absorb: use scmutil.cleanupnodes() also when obsmarkers are disabled
Martin von Zweigbergk <martinvonz@google.com>
parents: 41811
diff changeset
854 def _cleanupoldcommits(self):
41811
a008e0af892e absorb: use scmutil.cleanupnodes() so operation gets set
Martin von Zweigbergk <martinvonz@google.com>
parents: 41778
diff changeset
855 replacements = {k: ([v] if v is not None else [])
a008e0af892e absorb: use scmutil.cleanupnodes() so operation gets set
Martin von Zweigbergk <martinvonz@google.com>
parents: 41778
diff changeset
856 for k, v in self.replacemap.iteritems()}
a008e0af892e absorb: use scmutil.cleanupnodes() so operation gets set
Martin von Zweigbergk <martinvonz@google.com>
parents: 41778
diff changeset
857 if replacements:
41813
b38c7304974f absorb: let scmutil.cleanupnodes() take care of setting phase
Martin von Zweigbergk <martinvonz@google.com>
parents: 41812
diff changeset
858 scmutil.cleanupnodes(self.repo, replacements, operation='absorb',
b38c7304974f absorb: let scmutil.cleanupnodes() take care of setting phase
Martin von Zweigbergk <martinvonz@google.com>
parents: 41812
diff changeset
859 fixphase=True)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
860
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
861 def _parsechunk(hunk):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
862 """(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
863 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
864 return None, None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
865 path = hunk.header.filename()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
866 a1 = hunk.fromline + len(hunk.before) - 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
867 # remove before and after context
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
868 hunk.before = hunk.after = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
869 buf = util.stringio()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
870 hunk.write(buf)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
871 patchlines = mdiff.splitnewlines(buf.getvalue())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
872 # hunk.prettystr() will update hunk.removed
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
873 a2 = a1 + hunk.removed
42442
c1bf63ac30c5 py3: use .startswith() instead of bytes[0]
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42351
diff changeset
874 blines = [l[1:] for l in patchlines[1:] if not l.startswith('-')]
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
875 return path, (a1, a2, blines)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
876
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
877 def overlaydiffcontext(ctx, chunks):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
878 """(ctx, [crecord.uihunk]) -> memctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
879
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
880 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
881 [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
882 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
883 # 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
884 # 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
885 # 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
886 # structured hunk objects at hand.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
887 # 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
888 # patch.recordhunk, crecord.uihunk)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
889 # 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
890 # 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
891 # re-invent the logic using much simpler code here.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
892 memworkingcopy = {} # {path: content}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
893 patchmap = defaultdict(lambda: []) # {path: [(a1, a2, [bline])]}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
894 for path, info in map(_parsechunk, chunks):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
895 if not path or not info:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
896 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
897 patchmap[path].append(info)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
898 for path, patches in patchmap.iteritems():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
899 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
900 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
901 patches.sort(reverse=True)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
902 lines = mdiff.splitnewlines(ctx[path].data())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
903 for a1, a2, blines in patches:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
904 lines[a1:a2] = blines
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
905 memworkingcopy[path] = ''.join(lines)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
906 return overlaycontext(memworkingcopy, ctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
907
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
908 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
909 """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
910
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
911 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
912 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
913 return fixupstate.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
914 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
915 if stack is None:
38961
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
916 limit = ui.configint('absorb', 'max-stack-size')
42266
b3fc78c028ef absorb: be more specific when erroring out on merge commit
Martin von Zweigbergk <martinvonz@google.com>
parents: 42128
diff changeset
917 headctx = repo['.']
b3fc78c028ef absorb: be more specific when erroring out on merge commit
Martin von Zweigbergk <martinvonz@google.com>
parents: 42128
diff changeset
918 if len(headctx.parents()) > 1:
b3fc78c028ef absorb: be more specific when erroring out on merge commit
Martin von Zweigbergk <martinvonz@google.com>
parents: 42128
diff changeset
919 raise error.Abort(_('cannot absorb into a merge'))
b3fc78c028ef absorb: be more specific when erroring out on merge commit
Martin von Zweigbergk <martinvonz@google.com>
parents: 42128
diff changeset
920 stack = getdraftstack(headctx, limit)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
921 if limit and len(stack) >= limit:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
922 ui.warn(_('absorb: only the recent %d changesets will '
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
923 'be analysed\n')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
924 % limit)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
925 if not stack:
39453
ab452995eaff absorb: clarify the reason for not finding changesets to modify
Matt Harbison <matt_harbison@yahoo.com>
parents: 38987
diff changeset
926 raise error.Abort(_('no mutable changeset to change'))
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
927 if targetctx is None: # default to working copy
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
928 targetctx = repo[None]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
929 if pats is None:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
930 pats = ()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
931 if opts is None:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
932 opts = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
933 state = fixupstate(stack, ui=ui, opts=opts)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
934 matcher = scmutil.match(targetctx, pats, opts)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
935 if opts.get('interactive'):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
936 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
937 origchunks = patch.parsepatch(diff)
42351
86f17fc31aa8 absorb: fix interactive mode I didn't know existed
Augie Fackler <augie@google.com>
parents: 42266
diff changeset
938 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
939 targetctx = overlaydiffcontext(stack[-1], chunks)
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
940 fm = None
40190
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
941 if opts.get('print_changes') or not opts.get('apply_changes'):
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
942 fm = ui.formatter('absorb', opts)
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
943 state.diffwith(targetctx, matcher, fm)
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
944 if fm is not None:
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
945 fm.startitem()
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
946 fm.write("count", "\n%d changesets affected\n", len(state.ctxaffected))
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
947 fm.data(linetype='summary')
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
948 for ctx in reversed(stack):
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
949 if ctx not in state.ctxaffected:
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
950 continue
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
951 fm.startitem()
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
952 fm.context(ctx=ctx)
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
953 fm.data(linetype='changeset')
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
954 fm.write('node', '%-7.7s ', ctx.hex(), label='absorb.node')
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
955 descfirstline = ctx.description().splitlines()[0]
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
956 fm.write('descfirstline', '%s\n', descfirstline,
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
957 label='absorb.description')
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
958 fm.end()
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
959 if not opts.get('dry_run'):
40951
e993a86cfcb8 absorb: don't prompt to apply changes when there are none to apply
Danny Hooper <hooper@google.com>
parents: 40295
diff changeset
960 if (not opts.get('apply_changes') and
e993a86cfcb8 absorb: don't prompt to apply changes when there are none to apply
Danny Hooper <hooper@google.com>
parents: 40295
diff changeset
961 state.ctxaffected and
e993a86cfcb8 absorb: don't prompt to apply changes when there are none to apply
Danny Hooper <hooper@google.com>
parents: 40295
diff changeset
962 ui.promptchoice("apply changes (yn)? $$ &Yes $$ &No", default=1)):
e993a86cfcb8 absorb: don't prompt to apply changes when there are none to apply
Danny Hooper <hooper@google.com>
parents: 40295
diff changeset
963 raise error.Abort(_('absorb cancelled\n'))
40190
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
964
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
965 state.apply()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
966 if state.commit():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
967 state.printchunkstats()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
968 elif not ui.quiet:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
969 ui.write(_('nothing applied\n'))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
970 return state
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
971
40295
fa88170c10bb help: adding a proper declaration for shortlist/basic commands (API)
Rodrigo Damazio <rdamazio@google.com>
parents: 40293
diff changeset
972 @command('absorb',
40190
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
973 [('a', 'apply-changes', None,
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
974 _('apply changes without prompting for confirmation')),
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
975 ('p', 'print-changes', None,
40210
8f192f2c4a1e absorb: update help text
Mark Thomas <mbthomas@fb.com>
parents: 40190
diff changeset
976 _('always print which changesets are modified by which changes')),
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
977 ('i', 'interactive', None,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
978 _('interactively select which chunks to apply (EXPERIMENTAL)')),
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
979 ('e', 'edit-lines', None,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
980 _('edit what lines belong to which changesets before commit '
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
981 '(EXPERIMENTAL)')),
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
982 ] + commands.dryrunopts + commands.templateopts + commands.walkopts,
40293
c303d65d2e34 help: assigning categories to existing commands
rdamazio@google.com
parents: 40210
diff changeset
983 _('hg absorb [OPTION] [FILE]...'),
40295
fa88170c10bb help: adding a proper declaration for shortlist/basic commands (API)
Rodrigo Damazio <rdamazio@google.com>
parents: 40293
diff changeset
984 helpcategory=command.CATEGORY_COMMITTING,
fa88170c10bb help: adding a proper declaration for shortlist/basic commands (API)
Rodrigo Damazio <rdamazio@google.com>
parents: 40293
diff changeset
985 helpbasic=True)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
986 def absorbcmd(ui, repo, *pats, **opts):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
987 """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
988
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
989 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
990 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
991 introduced those lines.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
992
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
993 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
994 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
995 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
996 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
997
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
998 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
999 not be changed.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1000
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1001 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
1002
40210
8f192f2c4a1e absorb: update help text
Mark Thomas <mbthomas@fb.com>
parents: 40190
diff changeset
1003 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
1004 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
1005 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
1006 immediately.
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1007
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1008 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
1009 """
39786
d50125dec2c1 py3: fix kwargs handling in hgext/absorb.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39453
diff changeset
1010 opts = pycompat.byteskwargs(opts)
42128
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
1011
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
1012 with repo.wlock(), repo.lock():
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
1013 if not opts['dry_run']:
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
1014 cmdutil.checkunfinished(repo)
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
1015
537a8aeb9977 absorb: aborting if another operation is in progress
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41830
diff changeset
1016 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
1017 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
1018 return 1