annotate hgext/absorb.py @ 40190:31dfa7dac4c9

absorb: prompt user to accept absorb changes by default Change the default absorb behaviour to print the changes out and then prompt the user if they want to absorb the changes or not. Providing the `-p` option still prints the result and exits. A new `-a` option is provided which applies the changes without printing them, giving the equivalent of the old behaviour. Differential Revision: https://phab.mercurial-scm.org/D4999
author Mark Thomas <mbthomas@fb.com>
date Fri, 12 Oct 2018 17:48:40 +0000
parents 2c5316796f45
children 8f192f2c4a1e
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 repair,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
54 scmutil,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
55 util,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
56 )
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
57 from mercurial.utils import (
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
58 stringutil,
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
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
61 # 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
62 # 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
63 # 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
64 # leave the attribute unspecified.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
65 testedwith = 'ships-with-hg-core'
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
66
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
67 cmdtable = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
68 command = registrar.command(cmdtable)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
69
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
70 configtable = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
71 configitem = registrar.configitem(configtable)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
72
38961
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
73 configitem('absorb', 'add-noise', default=True)
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
74 configitem('absorb', 'amend-flag', default=None)
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
75 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
76
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
77 colortable = {
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
78 'absorb.description': 'yellow',
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
79 'absorb.node': 'blue bold',
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
80 'absorb.path': 'bold',
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
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
83 defaultdict = collections.defaultdict
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
84
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
85 class nullui(object):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
86 """blank ui object doing nothing"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
87 debugflag = False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
88 verbose = False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
89 quiet = True
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
90
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
91 def __getitem__(name):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
92 def nullfunc(*args, **kwds):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
93 return
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
94 return nullfunc
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
95
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
96 class emptyfilecontext(object):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
97 """minimal filecontext representing an empty file"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
98 def data(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
99 return ''
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
100
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
101 def node(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
102 return node.nullid
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
103
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
104 def uniq(lst):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
105 """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
106 seen = set()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
107 result = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
108 for x in lst:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
109 if x not in seen:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
110 seen.add(x)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
111 result.append(x)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
112 return result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
113
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
114 def getdraftstack(headctx, limit=None):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
115 """(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
116
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
117 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
118 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
119
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
120 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
121 returned has and only has 1 parent.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
122 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
123 ctx = headctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
124 result = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
125 while ctx.phase() != phases.public:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
126 if limit and len(result) >= limit:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
127 break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
128 parents = ctx.parents()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
129 if len(parents) != 1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
130 break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
131 result.append(ctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
132 ctx = parents[0]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
133 result.reverse()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
134 return result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
135
38918
2ac40e86f604 absorb: avoid mutable default arg
Augie Fackler <augie@google.com>
parents: 38917
diff changeset
136 def getfilestack(stack, path, seenfctxs=None):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
137 """([ctx], str, set) -> [fctx], {ctx: fctx}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
138
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
139 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
140 "getdraftstack" returns.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
141
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
142 follows renames, but not copies.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
143
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
144 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
145 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
146 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
147 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
148 "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
149 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
150
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
151 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
152 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
153
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
154 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
155 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
156 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
157 the remaining items are within the stack.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
158
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
159 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
160 revisions:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
161
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
162 changelog: 3----4----5----6----7
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
163 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
164
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
165 - 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
166 - 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
167 dummy empty filecontext.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
168 - if stack = [2], returns ([], {})
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
169 - 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
170 - 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
171 removed, since 1 is immutable.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
172 """
38918
2ac40e86f604 absorb: avoid mutable default arg
Augie Fackler <augie@google.com>
parents: 38917
diff changeset
173 if seenfctxs is None:
2ac40e86f604 absorb: avoid mutable default arg
Augie Fackler <augie@google.com>
parents: 38917
diff changeset
174 seenfctxs = set()
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
175 assert stack
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
176
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
177 if path not in stack[-1]:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
178 return [], {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
179
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
180 fctxs = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
181 fctxmap = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
182
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
183 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
184 for ctx in reversed(stack):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
185 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
186 pctx = ctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
187 break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
188 fctx = ctx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
189 fctxs.append(fctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
190 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
191 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
192 break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
193 fctxmap[ctx] = fctx # only for mutable fctxs
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
194 renamed = fctx.renamed()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
195 if renamed:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
196 path = renamed[0] # follow rename
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
197 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
198 pctx = ctx.p1()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
199 break
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
200
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
201 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
202 if path in pctx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
203 fctxs.append(pctx[path])
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
204 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
205 fctxs.append(emptyfilecontext())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
206
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
207 fctxs.reverse()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
208 # 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
209 # 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
210 # changelog: 4----5----6 (linear, no merges)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
211 # filelog: 1----2----1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
212 # ^ reuse filerev (impossible)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
213 # 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
214 # 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
215 return uniq(fctxs), fctxmap
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
216
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
217 class overlaystore(patch.filestore):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
218 """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
219 memworkingcopy: {path: content}, overrides file contents.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
220 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
221 def __init__(self, basectx, memworkingcopy):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
222 self.basectx = basectx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
223 self.memworkingcopy = memworkingcopy
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
224
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
225 def getfile(self, path):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
226 """comply with mercurial.patch.filestore.getfile"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
227 if path not in self.basectx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
228 return None, None, None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
229 fctx = self.basectx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
230 if path in self.memworkingcopy:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
231 content = self.memworkingcopy[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
232 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
233 content = fctx.data()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
234 mode = (fctx.islink(), fctx.isexec())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
235 renamed = fctx.renamed() # False or (path, node)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
236 return content, mode, (renamed and renamed[0])
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
237
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
238 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
239 """({path: content}, ctx, (p1node, p2node)?, {}?) -> memctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
240 memworkingcopy overrides file contents.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
241 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
242 # parents must contain 2 items: (node1, node2)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
243 if parents is None:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
244 parents = ctx.repo().changelog.parents(ctx.node())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
245 if extra is None:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
246 extra = ctx.extra()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
247 date = ctx.date()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
248 desc = ctx.description()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
249 user = ctx.user()
38987
9204445ad54c absorb: port partway to Python 3
Augie Fackler <augie@google.com>
parents: 38961
diff changeset
250 files = set(ctx.files()).union(memworkingcopy)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
251 store = overlaystore(ctx, memworkingcopy)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
252 return context.memctx(
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
253 repo=ctx.repo(), parents=parents, text=desc,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
254 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
255 branch=None, extra=extra)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
256
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
257 class filefixupstate(object):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
258 """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
259
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
260 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
261
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
262 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
263 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
264
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
265 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
266 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
267 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
268 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
269 ...
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
270
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
271 a typical use is like:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
272
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
273 1. call diffwith, to calculate self.fixups
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
274 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
275 3. call apply, to apply changes
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
276 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
277 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
278
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
279 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
280 """([fctx], ui or None) -> None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
281
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
282 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
283 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
284 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
285 self.fctxs = fctxs
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
286 self.path = path
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
287 self.ui = ui or nullui()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
288 self.opts = opts or {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
289
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
290 # 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
291 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
292 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
293 self.linelog = self._buildlinelog()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
294 if self.ui.debugflag:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
295 assert self._checkoutlinelog() == self.contents
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
296
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
297 # following fields will be filled later
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
298 self.chunkstats = [0, 0] # [adopted, total : int]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
299 self.targetlines = [] # [str]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
300 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
301 self.finalcontents = [] # [str]
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
302 self.ctxaffected = set()
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
303
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
304 def diffwith(self, targetfctx, fm=None):
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
305 """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
306 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
307
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
308 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
309 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
310 a non-public fctx unambiguously.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
311
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
312 call this only once, before apply().
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
313
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
314 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
315 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
316 a = self.contents[-1]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
317 alines = self.contentlines[-1]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
318 b = targetfctx.data()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
319 blines = mdiff.splitnewlines(b)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
320 self.targetlines = blines
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
321
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
322 self.linelog.annotate(self.linelog.maxrev)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
323 annotated = self.linelog.annotateresult # [(linelog rev, linenum)]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
324 assert len(annotated) == len(alines)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
325 # 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
326 if annotated:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
327 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
328 annotated.append(dummyendline)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
329
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
330 # analyse diff blocks
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
331 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
332 newfixups = self._analysediffchunk(chunk, annotated)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
333 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
334 self.chunkstats[1] += 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
335 self.fixups += newfixups
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
336 if fm is not None:
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
337 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
338
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
339 def apply(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
340 """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
341
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
342 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
343 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
344 # 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
345 # self.linelog.annotate(self.linelog.maxrev)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
346 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
347 blines = self.targetlines[b1:b2]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
348 if self.ui.debugflag:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
349 idx = (max(rev - 1, 0)) // 2
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
350 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
351 % (node.short(self.fctxs[idx].node()),
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
352 a1, a2, len(blines)))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
353 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
354 if self.opts.get('edit_lines', False):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
355 self.finalcontents = self._checkoutlinelogwithedits()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
356 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
357 self.finalcontents = self._checkoutlinelog()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
358
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
359 def getfinalcontent(self, fctx):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
360 """(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
361 idx = self.fctxs.index(fctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
362 return self.finalcontents[idx]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
363
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
364 def _analysediffchunk(self, chunk, annotated):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
365 """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
366
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
367 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
368
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
369 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
370 - 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
371 (self.fctxs[0])
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
372 - 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
373 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
374 to any non-public changesets.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
375 - 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
376 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
377 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
378 otherwise, give up.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
379 - 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
380 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
381 not continuous as seen from the linelog.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
382 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
383 a1, a2, b1, b2 = chunk
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
384 # find involved indexes from annotate result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
385 involved = annotated[a1:a2]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
386 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
387 # 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
388 # 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
389 nearbylinenums = {a2, max(0, a1 - 1)}
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
390 involved = [annotated[i]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
391 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
392 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
393 newfixups = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
394 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
395 # chunk belongs to a single revision
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
396 rev = involvedrevs[0]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
397 if rev > 1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
398 fixuprev = rev + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
399 newfixups.append((fixuprev, a1, a2, b1, b2))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
400 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
401 # 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
402 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
403 rev, linenum = annotated[i]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
404 if rev > 1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
405 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
406 nb1 = nb2 = 0
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
407 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
408 nb1 = b1 + i - a1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
409 nb2 = nb1 + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
410 fixuprev = rev + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
411 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
412 return self._optimizefixups(newfixups)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
413
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
414 @staticmethod
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
415 def _alldiffchunks(a, b, alines, blines):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
416 """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
417 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
418 for chunk, btype in blocks:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
419 if btype != '!':
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
420 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
421 yield chunk
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
422
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
423 def _buildlinelog(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
424 """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
425 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
426 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
427 llog = linelog.linelog()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
428 a, alines = '', []
38920
a5c8c5476339 absorb: use pycompat to get xrange
Augie Fackler <augie@google.com>
parents: 38919
diff changeset
429 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
430 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
431 llrev = i * 2 + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
432 chunks = self._alldiffchunks(a, b, alines, blines)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
433 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
434 llog.replacelines(llrev, a1, a2, b1, b2)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
435 a, alines = b, blines
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
436 return llog
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
437
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
438 def _checkoutlinelog(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
439 """() -> [str]. check out file contents from linelog"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
440 contents = []
38920
a5c8c5476339 absorb: use pycompat to get xrange
Augie Fackler <augie@google.com>
parents: 38919
diff changeset
441 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
442 rev = (i + 1) * 2
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
443 self.linelog.annotate(rev)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
444 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
445 contents.append(content)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
446 return contents
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
447
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
448 def _checkoutlinelogwithedits(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
449 """() -> [str]. prompt all lines for edit"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
450 alllines = self.linelog.getalllines()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
451 # header
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
452 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
453 '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
454 % self.fctxs[-1].path())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
455 # [(idx, fctx)]. hide the dummy emptyfilecontext
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
456 visiblefctxs = [(i, f)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
457 for i, f in enumerate(self.fctxs)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
458 if not isinstance(f, emptyfilecontext)]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
459 for i, (j, f) in enumerate(visiblefctxs):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
460 editortext += (_('HG: %s/%s %s %s\n') %
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
461 ('|' * i, '-' * (len(visiblefctxs) - i + 1),
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
462 node.short(f.node()),
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
463 f.description().split('\n',1)[0]))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
464 editortext += _('HG: %s\n') % ('|' * len(visiblefctxs))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
465 # 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
466 # but probably fine
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
467 lineset = defaultdict(lambda: set()) # {(llrev, linenum): {llrev}}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
468 for i, f in visiblefctxs:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
469 self.linelog.annotate((i + 1) * 2)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
470 for l in self.linelog.annotateresult:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
471 lineset[l].add(i)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
472 # append lines
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
473 for l in alllines:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
474 editortext += (' %s : %s' %
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
475 (''.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
476 for i, _f in visiblefctxs]),
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
477 self._getline(l)))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
478 # run editor
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
479 editedtext = self.ui.edit(editortext, '', action='absorb')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
480 if not editedtext:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
481 raise error.Abort(_('empty editor text'))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
482 # parse edited result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
483 contents = ['' for i in self.fctxs]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
484 leftpadpos = 4
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
485 colonpos = leftpadpos + len(visiblefctxs) + 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
486 for l in mdiff.splitnewlines(editedtext):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
487 if l.startswith('HG:'):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
488 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
489 if l[colonpos - 1:colonpos + 2] != ' : ':
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
490 raise error.Abort(_('malformed line: %s') % l)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
491 linecontent = l[colonpos + 2:]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
492 for i, ch in enumerate(l[leftpadpos:colonpos - 1]):
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"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
685 with self.repo.wlock(), self.repo.lock():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
686 with self.repo.transaction('absorb') as tr:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
687 self._commitstack()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
688 self._movebookmarks(tr)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
689 if self.repo['.'].node() in self.replacemap:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
690 self._moveworkingdirectoryparent()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
691 if self._useobsolete:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
692 self._obsoleteoldcommits()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
693 if not self._useobsolete: # strip must be outside transactions
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
694 self._stripoldcommits()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
695 return self.finalnode
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
696
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
697 def printchunkstats(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
698 """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
699 ui = self.ui
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
700 chunkstats = self.chunkstats
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
701 if ui.verbose:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
702 # chunkstats for each file
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
703 for path, stat in chunkstats.iteritems():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
704 if stat[0]:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
705 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
706 % (path, stat[0], stat[1]))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
707 elif not ui.quiet:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
708 # a summary for all files
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
709 stats = chunkstats.values()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
710 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
711 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
712
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
713 def _commitstack(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
714 """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
715 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
716 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
717 # last node (20-char) committed by us
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
718 lastcommitted = None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
719 # 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
720 # the original parent unchanged
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
721 nextp1 = None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
722 for ctx in self.stack:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
723 memworkingcopy = self._getnewfilecontents(ctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
724 if not memworkingcopy and not lastcommitted:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
725 # nothing changed, nothing commited
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
726 nextp1 = ctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
727 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
728 msg = ''
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
729 if self._willbecomenoop(memworkingcopy, ctx, nextp1):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
730 # changeset is no longer necessary
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
731 self.replacemap[ctx.node()] = None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
732 msg = _('became empty and was dropped')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
733 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
734 # changeset needs re-commit
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
735 nodestr = self._commitsingle(memworkingcopy, ctx, p1=nextp1)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
736 lastcommitted = self.repo[nodestr]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
737 nextp1 = lastcommitted
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
738 self.replacemap[ctx.node()] = lastcommitted.node()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
739 if memworkingcopy:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
740 msg = _('%d file(s) changed, became %s') % (
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
741 len(memworkingcopy), self._ctx2str(lastcommitted))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
742 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
743 msg = _('became %s') % self._ctx2str(lastcommitted)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
744 if self.ui.verbose and msg:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
745 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
746 self.finalnode = lastcommitted and lastcommitted.node()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
747
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
748 def _ctx2str(self, ctx):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
749 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
750 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
751 else:
40150
1be1689d9ce9 absorb: print '{rev}:' as a prefix to the hash
Matt Harbison <matt_harbison@yahoo.com>
parents: 39786
diff changeset
752 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
753
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
754 def _getnewfilecontents(self, ctx):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
755 """(ctx) -> {path: str}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
756
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
757 fetch file contents from filefixupstates.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
758 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
759 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
760 result = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
761 for path in self.paths:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
762 ctx2fctx = self.fctxmap[path] # {ctx: fctx}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
763 if ctx not in ctx2fctx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
764 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
765 fctx = ctx2fctx[ctx]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
766 content = fctx.data()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
767 newcontent = self.fixupmap[path].getfinalcontent(fctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
768 if content != newcontent:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
769 result[fctx.path()] = newcontent
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
770 return result
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
771
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
772 def _movebookmarks(self, tr):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
773 repo = self.repo
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
774 needupdate = [(name, self.replacemap[hsh])
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
775 for name, hsh in repo._bookmarks.iteritems()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
776 if hsh in self.replacemap]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
777 changes = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
778 for name, hsh in needupdate:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
779 if hsh:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
780 changes.append((name, hsh))
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(_('moving bookmark %s to %s\n')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
783 % (name, node.hex(hsh)))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
784 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
785 changes.append((name, None))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
786 if self.ui.verbose:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
787 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
788 repo._bookmarks.applychanges(repo, tr, changes)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
789
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
790 def _moveworkingdirectoryparent(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
791 if not self.finalnode:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
792 # Find the latest not-{obsoleted,stripped} parent.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
793 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
794 ctx = self.repo[revs.first()]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
795 self.finalnode = ctx.node()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
796 else:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
797 ctx = self.repo[self.finalnode]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
798
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
799 dirstate = self.repo.dirstate
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
800 # 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
801 # 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
802 noop = lambda: 0
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
803 restore = noop
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
804 if util.safehasattr(dirstate, '_fsmonitorstate'):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
805 bak = dirstate._fsmonitorstate.invalidate
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
806 def restore():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
807 dirstate._fsmonitorstate.invalidate = bak
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
808 dirstate._fsmonitorstate.invalidate = noop
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
809 try:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
810 with dirstate.parentchange():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
811 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
812 finally:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
813 restore()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
814
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
815 @staticmethod
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
816 def _willbecomenoop(memworkingcopy, ctx, pctx=None):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
817 """({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
818
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
819 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
820 memworkingcopy overrides), return True. otherwise return False.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
821 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
822 if not pctx:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
823 parents = ctx.parents()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
824 if len(parents) != 1:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
825 return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
826 pctx = parents[0]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
827 # 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
828 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
829 return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
830 for path, content in memworkingcopy.iteritems():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
831 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
832 return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
833 fctx = ctx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
834 pfctx = pctx[path]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
835 if pfctx.flags() != fctx.flags():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
836 return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
837 if pfctx.data() != content:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
838 return False
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
839 return True
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
840
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
841 def _commitsingle(self, memworkingcopy, ctx, p1=None):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
842 """(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
843
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
844 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
845 different file contents replaced by memworkingcopy.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
846 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
847 parents = p1 and (p1, node.nullid)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
848 extra = ctx.extra()
38961
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
849 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
850 extra['absorb_source'] = ctx.hex()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
851 mctx = overlaycontext(memworkingcopy, ctx, parents, extra=extra)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
852 # preserve phase
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
853 with mctx.repo().ui.configoverride({
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
854 ('phases', 'new-commit'): ctx.phase()}):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
855 return mctx.commit()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
856
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
857 @util.propertycache
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
858 def _useobsolete(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
859 """() -> bool"""
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
860 return obsolete.isenabled(self.repo, obsolete.createmarkersopt)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
861
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
862 def _obsoleteoldcommits(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
863 relations = [(self.repo[k], v and (self.repo[v],) or ())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
864 for k, v in self.replacemap.iteritems()]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
865 if relations:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
866 obsolete.createmarkers(self.repo, relations)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
867
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
868 def _stripoldcommits(self):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
869 nodelist = self.replacemap.keys()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
870 # make sure we don't strip innocent children
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
871 revs = self.repo.revs('%ln - (::(heads(%ln::)-%ln))', nodelist,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
872 nodelist, nodelist)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
873 tonode = self.repo.changelog.node
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
874 nodelist = [tonode(r) for r in revs]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
875 if nodelist:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
876 repair.strip(self.repo.ui, self.repo, nodelist)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
877
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
878 def _parsechunk(hunk):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
879 """(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
880 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
881 return None, None
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
882 path = hunk.header.filename()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
883 a1 = hunk.fromline + len(hunk.before) - 1
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
884 # remove before and after context
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
885 hunk.before = hunk.after = []
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
886 buf = util.stringio()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
887 hunk.write(buf)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
888 patchlines = mdiff.splitnewlines(buf.getvalue())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
889 # hunk.prettystr() will update hunk.removed
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
890 a2 = a1 + hunk.removed
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
891 blines = [l[1:] for l in patchlines[1:] if l[0] != '-']
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
892 return path, (a1, a2, blines)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
893
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
894 def overlaydiffcontext(ctx, chunks):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
895 """(ctx, [crecord.uihunk]) -> memctx
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
896
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
897 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
898 [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
899 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
900 # 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
901 # 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
902 # 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
903 # structured hunk objects at hand.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
904 # 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
905 # patch.recordhunk, crecord.uihunk)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
906 # 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
907 # 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
908 # 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
909 memworkingcopy = {} # {path: content}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
910 patchmap = defaultdict(lambda: []) # {path: [(a1, a2, [bline])]}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
911 for path, info in map(_parsechunk, chunks):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
912 if not path or not info:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
913 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
914 patchmap[path].append(info)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
915 for path, patches in patchmap.iteritems():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
916 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
917 continue
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
918 patches.sort(reverse=True)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
919 lines = mdiff.splitnewlines(ctx[path].data())
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
920 for a1, a2, blines in patches:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
921 lines[a1:a2] = blines
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
922 memworkingcopy[path] = ''.join(lines)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
923 return overlaycontext(memworkingcopy, ctx)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
924
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
925 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
926 """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
927
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
928 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
929 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
930 return fixupstate.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
931 """
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
932 if stack is None:
38961
19344143b3e1 absorb: following UI conventions
David Demelier <markand@malikania.fr>
parents: 38932
diff changeset
933 limit = ui.configint('absorb', 'max-stack-size')
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
934 stack = getdraftstack(repo['.'], limit)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
935 if limit and len(stack) >= limit:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
936 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
937 'be analysed\n')
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
938 % limit)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
939 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
940 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
941 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
942 targetctx = repo[None]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
943 if pats is None:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
944 pats = ()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
945 if opts is None:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
946 opts = {}
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
947 state = fixupstate(stack, ui=ui, opts=opts)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
948 matcher = scmutil.match(targetctx, pats, opts)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
949 if opts.get('interactive'):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
950 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
951 origchunks = patch.parsepatch(diff)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
952 chunks = cmdutil.recordfilter(ui, origchunks)[0]
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
953 targetctx = overlaydiffcontext(stack[-1], chunks)
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
954 fm = None
40190
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
955 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
956 fm = ui.formatter('absorb', opts)
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
957 state.diffwith(targetctx, matcher, fm)
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
958 if fm is not None:
40188
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
959 fm.startitem()
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
960 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
961 fm.data(linetype='summary')
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
962 for ctx in reversed(stack):
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
963 if ctx not in state.ctxaffected:
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
964 continue
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
965 fm.startitem()
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
966 fm.context(ctx=ctx)
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
967 fm.data(linetype='changeset')
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
968 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
969 descfirstline = ctx.description().splitlines()[0]
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
970 fm.write('descfirstline', '%s\n', descfirstline,
2c5316796f45 absorb: print summary of changesets affected
Mark Thomas <mbthomas@fb.com>
parents: 40187
diff changeset
971 label='absorb.description')
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
972 fm.end()
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
973 if not opts.get('dry_run'):
40190
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
974 if not opts.get('apply_changes'):
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
975 if ui.promptchoice("apply changes (yn)? $$ &Yes $$ &No", default=1):
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
976 raise error.Abort(_('absorb cancelled\n'))
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
977
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
978 state.apply()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
979 if state.commit():
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
980 state.printchunkstats()
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
981 elif not ui.quiet:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
982 ui.write(_('nothing applied\n'))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
983 return state
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
984
38932
205efbf656c2 absorb: remove sf alias for command
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38923
diff changeset
985 @command('^absorb',
40190
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
986 [('a', 'apply-changes', None,
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
987 _('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
988 ('p', 'print-changes', None,
31dfa7dac4c9 absorb: prompt user to accept absorb changes by default
Mark Thomas <mbthomas@fb.com>
parents: 40188
diff changeset
989 _('just 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
990 ('i', 'interactive', None,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
991 _('interactively select which chunks to apply (EXPERIMENTAL)')),
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
992 ('e', 'edit-lines', None,
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
993 _('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
994 '(EXPERIMENTAL)')),
40187
dcda50856843 absorb: use a formatter to generate output
Mark Thomas <mbthomas@fb.com>
parents: 40150
diff changeset
995 ] + commands.dryrunopts + commands.templateopts + commands.walkopts,
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
996 _('hg absorb [OPTION] [FILE]...'))
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
997 def absorbcmd(ui, repo, *pats, **opts):
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
998 """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
999
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1000 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
1001 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
1002 introduced those lines.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1003
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1004 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
1005 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
1006 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
1007 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
1008
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1009 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
1010 not be changed.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1011
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1012 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
1013
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1014 If in doubt, run :hg:`absorb -pn` to preview what changesets will
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1015 be amended by what changed lines, without actually changing anything.
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1016
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1017 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
1018 """
39786
d50125dec2c1 py3: fix kwargs handling in hgext/absorb.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39453
diff changeset
1019 opts = pycompat.byteskwargs(opts)
38917
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1020 state = absorb(ui, repo, pats=pats, opts=opts)
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1021 if sum(s[0] for s in state.chunkstats.values()) == 0:
5111d11b8719 absorb: import extension from Facebook's hg-experimental
Augie Fackler <augie@google.com>
parents:
diff changeset
1022 return 1