Mercurial > hg
annotate hgext/fix.py @ 40043:6509fcec830c
url: allow to configure timeout on http connection
By default, httplib.HTTPConnection opens connection with no timeout.
If the server is hanging, Mercurial will wait indefinitely. This may be an
issue for automated scripts.
Differential Revision: https://phab.mercurial-scm.org/D4878
author | Cédric Krier <ced@b2ck.com> |
---|---|
date | Thu, 04 Oct 2018 11:28:48 +0200 |
parents | f1d6021453c2 |
children | c303d65d2e34 |
rev | line source |
---|---|
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
1 # fix - rewrite file content in changesets and working copy |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
2 # |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
3 # Copyright 2018 Google LLC. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
4 # |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
7 """rewrite file content in changesets or working copy (EXPERIMENTAL) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
8 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
9 Provides a command that runs configured tools on the contents of modified files, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
10 writing back any fixes to the working copy or replacing changesets. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
11 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
12 Here is an example configuration that causes :hg:`fix` to apply automatic |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
13 formatting fixes to modified lines in C++ code:: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
14 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
15 [fix] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
16 clang-format:command=clang-format --assume-filename={rootpath} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
17 clang-format:linerange=--lines={first}:{last} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
18 clang-format:fileset=set:**.cpp or **.hpp |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
19 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
20 The :command suboption forms the first part of the shell command that will be |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
21 used to fix a file. The content of the file is passed on standard input, and the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
22 fixed file content is expected on standard output. If there is any output on |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
23 standard error, the file will not be affected. Some values may be substituted |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
24 into the command:: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
25 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
26 {rootpath} The path of the file being fixed, relative to the repo root |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
27 {basename} The name of the file being fixed, without the directory path |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
28 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
29 If the :linerange suboption is set, the tool will only be run if there are |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
30 changed lines in a file. The value of this suboption is appended to the shell |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
31 command once for every range of changed lines in the file. Some values may be |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
32 substituted into the command:: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
33 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
34 {first} The 1-based line number of the first line in the modified range |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
35 {last} The 1-based line number of the last line in the modified range |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
36 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
37 The :fileset suboption determines which files will be passed through each |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
38 configured tool. See :hg:`help fileset` for possible values. If there are file |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
39 arguments to :hg:`fix`, the intersection of these filesets is used. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
40 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
41 There is also a configurable limit for the maximum size of file that will be |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
42 processed by :hg:`fix`:: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
43 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
44 [fix] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
45 maxfilesize=2MB |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
46 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
47 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
48 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
49 from __future__ import absolute_import |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
50 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
51 import collections |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
52 import itertools |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
53 import os |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
54 import re |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
55 import subprocess |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
56 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
57 from mercurial.i18n import _ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
58 from mercurial.node import nullrev |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
59 from mercurial.node import wdirrev |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
60 |
39826
c31ce080eb75
py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents:
38967
diff
changeset
|
61 from mercurial.utils import ( |
c31ce080eb75
py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents:
38967
diff
changeset
|
62 procutil, |
c31ce080eb75
py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents:
38967
diff
changeset
|
63 ) |
c31ce080eb75
py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents:
38967
diff
changeset
|
64 |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
65 from mercurial import ( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
66 cmdutil, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
67 context, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
68 copies, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
69 error, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
70 mdiff, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
71 merge, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
72 obsolete, |
37618
1edf3738e000
fix: port most of the way to python 3
Augie Fackler <augie@google.com>
parents:
37595
diff
changeset
|
73 pycompat, |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
74 registrar, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
75 scmutil, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
76 util, |
38536
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
77 worker, |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
78 ) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
79 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
80 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
81 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
82 # be specifying the version(s) of Mercurial they are tested with, or |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
83 # leave the attribute unspecified. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
84 testedwith = 'ships-with-hg-core' |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
85 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
86 cmdtable = {} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
87 command = registrar.command(cmdtable) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
88 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
89 configtable = {} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
90 configitem = registrar.configitem(configtable) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
91 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
92 # Register the suboptions allowed for each configured fixer. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
93 FIXER_ATTRS = ('command', 'linerange', 'fileset') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
94 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
95 for key in FIXER_ATTRS: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
96 configitem('fix', '.*(:%s)?' % key, default=None, generic=True) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
97 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
98 # A good default size allows most source code files to be fixed, but avoids |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
99 # letting fixer tools choke on huge inputs, which could be surprising to the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
100 # user. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
101 configitem('fix', 'maxfilesize', default='2MB') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
102 |
38949
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38860
diff
changeset
|
103 allopt = ('', 'all', False, _('fix all non-public non-obsolete revisions')) |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38860
diff
changeset
|
104 baseopt = ('', 'base', [], _('revisions to diff against (overrides automatic ' |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38860
diff
changeset
|
105 'selection, and applies to every revision being ' |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38860
diff
changeset
|
106 'fixed)'), _('REV')) |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38860
diff
changeset
|
107 revopt = ('r', 'rev', [], _('revisions to fix'), _('REV')) |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38860
diff
changeset
|
108 wdiropt = ('w', 'working-dir', False, _('fix the working directory')) |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38860
diff
changeset
|
109 wholeopt = ('', 'whole', False, _('always fix every line of a file')) |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38860
diff
changeset
|
110 usage = _('[OPTION]... [FILE]...') |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38860
diff
changeset
|
111 |
b0c591950e51
fix: pull out flag definitions to make them re-usable from extensions
Danny Hooper <hooper@google.com>
parents:
38860
diff
changeset
|
112 @command('fix', [allopt, baseopt, revopt, wdiropt, wholeopt], usage) |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
113 def fix(ui, repo, *pats, **opts): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
114 """rewrite file content in changesets or working directory |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
115 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
116 Runs any configured tools to fix the content of files. Only affects files |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
117 with changes, unless file arguments are provided. Only affects changed lines |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
118 of files, unless the --whole flag is used. Some tools may always affect the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
119 whole file regardless of --whole. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
120 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
121 If revisions are specified with --rev, those revisions will be checked, and |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
122 they may be replaced with new revisions that have fixed file content. It is |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
123 desirable to specify all descendants of each specified revision, so that the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
124 fixes propagate to the descendants. If all descendants are fixed at the same |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
125 time, no merging, rebasing, or evolution will be required. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
126 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
127 If --working-dir is used, files with uncommitted changes in the working copy |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
128 will be fixed. If the checked-out revision is also fixed, the working |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
129 directory will update to the replacement revision. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
130 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
131 When determining what lines of each file to fix at each revision, the whole |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
132 set of revisions being fixed is considered, so that fixes to earlier |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
133 revisions are not forgotten in later ones. The --base flag can be used to |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
134 override this default behavior, though it is not usually desirable to do so. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
135 """ |
37618
1edf3738e000
fix: port most of the way to python 3
Augie Fackler <augie@google.com>
parents:
37595
diff
changeset
|
136 opts = pycompat.byteskwargs(opts) |
37595
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37213
diff
changeset
|
137 if opts['all']: |
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37213
diff
changeset
|
138 if opts['rev']: |
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37213
diff
changeset
|
139 raise error.Abort(_('cannot specify both "--rev" and "--all"')) |
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37213
diff
changeset
|
140 opts['rev'] = ['not public() and not obsolete()'] |
e2506748b47f
fix: add --all flag to fix non-public non-obsolete revisions
Danny Hooper <hooper@google.com>
parents:
37213
diff
changeset
|
141 opts['working_dir'] = True |
38420
c1f4364f9336
fix: include cleanupnodes() in transaction
Martin von Zweigbergk <martinvonz@google.com>
parents:
37774
diff
changeset
|
142 with repo.wlock(), repo.lock(), repo.transaction('fix'): |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
143 revstofix = getrevstofix(ui, repo, opts) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
144 basectxs = getbasectxs(repo, opts, revstofix) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
145 workqueue, numitems = getworkqueue(ui, repo, pats, opts, revstofix, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
146 basectxs) |
38536
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
147 fixers = getfixers(ui) |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
148 |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
149 # There are no data dependencies between the workers fixing each file |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
150 # revision, so we can use all available parallelism. |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
151 def getfixes(items): |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
152 for rev, path in items: |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
153 ctx = repo[rev] |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
154 olddata = ctx[path].data() |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
155 newdata = fixfile(ui, opts, fixers, ctx, path, basectxs[rev]) |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
156 # Don't waste memory/time passing unchanged content back, but |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
157 # produce one result per item either way. |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
158 yield (rev, path, newdata if newdata != olddata else None) |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
159 results = worker.worker(ui, 1.0, getfixes, tuple(), workqueue) |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
160 |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
161 # We have to hold on to the data for each successor revision in memory |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
162 # until all its parents are committed. We ensure this by committing and |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
163 # freeing memory for the revisions in some topological order. This |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
164 # leaves a little bit of memory efficiency on the table, but also makes |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
165 # the tests deterministic. It might also be considered a feature since |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
166 # it makes the results more easily reproducible. |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
167 filedata = collections.defaultdict(dict) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
168 replacements = {} |
38950
35bc4b6e132d
fix: correctly set wdirwritten given that the dict item is deleted
Danny Hooper <hooper@google.com>
parents:
38949
diff
changeset
|
169 wdirwritten = False |
38536
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
170 commitorder = sorted(revstofix, reverse=True) |
38537
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
171 with ui.makeprogress(topic=_('fixing'), unit=_('files'), |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
172 total=sum(numitems.values())) as progress: |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
173 for rev, path, newdata in results: |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
174 progress.increment(item=path) |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
175 if newdata is not None: |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
176 filedata[rev][path] = newdata |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
177 numitems[rev] -= 1 |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
178 # Apply the fixes for this and any other revisions that are |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
179 # ready and sitting at the front of the queue. Using a loop here |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
180 # prevents the queue from being blocked by the first revision to |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
181 # be ready out of order. |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
182 while commitorder and not numitems[commitorder[-1]]: |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
183 rev = commitorder.pop() |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
184 ctx = repo[rev] |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
185 if rev == wdirrev: |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
186 writeworkingdir(repo, ctx, filedata[rev], replacements) |
38950
35bc4b6e132d
fix: correctly set wdirwritten given that the dict item is deleted
Danny Hooper <hooper@google.com>
parents:
38949
diff
changeset
|
187 wdirwritten = bool(filedata[rev]) |
38537
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
188 else: |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
189 replacerev(ui, repo, ctx, filedata[rev], replacements) |
a3be09e277e9
fix: add progress bar for number of file revisions processed
Danny Hooper <hooper@google.com>
parents:
38536
diff
changeset
|
190 del filedata[rev] |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
191 |
38950
35bc4b6e132d
fix: correctly set wdirwritten given that the dict item is deleted
Danny Hooper <hooper@google.com>
parents:
38949
diff
changeset
|
192 cleanup(repo, replacements, wdirwritten) |
38811
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
193 |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
194 def cleanup(repo, replacements, wdirwritten): |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
195 """Calls scmutil.cleanupnodes() with the given replacements. |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
196 |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
197 "replacements" is a dict from nodeid to nodeid, with one key and one value |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
198 for every revision that was affected by fixing. This is slightly different |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
199 from cleanupnodes(). |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
200 |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
201 "wdirwritten" is a bool which tells whether the working copy was affected by |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
202 fixing, since it has no entry in "replacements". |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
203 |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
204 Useful as a hook point for extending "hg fix" with output summarizing the |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
205 effects of the command, though we choose not to output anything here. |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
206 """ |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
207 replacements = {prec: [succ] for prec, succ in replacements.iteritems()} |
64535d43c103
fix: add a monkey-patchable point after all new revisions have been committed
Danny Hooper <hooper@google.com>
parents:
38770
diff
changeset
|
208 scmutil.cleanupnodes(repo, replacements, 'fix', fixphase=True) |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
209 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
210 def getworkqueue(ui, repo, pats, opts, revstofix, basectxs): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
211 """"Constructs the list of files to be fixed at specific revisions |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
212 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
213 It is up to the caller how to consume the work items, and the only |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
214 dependence between them is that replacement revisions must be committed in |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
215 topological order. Each work item represents a file in the working copy or |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
216 in some revision that should be fixed and written back to the working copy |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
217 or into a replacement revision. |
38536
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
218 |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
219 Work items for the same revision are grouped together, so that a worker |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
220 pool starting with the first N items in parallel is likely to finish the |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
221 first revision's work before other revisions. This can allow us to write |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
222 the result to disk and reduce memory footprint. At time of writing, the |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
223 partition strategy in worker.py seems favorable to this. We also sort the |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
224 items by ascending revision number to match the order in which we commit |
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
225 the fixes later. |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
226 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
227 workqueue = [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
228 numitems = collections.defaultdict(int) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
229 maxfilesize = ui.configbytes('fix', 'maxfilesize') |
38536
5ffe2041d427
fix: use a worker pool to parallelize running tools
Danny Hooper <hooper@google.com>
parents:
38423
diff
changeset
|
230 for rev in sorted(revstofix): |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
231 fixctx = repo[rev] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
232 match = scmutil.match(fixctx, pats, opts) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
233 for path in pathstofix(ui, repo, pats, opts, match, basectxs[rev], |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
234 fixctx): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
235 if path not in fixctx: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
236 continue |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
237 fctx = fixctx[path] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
238 if fctx.islink(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
239 continue |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
240 if fctx.size() > maxfilesize: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
241 ui.warn(_('ignoring file larger than %s: %s\n') % |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
242 (util.bytecount(maxfilesize), path)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
243 continue |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
244 workqueue.append((rev, path)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
245 numitems[rev] += 1 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
246 return workqueue, numitems |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
247 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
248 def getrevstofix(ui, repo, opts): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
249 """Returns the set of revision numbers that should be fixed""" |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
250 revs = set(scmutil.revrange(repo, opts['rev'])) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
251 for rev in revs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
252 checkfixablectx(ui, repo, repo[rev]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
253 if revs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
254 cmdutil.checkunfinished(repo) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
255 checknodescendants(repo, revs) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
256 if opts.get('working_dir'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
257 revs.add(wdirrev) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
258 if list(merge.mergestate.read(repo).unresolved()): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
259 raise error.Abort('unresolved conflicts', hint="use 'hg resolve'") |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
260 if not revs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
261 raise error.Abort( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
262 'no changesets specified', hint='use --rev or --working-dir') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
263 return revs |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
264 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
265 def checknodescendants(repo, revs): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
266 if (not obsolete.isenabled(repo, obsolete.allowunstableopt) and |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
267 repo.revs('(%ld::) - (%ld)', revs, revs)): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
268 raise error.Abort(_('can only fix a changeset together ' |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
269 'with all its descendants')) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
270 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
271 def checkfixablectx(ui, repo, ctx): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
272 """Aborts if the revision shouldn't be replaced with a fixed one.""" |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
273 if not ctx.mutable(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
274 raise error.Abort('can\'t fix immutable changeset %s' % |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
275 (scmutil.formatchangeid(ctx),)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
276 if ctx.obsolete(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
277 # It would be better to actually check if the revision has a successor. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
278 allowdivergence = ui.configbool('experimental', |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
279 'evolution.allowdivergence') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
280 if not allowdivergence: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
281 raise error.Abort('fixing obsolete revision could cause divergence') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
282 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
283 def pathstofix(ui, repo, pats, opts, match, basectxs, fixctx): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
284 """Returns the set of files that should be fixed in a context |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
285 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
286 The result depends on the base contexts; we include any file that has |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
287 changed relative to any of the base contexts. Base contexts should be |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
288 ancestors of the context being fixed. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
289 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
290 files = set() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
291 for basectx in basectxs: |
38770
260c17eaf3f7
fix: use ctx1.status(ctx2) instead of repo.status(ctx1, ctx2)
Martin von Zweigbergk <martinvonz@google.com>
parents:
38590
diff
changeset
|
292 stat = basectx.status(fixctx, match=match, listclean=bool(pats), |
260c17eaf3f7
fix: use ctx1.status(ctx2) instead of repo.status(ctx1, ctx2)
Martin von Zweigbergk <martinvonz@google.com>
parents:
38590
diff
changeset
|
293 listunknown=bool(pats)) |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
294 files.update( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
295 set(itertools.chain(stat.added, stat.modified, stat.clean, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
296 stat.unknown))) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
297 return files |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
298 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
299 def lineranges(opts, path, basectxs, fixctx, content2): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
300 """Returns the set of line ranges that should be fixed in a file |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
301 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
302 Of the form [(10, 20), (30, 40)]. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
303 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
304 This depends on the given base contexts; we must consider lines that have |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
305 changed versus any of the base contexts, and whether the file has been |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
306 renamed versus any of them. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
307 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
308 Another way to understand this is that we exclude line ranges that are |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
309 common to the file in all base contexts. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
310 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
311 if opts.get('whole'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
312 # Return a range containing all lines. Rely on the diff implementation's |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
313 # idea of how many lines are in the file, instead of reimplementing it. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
314 return difflineranges('', content2) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
315 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
316 rangeslist = [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
317 for basectx in basectxs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
318 basepath = copies.pathcopies(basectx, fixctx).get(path, path) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
319 if basepath in basectx: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
320 content1 = basectx[basepath].data() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
321 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
322 content1 = '' |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
323 rangeslist.extend(difflineranges(content1, content2)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
324 return unionranges(rangeslist) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
325 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
326 def unionranges(rangeslist): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
327 """Return the union of some closed intervals |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
328 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
329 >>> unionranges([]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
330 [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
331 >>> unionranges([(1, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
332 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
333 >>> unionranges([(1, 100), (1, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
334 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
335 >>> unionranges([(1, 100), (2, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
336 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
337 >>> unionranges([(1, 99), (1, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
338 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
339 >>> unionranges([(1, 100), (40, 60)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
340 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
341 >>> unionranges([(1, 49), (50, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
342 [(1, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
343 >>> unionranges([(1, 48), (50, 100)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
344 [(1, 48), (50, 100)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
345 >>> unionranges([(1, 2), (3, 4), (5, 6)]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
346 [(1, 6)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
347 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
348 rangeslist = sorted(set(rangeslist)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
349 unioned = [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
350 if rangeslist: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
351 unioned, rangeslist = [rangeslist[0]], rangeslist[1:] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
352 for a, b in rangeslist: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
353 c, d = unioned[-1] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
354 if a > d + 1: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
355 unioned.append((a, b)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
356 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
357 unioned[-1] = (c, max(b, d)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
358 return unioned |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
359 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
360 def difflineranges(content1, content2): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
361 """Return list of line number ranges in content2 that differ from content1. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
362 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
363 Line numbers are 1-based. The numbers are the first and last line contained |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
364 in the range. Single-line ranges have the same line number for the first and |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
365 last line. Excludes any empty ranges that result from lines that are only |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
366 present in content1. Relies on mdiff's idea of where the line endings are in |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
367 the string. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
368 |
37213
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
369 >>> from mercurial import pycompat |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
370 >>> lines = lambda s: b'\\n'.join([c for c in pycompat.iterbytestr(s)]) |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
371 >>> difflineranges2 = lambda a, b: difflineranges(lines(a), lines(b)) |
37213
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
372 >>> difflineranges2(b'', b'') |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
373 [] |
37213
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
374 >>> difflineranges2(b'a', b'') |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
375 [] |
37213
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
376 >>> difflineranges2(b'', b'A') |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
377 [(1, 1)] |
37213
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
378 >>> difflineranges2(b'a', b'a') |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
379 [] |
37213
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
380 >>> difflineranges2(b'a', b'A') |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
381 [(1, 1)] |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
382 >>> difflineranges2(b'ab', b'') |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
383 [] |
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
384 >>> difflineranges2(b'', b'AB') |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
385 [(1, 2)] |
37213
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
386 >>> difflineranges2(b'abc', b'ac') |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
387 [] |
37213
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
388 >>> difflineranges2(b'ab', b'aCb') |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
389 [(2, 2)] |
37213
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
390 >>> difflineranges2(b'abc', b'aBc') |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
391 [(2, 2)] |
37213
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
392 >>> difflineranges2(b'ab', b'AB') |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
393 [(1, 2)] |
37213
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
394 >>> difflineranges2(b'abcde', b'aBcDe') |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
395 [(2, 2), (4, 4)] |
37213
893ff8c3bc57
py3: fix fix doctests to be bytes-safe
Yuya Nishihara <yuya@tcha.org>
parents:
37207
diff
changeset
|
396 >>> difflineranges2(b'abcde', b'aBCDe') |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
397 [(2, 4)] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
398 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
399 ranges = [] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
400 for lines, kind in mdiff.allblocks(content1, content2): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
401 firstline, lastline = lines[2:4] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
402 if kind == '!' and firstline != lastline: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
403 ranges.append((firstline + 1, lastline)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
404 return ranges |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
405 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
406 def getbasectxs(repo, opts, revstofix): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
407 """Returns a map of the base contexts for each revision |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
408 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
409 The base contexts determine which lines are considered modified when we |
38590
f068495a1c28
fix: add test case that shows why --whole with --base is useful
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
410 attempt to fix just the modified lines in a file. It also determines which |
f068495a1c28
fix: add test case that shows why --whole with --base is useful
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
411 files we attempt to fix, so it is important to compute this even when |
f068495a1c28
fix: add test case that shows why --whole with --base is useful
Danny Hooper <hooper@google.com>
parents:
38537
diff
changeset
|
412 --whole is used. |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
413 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
414 # The --base flag overrides the usual logic, and we give every revision |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
415 # exactly the set of baserevs that the user specified. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
416 if opts.get('base'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
417 baserevs = set(scmutil.revrange(repo, opts.get('base'))) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
418 if not baserevs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
419 baserevs = {nullrev} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
420 basectxs = {repo[rev] for rev in baserevs} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
421 return {rev: basectxs for rev in revstofix} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
422 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
423 # Proceed in topological order so that we can easily determine each |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
424 # revision's baserevs by looking at its parents and their baserevs. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
425 basectxs = collections.defaultdict(set) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
426 for rev in sorted(revstofix): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
427 ctx = repo[rev] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
428 for pctx in ctx.parents(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
429 if pctx.rev() in basectxs: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
430 basectxs[rev].update(basectxs[pctx.rev()]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
431 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
432 basectxs[rev].add(pctx) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
433 return basectxs |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
434 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
435 def fixfile(ui, opts, fixers, fixctx, path, basectxs): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
436 """Run any configured fixers that should affect the file in this context |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
437 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
438 Returns the file content that results from applying the fixers in some order |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
439 starting with the file's content in the fixctx. Fixers that support line |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
440 ranges will affect lines that have changed relative to any of the basectxs |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
441 (i.e. they will only avoid lines that are common to all basectxs). |
38967
a009589cd32a
fix: determine fixer tool failure by exit code instead of stderr
Danny Hooper <hooper@google.com>
parents:
38950
diff
changeset
|
442 |
a009589cd32a
fix: determine fixer tool failure by exit code instead of stderr
Danny Hooper <hooper@google.com>
parents:
38950
diff
changeset
|
443 A fixer tool's stdout will become the file's new content if and only if it |
a009589cd32a
fix: determine fixer tool failure by exit code instead of stderr
Danny Hooper <hooper@google.com>
parents:
38950
diff
changeset
|
444 exits with code zero. |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
445 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
446 newdata = fixctx[path].data() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
447 for fixername, fixer in fixers.iteritems(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
448 if fixer.affects(opts, fixctx, path): |
38860
257c9846b532
fix: compute changed lines lazily to make whole-file fixer tools faster
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
449 rangesfn = lambda: lineranges(opts, path, basectxs, fixctx, newdata) |
257c9846b532
fix: compute changed lines lazily to make whole-file fixer tools faster
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
450 command = fixer.command(ui, path, rangesfn) |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
451 if command is None: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
452 continue |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
453 ui.debug('subprocess: %s\n' % (command,)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
454 proc = subprocess.Popen( |
39836
f1d6021453c2
py3: remove a couple of superfluous calls to pycompat.rapply()
Matt Harbison <matt_harbison@yahoo.com>
parents:
39826
diff
changeset
|
455 procutil.tonativestr(command), |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
456 shell=True, |
39826
c31ce080eb75
py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents:
38967
diff
changeset
|
457 cwd=procutil.tonativestr(b'/'), |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
458 stdin=subprocess.PIPE, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
459 stdout=subprocess.PIPE, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
460 stderr=subprocess.PIPE) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
461 newerdata, stderr = proc.communicate(newdata) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
462 if stderr: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
463 showstderr(ui, fixctx.rev(), fixername, stderr) |
38967
a009589cd32a
fix: determine fixer tool failure by exit code instead of stderr
Danny Hooper <hooper@google.com>
parents:
38950
diff
changeset
|
464 if proc.returncode == 0: |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
465 newdata = newerdata |
38967
a009589cd32a
fix: determine fixer tool failure by exit code instead of stderr
Danny Hooper <hooper@google.com>
parents:
38950
diff
changeset
|
466 elif not stderr: |
a009589cd32a
fix: determine fixer tool failure by exit code instead of stderr
Danny Hooper <hooper@google.com>
parents:
38950
diff
changeset
|
467 showstderr(ui, fixctx.rev(), fixername, |
a009589cd32a
fix: determine fixer tool failure by exit code instead of stderr
Danny Hooper <hooper@google.com>
parents:
38950
diff
changeset
|
468 _('exited with status %d\n') % (proc.returncode,)) |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
469 return newdata |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
470 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
471 def showstderr(ui, rev, fixername, stderr): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
472 """Writes the lines of the stderr string as warnings on the ui |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
473 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
474 Uses the revision number and fixername to give more context to each line of |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
475 the error message. Doesn't include file names, since those take up a lot of |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
476 space and would tend to be included in the error message if they were |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
477 relevant. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
478 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
479 for line in re.split('[\r\n]+', stderr): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
480 if line: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
481 ui.warn(('[')) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
482 if rev is None: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
483 ui.warn(_('wdir'), label='evolve.rev') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
484 else: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
485 ui.warn((str(rev)), label='evolve.rev') |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
486 ui.warn(('] %s: %s\n') % (fixername, line)) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
487 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
488 def writeworkingdir(repo, ctx, filedata, replacements): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
489 """Write new content to the working copy and check out the new p1 if any |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
490 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
491 We check out a new revision if and only if we fixed something in both the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
492 working directory and its parent revision. This avoids the need for a full |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
493 update/merge, and means that the working directory simply isn't affected |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
494 unless the --working-dir flag is given. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
495 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
496 Directly updates the dirstate for the affected files. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
497 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
498 for path, data in filedata.iteritems(): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
499 fctx = ctx[path] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
500 fctx.write(data, fctx.flags()) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
501 if repo.dirstate[path] == 'n': |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
502 repo.dirstate.normallookup(path) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
503 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
504 oldparentnodes = repo.dirstate.parents() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
505 newparentnodes = [replacements.get(n, n) for n in oldparentnodes] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
506 if newparentnodes != oldparentnodes: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
507 repo.setparents(*newparentnodes) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
508 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
509 def replacerev(ui, repo, ctx, filedata, replacements): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
510 """Commit a new revision like the given one, but with file content changes |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
511 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
512 "ctx" is the original revision to be replaced by a modified one. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
513 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
514 "filedata" is a dict that maps paths to their new file content. All other |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
515 paths will be recreated from the original revision without changes. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
516 "filedata" may contain paths that didn't exist in the original revision; |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
517 they will be added. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
518 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
519 "replacements" is a dict that maps a single node to a single node, and it is |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
520 updated to indicate the original revision is replaced by the newly created |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
521 one. No entry is added if the replacement's node already exists. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
522 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
523 The new revision has the same parents as the old one, unless those parents |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
524 have already been replaced, in which case those replacements are the parents |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
525 of this new revision. Thus, if revisions are replaced in topological order, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
526 there is no need to rebase them into the original topology later. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
527 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
528 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
529 p1rev, p2rev = repo.changelog.parentrevs(ctx.rev()) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
530 p1ctx, p2ctx = repo[p1rev], repo[p2rev] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
531 newp1node = replacements.get(p1ctx.node(), p1ctx.node()) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
532 newp2node = replacements.get(p2ctx.node(), p2ctx.node()) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
533 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
534 def filectxfn(repo, memctx, path): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
535 if path not in ctx: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
536 return None |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
537 fctx = ctx[path] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
538 copied = fctx.renamed() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
539 if copied: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
540 copied = copied[0] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
541 return context.memfilectx( |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
542 repo, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
543 memctx, |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
544 path=fctx.path(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
545 data=filedata.get(path, fctx.data()), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
546 islink=fctx.islink(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
547 isexec=fctx.isexec(), |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
548 copied=copied) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
549 |
38423
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
550 memctx = context.memctx( |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
551 repo, |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
552 parents=(newp1node, newp2node), |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
553 text=ctx.description(), |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
554 files=set(ctx.files()) | set(filedata.keys()), |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
555 filectxfn=filectxfn, |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
556 user=ctx.user(), |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
557 date=ctx.date(), |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
558 extra=ctx.extra(), |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
559 branch=ctx.branch(), |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
560 editor=None) |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
561 sucnode = memctx.commit() |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
562 prenode = ctx.node() |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
563 if prenode == sucnode: |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
564 ui.debug('node %s already existed\n' % (ctx.hex())) |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
565 else: |
32fba6fe893d
scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents:
38420
diff
changeset
|
566 replacements[ctx.node()] = sucnode |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
567 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
568 def getfixers(ui): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
569 """Returns a map of configured fixer tools indexed by their names |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
570 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
571 Each value is a Fixer object with methods that implement the behavior of the |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
572 fixer's config suboptions. Does not validate the config values. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
573 """ |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
574 result = {} |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
575 for name in fixernames(ui): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
576 result[name] = Fixer() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
577 attrs = ui.configsuboptions('fix', name)[1] |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
578 for key in FIXER_ATTRS: |
37618
1edf3738e000
fix: port most of the way to python 3
Augie Fackler <augie@google.com>
parents:
37595
diff
changeset
|
579 setattr(result[name], pycompat.sysstr('_' + key), |
1edf3738e000
fix: port most of the way to python 3
Augie Fackler <augie@google.com>
parents:
37595
diff
changeset
|
580 attrs.get(key, '')) |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
581 return result |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
582 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
583 def fixernames(ui): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
584 """Returns the names of [fix] config options that have suboptions""" |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
585 names = set() |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
586 for k, v in ui.configitems('fix'): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
587 if ':' in k: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
588 names.add(k.split(':', 1)[0]) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
589 return names |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
590 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
591 class Fixer(object): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
592 """Wraps the raw config values for a fixer with methods""" |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
593 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
594 def affects(self, opts, fixctx, path): |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
595 """Should this fixer run on the file at the given path and context?""" |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
596 return scmutil.match(fixctx, [self._fileset], opts)(path) |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
597 |
38860
257c9846b532
fix: compute changed lines lazily to make whole-file fixer tools faster
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
598 def command(self, ui, path, rangesfn): |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
599 """A shell command to use to invoke this fixer on the given file/lines |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
600 |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
601 May return None if there is no appropriate command to run for the given |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
602 parameters. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
603 """ |
37774
d6970628b95f
fix: use templater to substitute values in command string
Yuya Nishihara <yuya@tcha.org>
parents:
37618
diff
changeset
|
604 expand = cmdutil.rendercommandtemplate |
d6970628b95f
fix: use templater to substitute values in command string
Yuya Nishihara <yuya@tcha.org>
parents:
37618
diff
changeset
|
605 parts = [expand(ui, self._command, |
d6970628b95f
fix: use templater to substitute values in command string
Yuya Nishihara <yuya@tcha.org>
parents:
37618
diff
changeset
|
606 {'rootpath': path, 'basename': os.path.basename(path)})] |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
607 if self._linerange: |
38860
257c9846b532
fix: compute changed lines lazily to make whole-file fixer tools faster
Danny Hooper <hooper@google.com>
parents:
38811
diff
changeset
|
608 ranges = rangesfn() |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
609 if not ranges: |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
610 # No line ranges to fix, so don't run the fixer. |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
611 return None |
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
612 for first, last in ranges: |
37774
d6970628b95f
fix: use templater to substitute values in command string
Yuya Nishihara <yuya@tcha.org>
parents:
37618
diff
changeset
|
613 parts.append(expand(ui, self._linerange, |
d6970628b95f
fix: use templater to substitute values in command string
Yuya Nishihara <yuya@tcha.org>
parents:
37618
diff
changeset
|
614 {'first': first, 'last': last})) |
37183
ded5ea279a93
fix: new extension for automatically modifying file contents
Danny Hooper <hooper@google.com>
parents:
diff
changeset
|
615 return ' '.join(parts) |