##// END OF EJS Templates
tests: demonstrate bug in `hg fix` with incorrectly dirty working copy...
Martin von Zweigbergk -
r48565:184d83ef stable
parent child Browse files
Show More
@@ -1,1695 +1,1716
1 A script that implements uppercasing of specific lines in a file. This
1 A script that implements uppercasing of specific lines in a file. This
2 approximates the behavior of code formatters well enough for our tests.
2 approximates the behavior of code formatters well enough for our tests.
3
3
4 $ UPPERCASEPY="$TESTTMP/uppercase.py"
4 $ UPPERCASEPY="$TESTTMP/uppercase.py"
5 $ cat > $UPPERCASEPY <<EOF
5 $ cat > $UPPERCASEPY <<EOF
6 > import re
6 > import sys
7 > import sys
7 > from mercurial.utils.procutil import setbinary
8 > from mercurial.utils.procutil import setbinary
8 > setbinary(sys.stdin)
9 > setbinary(sys.stdin)
9 > setbinary(sys.stdout)
10 > setbinary(sys.stdout)
10 > stdin = getattr(sys.stdin, 'buffer', sys.stdin)
11 > stdin = getattr(sys.stdin, 'buffer', sys.stdin)
11 > stdout = getattr(sys.stdout, 'buffer', sys.stdout)
12 > stdout = getattr(sys.stdout, 'buffer', sys.stdout)
12 > lines = set()
13 > lines = set()
14 > def format(text):
15 > return re.sub(b' +', b' ', text.upper())
13 > for arg in sys.argv[1:]:
16 > for arg in sys.argv[1:]:
14 > if arg == 'all':
17 > if arg == 'all':
15 > stdout.write(stdin.read().upper())
18 > stdout.write(format(stdin.read()))
16 > sys.exit(0)
19 > sys.exit(0)
17 > else:
20 > else:
18 > first, last = arg.split('-')
21 > first, last = arg.split('-')
19 > lines.update(range(int(first), int(last) + 1))
22 > lines.update(range(int(first), int(last) + 1))
20 > for i, line in enumerate(stdin.readlines()):
23 > for i, line in enumerate(stdin.readlines()):
21 > if i + 1 in lines:
24 > if i + 1 in lines:
22 > stdout.write(line.upper())
25 > stdout.write(format(line))
23 > else:
26 > else:
24 > stdout.write(line)
27 > stdout.write(line)
25 > EOF
28 > EOF
26 $ TESTLINES="foo\nbar\nbaz\nqux\n"
29 $ TESTLINES="foo\nbar\nbaz\nqux\n"
27 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY
30 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY
28 foo
31 foo
29 bar
32 bar
30 baz
33 baz
31 qux
34 qux
32 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY all
35 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY all
33 FOO
36 FOO
34 BAR
37 BAR
35 BAZ
38 BAZ
36 QUX
39 QUX
37 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 1-1
40 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 1-1
38 FOO
41 FOO
39 bar
42 bar
40 baz
43 baz
41 qux
44 qux
42 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 1-2
45 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 1-2
43 FOO
46 FOO
44 BAR
47 BAR
45 baz
48 baz
46 qux
49 qux
47 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 2-3
50 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 2-3
48 foo
51 foo
49 BAR
52 BAR
50 BAZ
53 BAZ
51 qux
54 qux
52 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 2-2 4-4
55 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 2-2 4-4
53 foo
56 foo
54 BAR
57 BAR
55 baz
58 baz
56 QUX
59 QUX
57
60
58 Set up the config with two simple fixers: one that fixes specific line ranges,
61 Set up the config with two simple fixers: one that fixes specific line ranges,
59 and one that always fixes the whole file. They both "fix" files by converting
62 and one that always fixes the whole file. They both "fix" files by converting
60 letters to uppercase. They use different file extensions, so each test case can
63 letters to uppercase. They use different file extensions, so each test case can
61 choose which behavior to use by naming files.
64 choose which behavior to use by naming files.
62
65
63 $ cat >> $HGRCPATH <<EOF
66 $ cat >> $HGRCPATH <<EOF
64 > [extensions]
67 > [extensions]
65 > fix =
68 > fix =
66 > [experimental]
69 > [experimental]
67 > evolution.createmarkers=True
70 > evolution.createmarkers=True
68 > evolution.allowunstable=True
71 > evolution.allowunstable=True
69 > [fix]
72 > [fix]
70 > uppercase-whole-file:command="$PYTHON" $UPPERCASEPY all
73 > uppercase-whole-file:command="$PYTHON" $UPPERCASEPY all
71 > uppercase-whole-file:pattern=set:**.whole
74 > uppercase-whole-file:pattern=set:**.whole
72 > uppercase-changed-lines:command="$PYTHON" $UPPERCASEPY
75 > uppercase-changed-lines:command="$PYTHON" $UPPERCASEPY
73 > uppercase-changed-lines:linerange={first}-{last}
76 > uppercase-changed-lines:linerange={first}-{last}
74 > uppercase-changed-lines:pattern=set:**.changed
77 > uppercase-changed-lines:pattern=set:**.changed
75 > EOF
78 > EOF
76
79
77 Help text for fix.
80 Help text for fix.
78
81
79 $ hg help fix
82 $ hg help fix
80 hg fix [OPTION]... [FILE]...
83 hg fix [OPTION]... [FILE]...
81
84
82 rewrite file content in changesets or working directory
85 rewrite file content in changesets or working directory
83
86
84 Runs any configured tools to fix the content of files. Only affects files
87 Runs any configured tools to fix the content of files. Only affects files
85 with changes, unless file arguments are provided. Only affects changed
88 with changes, unless file arguments are provided. Only affects changed
86 lines of files, unless the --whole flag is used. Some tools may always
89 lines of files, unless the --whole flag is used. Some tools may always
87 affect the whole file regardless of --whole.
90 affect the whole file regardless of --whole.
88
91
89 If --working-dir is used, files with uncommitted changes in the working
92 If --working-dir is used, files with uncommitted changes in the working
90 copy will be fixed. Note that no backup are made.
93 copy will be fixed. Note that no backup are made.
91
94
92 If revisions are specified with --source, those revisions and their
95 If revisions are specified with --source, those revisions and their
93 descendants will be checked, and they may be replaced with new revisions
96 descendants will be checked, and they may be replaced with new revisions
94 that have fixed file content. By automatically including the descendants,
97 that have fixed file content. By automatically including the descendants,
95 no merging, rebasing, or evolution will be required. If an ancestor of the
98 no merging, rebasing, or evolution will be required. If an ancestor of the
96 working copy is included, then the working copy itself will also be fixed,
99 working copy is included, then the working copy itself will also be fixed,
97 and the working copy will be updated to the fixed parent.
100 and the working copy will be updated to the fixed parent.
98
101
99 When determining what lines of each file to fix at each revision, the
102 When determining what lines of each file to fix at each revision, the
100 whole set of revisions being fixed is considered, so that fixes to earlier
103 whole set of revisions being fixed is considered, so that fixes to earlier
101 revisions are not forgotten in later ones. The --base flag can be used to
104 revisions are not forgotten in later ones. The --base flag can be used to
102 override this default behavior, though it is not usually desirable to do
105 override this default behavior, though it is not usually desirable to do
103 so.
106 so.
104
107
105 (use 'hg help -e fix' to show help for the fix extension)
108 (use 'hg help -e fix' to show help for the fix extension)
106
109
107 options ([+] can be repeated):
110 options ([+] can be repeated):
108
111
109 --all fix all non-public non-obsolete revisions
112 --all fix all non-public non-obsolete revisions
110 --base REV [+] revisions to diff against (overrides automatic selection,
113 --base REV [+] revisions to diff against (overrides automatic selection,
111 and applies to every revision being fixed)
114 and applies to every revision being fixed)
112 -s --source REV [+] fix the specified revisions and their descendants
115 -s --source REV [+] fix the specified revisions and their descendants
113 -w --working-dir fix the working directory
116 -w --working-dir fix the working directory
114 --whole always fix every line of a file
117 --whole always fix every line of a file
115
118
116 (some details hidden, use --verbose to show complete help)
119 (some details hidden, use --verbose to show complete help)
117
120
118 $ hg help -e fix
121 $ hg help -e fix
119 fix extension - rewrite file content in changesets or working copy
122 fix extension - rewrite file content in changesets or working copy
120 (EXPERIMENTAL)
123 (EXPERIMENTAL)
121
124
122 Provides a command that runs configured tools on the contents of modified
125 Provides a command that runs configured tools on the contents of modified
123 files, writing back any fixes to the working copy or replacing changesets.
126 files, writing back any fixes to the working copy or replacing changesets.
124
127
125 Here is an example configuration that causes 'hg fix' to apply automatic
128 Here is an example configuration that causes 'hg fix' to apply automatic
126 formatting fixes to modified lines in C++ code:
129 formatting fixes to modified lines in C++ code:
127
130
128 [fix]
131 [fix]
129 clang-format:command=clang-format --assume-filename={rootpath}
132 clang-format:command=clang-format --assume-filename={rootpath}
130 clang-format:linerange=--lines={first}:{last}
133 clang-format:linerange=--lines={first}:{last}
131 clang-format:pattern=set:**.cpp or **.hpp
134 clang-format:pattern=set:**.cpp or **.hpp
132
135
133 The :command suboption forms the first part of the shell command that will be
136 The :command suboption forms the first part of the shell command that will be
134 used to fix a file. The content of the file is passed on standard input, and
137 used to fix a file. The content of the file is passed on standard input, and
135 the fixed file content is expected on standard output. Any output on standard
138 the fixed file content is expected on standard output. Any output on standard
136 error will be displayed as a warning. If the exit status is not zero, the file
139 error will be displayed as a warning. If the exit status is not zero, the file
137 will not be affected. A placeholder warning is displayed if there is a non-
140 will not be affected. A placeholder warning is displayed if there is a non-
138 zero exit status but no standard error output. Some values may be substituted
141 zero exit status but no standard error output. Some values may be substituted
139 into the command:
142 into the command:
140
143
141 {rootpath} The path of the file being fixed, relative to the repo root
144 {rootpath} The path of the file being fixed, relative to the repo root
142 {basename} The name of the file being fixed, without the directory path
145 {basename} The name of the file being fixed, without the directory path
143
146
144 If the :linerange suboption is set, the tool will only be run if there are
147 If the :linerange suboption is set, the tool will only be run if there are
145 changed lines in a file. The value of this suboption is appended to the shell
148 changed lines in a file. The value of this suboption is appended to the shell
146 command once for every range of changed lines in the file. Some values may be
149 command once for every range of changed lines in the file. Some values may be
147 substituted into the command:
150 substituted into the command:
148
151
149 {first} The 1-based line number of the first line in the modified range
152 {first} The 1-based line number of the first line in the modified range
150 {last} The 1-based line number of the last line in the modified range
153 {last} The 1-based line number of the last line in the modified range
151
154
152 Deleted sections of a file will be ignored by :linerange, because there is no
155 Deleted sections of a file will be ignored by :linerange, because there is no
153 corresponding line range in the version being fixed.
156 corresponding line range in the version being fixed.
154
157
155 By default, tools that set :linerange will only be executed if there is at
158 By default, tools that set :linerange will only be executed if there is at
156 least one changed line range. This is meant to prevent accidents like running
159 least one changed line range. This is meant to prevent accidents like running
157 a code formatter in such a way that it unexpectedly reformats the whole file.
160 a code formatter in such a way that it unexpectedly reformats the whole file.
158 If such a tool needs to operate on unchanged files, it should set the
161 If such a tool needs to operate on unchanged files, it should set the
159 :skipclean suboption to false.
162 :skipclean suboption to false.
160
163
161 The :pattern suboption determines which files will be passed through each
164 The :pattern suboption determines which files will be passed through each
162 configured tool. See 'hg help patterns' for possible values. However, all
165 configured tool. See 'hg help patterns' for possible values. However, all
163 patterns are relative to the repo root, even if that text says they are
166 patterns are relative to the repo root, even if that text says they are
164 relative to the current working directory. If there are file arguments to 'hg
167 relative to the current working directory. If there are file arguments to 'hg
165 fix', the intersection of these patterns is used.
168 fix', the intersection of these patterns is used.
166
169
167 There is also a configurable limit for the maximum size of file that will be
170 There is also a configurable limit for the maximum size of file that will be
168 processed by 'hg fix':
171 processed by 'hg fix':
169
172
170 [fix]
173 [fix]
171 maxfilesize = 2MB
174 maxfilesize = 2MB
172
175
173 Normally, execution of configured tools will continue after a failure
176 Normally, execution of configured tools will continue after a failure
174 (indicated by a non-zero exit status). It can also be configured to abort
177 (indicated by a non-zero exit status). It can also be configured to abort
175 after the first such failure, so that no files will be affected if any tool
178 after the first such failure, so that no files will be affected if any tool
176 fails. This abort will also cause 'hg fix' to exit with a non-zero status:
179 fails. This abort will also cause 'hg fix' to exit with a non-zero status:
177
180
178 [fix]
181 [fix]
179 failure = abort
182 failure = abort
180
183
181 When multiple tools are configured to affect a file, they execute in an order
184 When multiple tools are configured to affect a file, they execute in an order
182 defined by the :priority suboption. The priority suboption has a default value
185 defined by the :priority suboption. The priority suboption has a default value
183 of zero for each tool. Tools are executed in order of descending priority. The
186 of zero for each tool. Tools are executed in order of descending priority. The
184 execution order of tools with equal priority is unspecified. For example, you
187 execution order of tools with equal priority is unspecified. For example, you
185 could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers
188 could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers
186 in a text file by ensuring that 'sort' runs before 'head':
189 in a text file by ensuring that 'sort' runs before 'head':
187
190
188 [fix]
191 [fix]
189 sort:command = sort -n
192 sort:command = sort -n
190 head:command = head -n 10
193 head:command = head -n 10
191 sort:pattern = numbers.txt
194 sort:pattern = numbers.txt
192 head:pattern = numbers.txt
195 head:pattern = numbers.txt
193 sort:priority = 2
196 sort:priority = 2
194 head:priority = 1
197 head:priority = 1
195
198
196 To account for changes made by each tool, the line numbers used for
199 To account for changes made by each tool, the line numbers used for
197 incremental formatting are recomputed before executing the next tool. So, each
200 incremental formatting are recomputed before executing the next tool. So, each
198 tool may see different values for the arguments added by the :linerange
201 tool may see different values for the arguments added by the :linerange
199 suboption.
202 suboption.
200
203
201 Each fixer tool is allowed to return some metadata in addition to the fixed
204 Each fixer tool is allowed to return some metadata in addition to the fixed
202 file content. The metadata must be placed before the file content on stdout,
205 file content. The metadata must be placed before the file content on stdout,
203 separated from the file content by a zero byte. The metadata is parsed as a
206 separated from the file content by a zero byte. The metadata is parsed as a
204 JSON value (so, it should be UTF-8 encoded and contain no zero bytes). A fixer
207 JSON value (so, it should be UTF-8 encoded and contain no zero bytes). A fixer
205 tool is expected to produce this metadata encoding if and only if the
208 tool is expected to produce this metadata encoding if and only if the
206 :metadata suboption is true:
209 :metadata suboption is true:
207
210
208 [fix]
211 [fix]
209 tool:command = tool --prepend-json-metadata
212 tool:command = tool --prepend-json-metadata
210 tool:metadata = true
213 tool:metadata = true
211
214
212 The metadata values are passed to hooks, which can be used to print summaries
215 The metadata values are passed to hooks, which can be used to print summaries
213 or perform other post-fixing work. The supported hooks are:
216 or perform other post-fixing work. The supported hooks are:
214
217
215 "postfixfile"
218 "postfixfile"
216 Run once for each file in each revision where any fixer tools made changes
219 Run once for each file in each revision where any fixer tools made changes
217 to the file content. Provides "$HG_REV" and "$HG_PATH" to identify the file,
220 to the file content. Provides "$HG_REV" and "$HG_PATH" to identify the file,
218 and "$HG_METADATA" with a map of fixer names to metadata values from fixer
221 and "$HG_METADATA" with a map of fixer names to metadata values from fixer
219 tools that affected the file. Fixer tools that didn't affect the file have a
222 tools that affected the file. Fixer tools that didn't affect the file have a
220 value of None. Only fixer tools that executed are present in the metadata.
223 value of None. Only fixer tools that executed are present in the metadata.
221
224
222 "postfix"
225 "postfix"
223 Run once after all files and revisions have been handled. Provides
226 Run once after all files and revisions have been handled. Provides
224 "$HG_REPLACEMENTS" with information about what revisions were created and
227 "$HG_REPLACEMENTS" with information about what revisions were created and
225 made obsolete. Provides a boolean "$HG_WDIRWRITTEN" to indicate whether any
228 made obsolete. Provides a boolean "$HG_WDIRWRITTEN" to indicate whether any
226 files in the working copy were updated. Provides a list "$HG_METADATA"
229 files in the working copy were updated. Provides a list "$HG_METADATA"
227 mapping fixer tool names to lists of metadata values returned from
230 mapping fixer tool names to lists of metadata values returned from
228 executions that modified a file. This aggregates the same metadata
231 executions that modified a file. This aggregates the same metadata
229 previously passed to the "postfixfile" hook.
232 previously passed to the "postfixfile" hook.
230
233
231 Fixer tools are run in the repository's root directory. This allows them to
234 Fixer tools are run in the repository's root directory. This allows them to
232 read configuration files from the working copy, or even write to the working
235 read configuration files from the working copy, or even write to the working
233 copy. The working copy is not updated to match the revision being fixed. In
236 copy. The working copy is not updated to match the revision being fixed. In
234 fact, several revisions may be fixed in parallel. Writes to the working copy
237 fact, several revisions may be fixed in parallel. Writes to the working copy
235 are not amended into the revision being fixed; fixer tools should always write
238 are not amended into the revision being fixed; fixer tools should always write
236 fixed file content back to stdout as documented above.
239 fixed file content back to stdout as documented above.
237
240
238 list of commands:
241 list of commands:
239
242
240 fix rewrite file content in changesets or working directory
243 fix rewrite file content in changesets or working directory
241
244
242 (use 'hg help -v -e fix' to show built-in aliases and global options)
245 (use 'hg help -v -e fix' to show built-in aliases and global options)
243
246
244 There is no default behavior in the absence of --rev and --working-dir.
247 There is no default behavior in the absence of --rev and --working-dir.
245
248
246 $ hg init badusage
249 $ hg init badusage
247 $ cd badusage
250 $ cd badusage
248
251
249 $ hg fix
252 $ hg fix
250 abort: no changesets specified
253 abort: no changesets specified
251 (use --source or --working-dir)
254 (use --source or --working-dir)
252 [255]
255 [255]
253 $ hg fix --whole
256 $ hg fix --whole
254 abort: no changesets specified
257 abort: no changesets specified
255 (use --source or --working-dir)
258 (use --source or --working-dir)
256 [255]
259 [255]
257 $ hg fix --base 0
260 $ hg fix --base 0
258 abort: no changesets specified
261 abort: no changesets specified
259 (use --source or --working-dir)
262 (use --source or --working-dir)
260 [255]
263 [255]
261
264
262 Fixing a public revision isn't allowed. It should abort early enough that
265 Fixing a public revision isn't allowed. It should abort early enough that
263 nothing happens, even to the working directory.
266 nothing happens, even to the working directory.
264
267
265 $ printf "hello\n" > hello.whole
268 $ printf "hello\n" > hello.whole
266 $ hg commit -Aqm "hello"
269 $ hg commit -Aqm "hello"
267 $ hg phase -r 0 --public
270 $ hg phase -r 0 --public
268 $ hg fix -r 0
271 $ hg fix -r 0
269 abort: cannot fix public changesets: 6470986d2e7b
272 abort: cannot fix public changesets: 6470986d2e7b
270 (see 'hg help phases' for details)
273 (see 'hg help phases' for details)
271 [10]
274 [10]
272 $ hg fix -r 0 --working-dir
275 $ hg fix -r 0 --working-dir
273 abort: cannot fix public changesets: 6470986d2e7b
276 abort: cannot fix public changesets: 6470986d2e7b
274 (see 'hg help phases' for details)
277 (see 'hg help phases' for details)
275 [10]
278 [10]
276 $ hg cat -r tip hello.whole
279 $ hg cat -r tip hello.whole
277 hello
280 hello
278 $ cat hello.whole
281 $ cat hello.whole
279 hello
282 hello
280
283
281 $ cd ..
284 $ cd ..
282
285
283 Fixing a clean working directory should do nothing. Even the --whole flag
286 Fixing a clean working directory should do nothing. Even the --whole flag
284 shouldn't cause any clean files to be fixed. Specifying a clean file explicitly
287 shouldn't cause any clean files to be fixed. Specifying a clean file explicitly
285 should only fix it if the fixer always fixes the whole file. The combination of
288 should only fix it if the fixer always fixes the whole file. The combination of
286 an explicit filename and --whole should format the entire file regardless.
289 an explicit filename and --whole should format the entire file regardless.
287
290
288 $ hg init fixcleanwdir
291 $ hg init fixcleanwdir
289 $ cd fixcleanwdir
292 $ cd fixcleanwdir
290
293
291 $ printf "hello\n" > hello.changed
294 $ printf "hello\n" > hello.changed
292 $ printf "world\n" > hello.whole
295 $ printf "world\n" > hello.whole
293 $ hg commit -Aqm "foo"
296 $ hg commit -Aqm "foo"
294 $ hg fix --working-dir
297 $ hg fix --working-dir
295 $ hg diff
298 $ hg diff
296 $ hg fix --working-dir --whole
299 $ hg fix --working-dir --whole
297 $ hg diff
300 $ hg diff
298 $ hg fix --working-dir *
301 $ hg fix --working-dir *
299 $ cat *
302 $ cat *
300 hello
303 hello
301 WORLD
304 WORLD
302 $ hg revert --all --no-backup
305 $ hg revert --all --no-backup
303 reverting hello.whole
306 reverting hello.whole
304 $ hg fix --working-dir * --whole
307 $ hg fix --working-dir * --whole
305 $ cat *
308 $ cat *
306 HELLO
309 HELLO
307 WORLD
310 WORLD
308
311
309 The same ideas apply to fixing a revision, so we create a revision that doesn't
312 The same ideas apply to fixing a revision, so we create a revision that doesn't
310 modify either of the files in question and try fixing it. This also tests that
313 modify either of the files in question and try fixing it. This also tests that
311 we ignore a file that doesn't match any configured fixer.
314 we ignore a file that doesn't match any configured fixer.
312
315
313 $ hg revert --all --no-backup
316 $ hg revert --all --no-backup
314 reverting hello.changed
317 reverting hello.changed
315 reverting hello.whole
318 reverting hello.whole
316 $ printf "unimportant\n" > some.file
319 $ printf "unimportant\n" > some.file
317 $ hg commit -Aqm "some other file"
320 $ hg commit -Aqm "some other file"
318
321
319 $ hg fix -r .
322 $ hg fix -r .
320 $ hg cat -r tip *
323 $ hg cat -r tip *
321 hello
324 hello
322 world
325 world
323 unimportant
326 unimportant
324 $ hg fix -r . --whole
327 $ hg fix -r . --whole
325 $ hg cat -r tip *
328 $ hg cat -r tip *
326 hello
329 hello
327 world
330 world
328 unimportant
331 unimportant
329 $ hg fix -r . *
332 $ hg fix -r . *
330 $ hg cat -r tip *
333 $ hg cat -r tip *
331 hello
334 hello
332 WORLD
335 WORLD
333 unimportant
336 unimportant
334 $ hg fix -r . * --whole --config experimental.evolution.allowdivergence=true
337 $ hg fix -r . * --whole --config experimental.evolution.allowdivergence=true
335 2 new content-divergent changesets
338 2 new content-divergent changesets
336 $ hg cat -r tip *
339 $ hg cat -r tip *
337 HELLO
340 HELLO
338 WORLD
341 WORLD
339 unimportant
342 unimportant
340
343
341 $ cd ..
344 $ cd ..
342
345
343 Fixing the working directory should still work if there are no revisions.
346 Fixing the working directory should still work if there are no revisions.
344
347
345 $ hg init norevisions
348 $ hg init norevisions
346 $ cd norevisions
349 $ cd norevisions
347
350
348 $ printf "something\n" > something.whole
351 $ printf "something\n" > something.whole
349 $ hg add
352 $ hg add
350 adding something.whole
353 adding something.whole
351 $ hg fix --working-dir
354 $ hg fix --working-dir
352 $ cat something.whole
355 $ cat something.whole
353 SOMETHING
356 SOMETHING
354
357
355 $ cd ..
358 $ cd ..
356
359
360 Test that the working copy is reported clean if formatting of the parent makes
361 it clean.
362 $ hg init wc-already-formatted
363 $ cd wc-already-formatted
364
365 $ printf "hello world\n" > hello.whole
366 $ hg commit -Am initial
367 adding hello.whole
368 $ hg fix -w *
369 $ hg st
370 M hello.whole
371 $ hg fix -s . *
372 $ hg st
373 M hello.whole (known-bad-output !)
374 $ hg diff
375
376 $ cd ..
377
357 Test the effect of fixing the working directory for each possible status, with
378 Test the effect of fixing the working directory for each possible status, with
358 and without providing explicit file arguments.
379 and without providing explicit file arguments.
359
380
360 $ hg init implicitlyfixstatus
381 $ hg init implicitlyfixstatus
361 $ cd implicitlyfixstatus
382 $ cd implicitlyfixstatus
362
383
363 $ printf "modified\n" > modified.whole
384 $ printf "modified\n" > modified.whole
364 $ printf "removed\n" > removed.whole
385 $ printf "removed\n" > removed.whole
365 $ printf "deleted\n" > deleted.whole
386 $ printf "deleted\n" > deleted.whole
366 $ printf "clean\n" > clean.whole
387 $ printf "clean\n" > clean.whole
367 $ printf "ignored.whole" > .hgignore
388 $ printf "ignored.whole" > .hgignore
368 $ hg commit -Aqm "stuff"
389 $ hg commit -Aqm "stuff"
369
390
370 $ printf "modified!!!\n" > modified.whole
391 $ printf "modified!!!\n" > modified.whole
371 $ printf "unknown\n" > unknown.whole
392 $ printf "unknown\n" > unknown.whole
372 $ printf "ignored\n" > ignored.whole
393 $ printf "ignored\n" > ignored.whole
373 $ printf "added\n" > added.whole
394 $ printf "added\n" > added.whole
374 $ hg add added.whole
395 $ hg add added.whole
375 $ hg remove removed.whole
396 $ hg remove removed.whole
376 $ rm deleted.whole
397 $ rm deleted.whole
377
398
378 $ hg status --all
399 $ hg status --all
379 M modified.whole
400 M modified.whole
380 A added.whole
401 A added.whole
381 R removed.whole
402 R removed.whole
382 ! deleted.whole
403 ! deleted.whole
383 ? unknown.whole
404 ? unknown.whole
384 I ignored.whole
405 I ignored.whole
385 C .hgignore
406 C .hgignore
386 C clean.whole
407 C clean.whole
387
408
388 $ hg fix --working-dir
409 $ hg fix --working-dir
389
410
390 $ hg status --all
411 $ hg status --all
391 M modified.whole
412 M modified.whole
392 A added.whole
413 A added.whole
393 R removed.whole
414 R removed.whole
394 ! deleted.whole
415 ! deleted.whole
395 ? unknown.whole
416 ? unknown.whole
396 I ignored.whole
417 I ignored.whole
397 C .hgignore
418 C .hgignore
398 C clean.whole
419 C clean.whole
399
420
400 $ cat *.whole
421 $ cat *.whole
401 ADDED
422 ADDED
402 clean
423 clean
403 ignored
424 ignored
404 MODIFIED!!!
425 MODIFIED!!!
405 unknown
426 unknown
406
427
407 $ printf "modified!!!\n" > modified.whole
428 $ printf "modified!!!\n" > modified.whole
408 $ printf "added\n" > added.whole
429 $ printf "added\n" > added.whole
409
430
410 Listing the files explicitly causes untracked files to also be fixed, but
431 Listing the files explicitly causes untracked files to also be fixed, but
411 ignored files are still unaffected.
432 ignored files are still unaffected.
412
433
413 $ hg fix --working-dir *.whole
434 $ hg fix --working-dir *.whole
414
435
415 $ hg status --all
436 $ hg status --all
416 M clean.whole
437 M clean.whole
417 M modified.whole
438 M modified.whole
418 A added.whole
439 A added.whole
419 R removed.whole
440 R removed.whole
420 ! deleted.whole
441 ! deleted.whole
421 ? unknown.whole
442 ? unknown.whole
422 I ignored.whole
443 I ignored.whole
423 C .hgignore
444 C .hgignore
424
445
425 $ cat *.whole
446 $ cat *.whole
426 ADDED
447 ADDED
427 CLEAN
448 CLEAN
428 ignored
449 ignored
429 MODIFIED!!!
450 MODIFIED!!!
430 UNKNOWN
451 UNKNOWN
431
452
432 $ cd ..
453 $ cd ..
433
454
434 Test that incremental fixing works on files with additions, deletions, and
455 Test that incremental fixing works on files with additions, deletions, and
435 changes in multiple line ranges. Note that deletions do not generally cause
456 changes in multiple line ranges. Note that deletions do not generally cause
436 neighboring lines to be fixed, so we don't return a line range for purely
457 neighboring lines to be fixed, so we don't return a line range for purely
437 deleted sections. In the future we should support a :deletion config that
458 deleted sections. In the future we should support a :deletion config that
438 allows fixers to know where deletions are located.
459 allows fixers to know where deletions are located.
439
460
440 $ hg init incrementalfixedlines
461 $ hg init incrementalfixedlines
441 $ cd incrementalfixedlines
462 $ cd incrementalfixedlines
442
463
443 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.txt
464 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.txt
444 $ hg commit -Aqm "foo"
465 $ hg commit -Aqm "foo"
445 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.txt
466 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.txt
446
467
447 $ hg --config "fix.fail:command=echo" \
468 $ hg --config "fix.fail:command=echo" \
448 > --config "fix.fail:linerange={first}:{last}" \
469 > --config "fix.fail:linerange={first}:{last}" \
449 > --config "fix.fail:pattern=foo.txt" \
470 > --config "fix.fail:pattern=foo.txt" \
450 > fix --working-dir
471 > fix --working-dir
451 $ cat foo.txt
472 $ cat foo.txt
452 1:1 4:6 8:8
473 1:1 4:6 8:8
453
474
454 $ cd ..
475 $ cd ..
455
476
456 Test that --whole fixes all lines regardless of the diffs present.
477 Test that --whole fixes all lines regardless of the diffs present.
457
478
458 $ hg init wholeignoresdiffs
479 $ hg init wholeignoresdiffs
459 $ cd wholeignoresdiffs
480 $ cd wholeignoresdiffs
460
481
461 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.changed
482 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.changed
462 $ hg commit -Aqm "foo"
483 $ hg commit -Aqm "foo"
463 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.changed
484 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.changed
464
485
465 $ hg fix --working-dir
486 $ hg fix --working-dir
466 $ cat foo.changed
487 $ cat foo.changed
467 ZZ
488 ZZ
468 a
489 a
469 c
490 c
470 DD
491 DD
471 EE
492 EE
472 FF
493 FF
473 f
494 f
474 GG
495 GG
475
496
476 $ hg fix --working-dir --whole
497 $ hg fix --working-dir --whole
477 $ cat foo.changed
498 $ cat foo.changed
478 ZZ
499 ZZ
479 A
500 A
480 C
501 C
481 DD
502 DD
482 EE
503 EE
483 FF
504 FF
484 F
505 F
485 GG
506 GG
486
507
487 $ cd ..
508 $ cd ..
488
509
489 We should do nothing with symlinks, and their targets should be unaffected. Any
510 We should do nothing with symlinks, and their targets should be unaffected. Any
490 other behavior would be more complicated to implement and harder to document.
511 other behavior would be more complicated to implement and harder to document.
491
512
492 #if symlink
513 #if symlink
493 $ hg init dontmesswithsymlinks
514 $ hg init dontmesswithsymlinks
494 $ cd dontmesswithsymlinks
515 $ cd dontmesswithsymlinks
495
516
496 $ printf "hello\n" > hello.whole
517 $ printf "hello\n" > hello.whole
497 $ ln -s hello.whole hellolink
518 $ ln -s hello.whole hellolink
498 $ hg add
519 $ hg add
499 adding hello.whole
520 adding hello.whole
500 adding hellolink
521 adding hellolink
501 $ hg fix --working-dir hellolink
522 $ hg fix --working-dir hellolink
502 $ hg status
523 $ hg status
503 A hello.whole
524 A hello.whole
504 A hellolink
525 A hellolink
505
526
506 $ cd ..
527 $ cd ..
507 #endif
528 #endif
508
529
509 We should allow fixers to run on binary files, even though this doesn't sound
530 We should allow fixers to run on binary files, even though this doesn't sound
510 like a common use case. There's not much benefit to disallowing it, and users
531 like a common use case. There's not much benefit to disallowing it, and users
511 can add "and not binary()" to their filesets if needed. The Mercurial
532 can add "and not binary()" to their filesets if needed. The Mercurial
512 philosophy is generally to not handle binary files specially anyway.
533 philosophy is generally to not handle binary files specially anyway.
513
534
514 $ hg init cantouchbinaryfiles
535 $ hg init cantouchbinaryfiles
515 $ cd cantouchbinaryfiles
536 $ cd cantouchbinaryfiles
516
537
517 $ printf "hello\0\n" > hello.whole
538 $ printf "hello\0\n" > hello.whole
518 $ hg add
539 $ hg add
519 adding hello.whole
540 adding hello.whole
520 $ hg fix --working-dir 'set:binary()'
541 $ hg fix --working-dir 'set:binary()'
521 $ cat hello.whole
542 $ cat hello.whole
522 HELLO\x00 (esc)
543 HELLO\x00 (esc)
523
544
524 $ cd ..
545 $ cd ..
525
546
526 We have a config for the maximum size of file we will attempt to fix. This can
547 We have a config for the maximum size of file we will attempt to fix. This can
527 be helpful to avoid running unsuspecting fixer tools on huge inputs, which
548 be helpful to avoid running unsuspecting fixer tools on huge inputs, which
528 could happen by accident without a well considered configuration. A more
549 could happen by accident without a well considered configuration. A more
529 precise configuration could use the size() fileset function if one global limit
550 precise configuration could use the size() fileset function if one global limit
530 is undesired.
551 is undesired.
531
552
532 $ hg init maxfilesize
553 $ hg init maxfilesize
533 $ cd maxfilesize
554 $ cd maxfilesize
534
555
535 $ printf "this file is huge\n" > hello.whole
556 $ printf "this file is huge\n" > hello.whole
536 $ hg add
557 $ hg add
537 adding hello.whole
558 adding hello.whole
538 $ hg --config fix.maxfilesize=10 fix --working-dir
559 $ hg --config fix.maxfilesize=10 fix --working-dir
539 ignoring file larger than 10 bytes: hello.whole
560 ignoring file larger than 10 bytes: hello.whole
540 $ cat hello.whole
561 $ cat hello.whole
541 this file is huge
562 this file is huge
542
563
543 $ cd ..
564 $ cd ..
544
565
545 If we specify a file to fix, other files should be left alone, even if they
566 If we specify a file to fix, other files should be left alone, even if they
546 have changes.
567 have changes.
547
568
548 $ hg init fixonlywhatitellyouto
569 $ hg init fixonlywhatitellyouto
549 $ cd fixonlywhatitellyouto
570 $ cd fixonlywhatitellyouto
550
571
551 $ printf "fix me!\n" > fixme.whole
572 $ printf "fix me!\n" > fixme.whole
552 $ printf "not me.\n" > notme.whole
573 $ printf "not me.\n" > notme.whole
553 $ hg add
574 $ hg add
554 adding fixme.whole
575 adding fixme.whole
555 adding notme.whole
576 adding notme.whole
556 $ hg fix --working-dir fixme.whole
577 $ hg fix --working-dir fixme.whole
557 $ cat *.whole
578 $ cat *.whole
558 FIX ME!
579 FIX ME!
559 not me.
580 not me.
560
581
561 $ cd ..
582 $ cd ..
562
583
563 If we try to fix a missing file, we still fix other files.
584 If we try to fix a missing file, we still fix other files.
564
585
565 $ hg init fixmissingfile
586 $ hg init fixmissingfile
566 $ cd fixmissingfile
587 $ cd fixmissingfile
567
588
568 $ printf "fix me!\n" > foo.whole
589 $ printf "fix me!\n" > foo.whole
569 $ hg add
590 $ hg add
570 adding foo.whole
591 adding foo.whole
571 $ hg fix --working-dir foo.whole bar.whole
592 $ hg fix --working-dir foo.whole bar.whole
572 bar.whole: $ENOENT$
593 bar.whole: $ENOENT$
573 $ cat *.whole
594 $ cat *.whole
574 FIX ME!
595 FIX ME!
575
596
576 $ cd ..
597 $ cd ..
577
598
578 Specifying a directory name should fix all its files and subdirectories.
599 Specifying a directory name should fix all its files and subdirectories.
579
600
580 $ hg init fixdirectory
601 $ hg init fixdirectory
581 $ cd fixdirectory
602 $ cd fixdirectory
582
603
583 $ mkdir -p dir1/dir2
604 $ mkdir -p dir1/dir2
584 $ printf "foo\n" > foo.whole
605 $ printf "foo\n" > foo.whole
585 $ printf "bar\n" > dir1/bar.whole
606 $ printf "bar\n" > dir1/bar.whole
586 $ printf "baz\n" > dir1/dir2/baz.whole
607 $ printf "baz\n" > dir1/dir2/baz.whole
587 $ hg add
608 $ hg add
588 adding dir1/bar.whole
609 adding dir1/bar.whole
589 adding dir1/dir2/baz.whole
610 adding dir1/dir2/baz.whole
590 adding foo.whole
611 adding foo.whole
591 $ hg fix --working-dir dir1
612 $ hg fix --working-dir dir1
592 $ cat foo.whole dir1/bar.whole dir1/dir2/baz.whole
613 $ cat foo.whole dir1/bar.whole dir1/dir2/baz.whole
593 foo
614 foo
594 BAR
615 BAR
595 BAZ
616 BAZ
596
617
597 $ cd ..
618 $ cd ..
598
619
599 Fixing a file in the working directory that needs no fixes should not actually
620 Fixing a file in the working directory that needs no fixes should not actually
600 write back to the file, so for example the mtime shouldn't change.
621 write back to the file, so for example the mtime shouldn't change.
601
622
602 $ hg init donttouchunfixedfiles
623 $ hg init donttouchunfixedfiles
603 $ cd donttouchunfixedfiles
624 $ cd donttouchunfixedfiles
604
625
605 $ printf "NO FIX NEEDED\n" > foo.whole
626 $ printf "NO FIX NEEDED\n" > foo.whole
606 $ hg add
627 $ hg add
607 adding foo.whole
628 adding foo.whole
608 $ cp -p foo.whole foo.whole.orig
629 $ cp -p foo.whole foo.whole.orig
609 $ cp -p foo.whole.orig foo.whole
630 $ cp -p foo.whole.orig foo.whole
610 $ sleep 2 # mtime has a resolution of one or two seconds.
631 $ sleep 2 # mtime has a resolution of one or two seconds.
611 $ hg fix --working-dir
632 $ hg fix --working-dir
612 $ f foo.whole.orig --newer foo.whole
633 $ f foo.whole.orig --newer foo.whole
613 foo.whole.orig: newer than foo.whole
634 foo.whole.orig: newer than foo.whole
614
635
615 $ cd ..
636 $ cd ..
616
637
617 When a fixer prints to stderr, we don't assume that it has failed. We show the
638 When a fixer prints to stderr, we don't assume that it has failed. We show the
618 error messages to the user, and we still let the fixer affect the file it was
639 error messages to the user, and we still let the fixer affect the file it was
619 fixing if its exit code is zero. Some code formatters might emit error messages
640 fixing if its exit code is zero. Some code formatters might emit error messages
620 on stderr and nothing on stdout, which would cause us the clear the file,
641 on stderr and nothing on stdout, which would cause us the clear the file,
621 except that they also exit with a non-zero code. We show the user which fixer
642 except that they also exit with a non-zero code. We show the user which fixer
622 emitted the stderr, and which revision, but we assume that the fixer will print
643 emitted the stderr, and which revision, but we assume that the fixer will print
623 the filename if it is relevant (since the issue may be non-specific). There is
644 the filename if it is relevant (since the issue may be non-specific). There is
624 also a config to abort (without affecting any files whatsoever) if we see any
645 also a config to abort (without affecting any files whatsoever) if we see any
625 tool with a non-zero exit status.
646 tool with a non-zero exit status.
626
647
627 $ hg init showstderr
648 $ hg init showstderr
628 $ cd showstderr
649 $ cd showstderr
629
650
630 $ printf "hello\n" > hello.txt
651 $ printf "hello\n" > hello.txt
631 $ hg add
652 $ hg add
632 adding hello.txt
653 adding hello.txt
633 $ cat > $TESTTMP/work.sh <<'EOF'
654 $ cat > $TESTTMP/work.sh <<'EOF'
634 > printf 'HELLO\n'
655 > printf 'HELLO\n'
635 > printf "$@: some\nerror that didn't stop the tool" >&2
656 > printf "$@: some\nerror that didn't stop the tool" >&2
636 > exit 0 # success despite the stderr output
657 > exit 0 # success despite the stderr output
637 > EOF
658 > EOF
638 $ hg --config "fix.work:command=sh $TESTTMP/work.sh {rootpath}" \
659 $ hg --config "fix.work:command=sh $TESTTMP/work.sh {rootpath}" \
639 > --config "fix.work:pattern=hello.txt" \
660 > --config "fix.work:pattern=hello.txt" \
640 > fix --working-dir
661 > fix --working-dir
641 [wdir] work: hello.txt: some
662 [wdir] work: hello.txt: some
642 [wdir] work: error that didn't stop the tool
663 [wdir] work: error that didn't stop the tool
643 $ cat hello.txt
664 $ cat hello.txt
644 HELLO
665 HELLO
645
666
646 $ printf "goodbye\n" > hello.txt
667 $ printf "goodbye\n" > hello.txt
647 $ printf "foo\n" > foo.whole
668 $ printf "foo\n" > foo.whole
648 $ hg add
669 $ hg add
649 adding foo.whole
670 adding foo.whole
650 $ cat > $TESTTMP/fail.sh <<'EOF'
671 $ cat > $TESTTMP/fail.sh <<'EOF'
651 > printf 'GOODBYE\n'
672 > printf 'GOODBYE\n'
652 > printf "$@: some\nerror that did stop the tool\n" >&2
673 > printf "$@: some\nerror that did stop the tool\n" >&2
653 > exit 42 # success despite the stdout output
674 > exit 42 # success despite the stdout output
654 > EOF
675 > EOF
655 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
676 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
656 > --config "fix.fail:pattern=hello.txt" \
677 > --config "fix.fail:pattern=hello.txt" \
657 > --config "fix.failure=abort" \
678 > --config "fix.failure=abort" \
658 > fix --working-dir
679 > fix --working-dir
659 [wdir] fail: hello.txt: some
680 [wdir] fail: hello.txt: some
660 [wdir] fail: error that did stop the tool
681 [wdir] fail: error that did stop the tool
661 abort: no fixes will be applied
682 abort: no fixes will be applied
662 (use --config fix.failure=continue to apply any successful fixes anyway)
683 (use --config fix.failure=continue to apply any successful fixes anyway)
663 [255]
684 [255]
664 $ cat hello.txt
685 $ cat hello.txt
665 goodbye
686 goodbye
666 $ cat foo.whole
687 $ cat foo.whole
667 foo
688 foo
668
689
669 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
690 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
670 > --config "fix.fail:pattern=hello.txt" \
691 > --config "fix.fail:pattern=hello.txt" \
671 > fix --working-dir
692 > fix --working-dir
672 [wdir] fail: hello.txt: some
693 [wdir] fail: hello.txt: some
673 [wdir] fail: error that did stop the tool
694 [wdir] fail: error that did stop the tool
674 $ cat hello.txt
695 $ cat hello.txt
675 goodbye
696 goodbye
676 $ cat foo.whole
697 $ cat foo.whole
677 FOO
698 FOO
678
699
679 $ hg --config "fix.fail:command=exit 42" \
700 $ hg --config "fix.fail:command=exit 42" \
680 > --config "fix.fail:pattern=hello.txt" \
701 > --config "fix.fail:pattern=hello.txt" \
681 > fix --working-dir
702 > fix --working-dir
682 [wdir] fail: exited with status 42
703 [wdir] fail: exited with status 42
683
704
684 $ cd ..
705 $ cd ..
685
706
686 Fixing the working directory and its parent revision at the same time should
707 Fixing the working directory and its parent revision at the same time should
687 check out the replacement revision for the parent. This prevents any new
708 check out the replacement revision for the parent. This prevents any new
688 uncommitted changes from appearing. We test this for a clean working directory
709 uncommitted changes from appearing. We test this for a clean working directory
689 and a dirty one. In both cases, all lines/files changed since the grandparent
710 and a dirty one. In both cases, all lines/files changed since the grandparent
690 will be fixed. The grandparent is the "baserev" for both the parent and the
711 will be fixed. The grandparent is the "baserev" for both the parent and the
691 working copy.
712 working copy.
692
713
693 $ hg init fixdotandcleanwdir
714 $ hg init fixdotandcleanwdir
694 $ cd fixdotandcleanwdir
715 $ cd fixdotandcleanwdir
695
716
696 $ printf "hello\n" > hello.whole
717 $ printf "hello\n" > hello.whole
697 $ printf "world\n" > world.whole
718 $ printf "world\n" > world.whole
698 $ hg commit -Aqm "the parent commit"
719 $ hg commit -Aqm "the parent commit"
699
720
700 $ hg parents --template '{rev} {desc}\n'
721 $ hg parents --template '{rev} {desc}\n'
701 0 the parent commit
722 0 the parent commit
702 $ hg fix --working-dir -r .
723 $ hg fix --working-dir -r .
703 $ hg parents --template '{rev} {desc}\n'
724 $ hg parents --template '{rev} {desc}\n'
704 1 the parent commit
725 1 the parent commit
705 $ hg cat -r . *.whole
726 $ hg cat -r . *.whole
706 HELLO
727 HELLO
707 WORLD
728 WORLD
708 $ cat *.whole
729 $ cat *.whole
709 HELLO
730 HELLO
710 WORLD
731 WORLD
711 $ hg status
732 $ hg status
712
733
713 $ cd ..
734 $ cd ..
714
735
715 Same test with a dirty working copy.
736 Same test with a dirty working copy.
716
737
717 $ hg init fixdotanddirtywdir
738 $ hg init fixdotanddirtywdir
718 $ cd fixdotanddirtywdir
739 $ cd fixdotanddirtywdir
719
740
720 $ printf "hello\n" > hello.whole
741 $ printf "hello\n" > hello.whole
721 $ printf "world\n" > world.whole
742 $ printf "world\n" > world.whole
722 $ hg commit -Aqm "the parent commit"
743 $ hg commit -Aqm "the parent commit"
723
744
724 $ printf "hello,\n" > hello.whole
745 $ printf "hello,\n" > hello.whole
725 $ printf "world!\n" > world.whole
746 $ printf "world!\n" > world.whole
726
747
727 $ hg parents --template '{rev} {desc}\n'
748 $ hg parents --template '{rev} {desc}\n'
728 0 the parent commit
749 0 the parent commit
729 $ hg fix --working-dir -r .
750 $ hg fix --working-dir -r .
730 $ hg parents --template '{rev} {desc}\n'
751 $ hg parents --template '{rev} {desc}\n'
731 1 the parent commit
752 1 the parent commit
732 $ hg cat -r . *.whole
753 $ hg cat -r . *.whole
733 HELLO
754 HELLO
734 WORLD
755 WORLD
735 $ cat *.whole
756 $ cat *.whole
736 HELLO,
757 HELLO,
737 WORLD!
758 WORLD!
738 $ hg status
759 $ hg status
739 M hello.whole
760 M hello.whole
740 M world.whole
761 M world.whole
741
762
742 $ cd ..
763 $ cd ..
743
764
744 When we have a chain of commits that change mutually exclusive lines of code,
765 When we have a chain of commits that change mutually exclusive lines of code,
745 we should be able to do incremental fixing that causes each commit in the chain
766 we should be able to do incremental fixing that causes each commit in the chain
746 to include fixes made to the previous commits. This prevents children from
767 to include fixes made to the previous commits. This prevents children from
747 backing out the fixes made in their parents. A dirty working directory is
768 backing out the fixes made in their parents. A dirty working directory is
748 conceptually similar to another commit in the chain.
769 conceptually similar to another commit in the chain.
749
770
750 $ hg init incrementallyfixchain
771 $ hg init incrementallyfixchain
751 $ cd incrementallyfixchain
772 $ cd incrementallyfixchain
752
773
753 $ cat > file.changed <<EOF
774 $ cat > file.changed <<EOF
754 > first
775 > first
755 > second
776 > second
756 > third
777 > third
757 > fourth
778 > fourth
758 > fifth
779 > fifth
759 > EOF
780 > EOF
760 $ hg commit -Aqm "the common ancestor (the baserev)"
781 $ hg commit -Aqm "the common ancestor (the baserev)"
761 $ cat > file.changed <<EOF
782 $ cat > file.changed <<EOF
762 > first (changed)
783 > first (changed)
763 > second
784 > second
764 > third
785 > third
765 > fourth
786 > fourth
766 > fifth
787 > fifth
767 > EOF
788 > EOF
768 $ hg commit -Aqm "the first commit to fix"
789 $ hg commit -Aqm "the first commit to fix"
769 $ cat > file.changed <<EOF
790 $ cat > file.changed <<EOF
770 > first (changed)
791 > first (changed)
771 > second
792 > second
772 > third (changed)
793 > third (changed)
773 > fourth
794 > fourth
774 > fifth
795 > fifth
775 > EOF
796 > EOF
776 $ hg commit -Aqm "the second commit to fix"
797 $ hg commit -Aqm "the second commit to fix"
777 $ cat > file.changed <<EOF
798 $ cat > file.changed <<EOF
778 > first (changed)
799 > first (changed)
779 > second
800 > second
780 > third (changed)
801 > third (changed)
781 > fourth
802 > fourth
782 > fifth (changed)
803 > fifth (changed)
783 > EOF
804 > EOF
784
805
785 $ hg fix -r . -r '.^' --working-dir
806 $ hg fix -r . -r '.^' --working-dir
786
807
787 $ hg parents --template '{rev}\n'
808 $ hg parents --template '{rev}\n'
788 4
809 4
789 $ hg cat -r '.^^' file.changed
810 $ hg cat -r '.^^' file.changed
790 first
811 first
791 second
812 second
792 third
813 third
793 fourth
814 fourth
794 fifth
815 fifth
795 $ hg cat -r '.^' file.changed
816 $ hg cat -r '.^' file.changed
796 FIRST (CHANGED)
817 FIRST (CHANGED)
797 second
818 second
798 third
819 third
799 fourth
820 fourth
800 fifth
821 fifth
801 $ hg cat -r . file.changed
822 $ hg cat -r . file.changed
802 FIRST (CHANGED)
823 FIRST (CHANGED)
803 second
824 second
804 THIRD (CHANGED)
825 THIRD (CHANGED)
805 fourth
826 fourth
806 fifth
827 fifth
807 $ cat file.changed
828 $ cat file.changed
808 FIRST (CHANGED)
829 FIRST (CHANGED)
809 second
830 second
810 THIRD (CHANGED)
831 THIRD (CHANGED)
811 fourth
832 fourth
812 FIFTH (CHANGED)
833 FIFTH (CHANGED)
813
834
814 $ cd ..
835 $ cd ..
815
836
816 If we incrementally fix a merge commit, we should fix any lines that changed
837 If we incrementally fix a merge commit, we should fix any lines that changed
817 versus either parent. You could imagine only fixing the intersection or some
838 versus either parent. You could imagine only fixing the intersection or some
818 other subset, but this is necessary if either parent is being fixed. It
839 other subset, but this is necessary if either parent is being fixed. It
819 prevents us from forgetting fixes made in either parent.
840 prevents us from forgetting fixes made in either parent.
820
841
821 $ hg init incrementallyfixmergecommit
842 $ hg init incrementallyfixmergecommit
822 $ cd incrementallyfixmergecommit
843 $ cd incrementallyfixmergecommit
823
844
824 $ printf "a\nb\nc\n" > file.changed
845 $ printf "a\nb\nc\n" > file.changed
825 $ hg commit -Aqm "ancestor"
846 $ hg commit -Aqm "ancestor"
826
847
827 $ printf "aa\nb\nc\n" > file.changed
848 $ printf "aa\nb\nc\n" > file.changed
828 $ hg commit -m "change a"
849 $ hg commit -m "change a"
829
850
830 $ hg checkout '.^'
851 $ hg checkout '.^'
831 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
852 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
832 $ printf "a\nb\ncc\n" > file.changed
853 $ printf "a\nb\ncc\n" > file.changed
833 $ hg commit -m "change c"
854 $ hg commit -m "change c"
834 created new head
855 created new head
835
856
836 $ hg merge
857 $ hg merge
837 merging file.changed
858 merging file.changed
838 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
859 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
839 (branch merge, don't forget to commit)
860 (branch merge, don't forget to commit)
840 $ hg commit -m "merge"
861 $ hg commit -m "merge"
841 $ hg cat -r . file.changed
862 $ hg cat -r . file.changed
842 aa
863 aa
843 b
864 b
844 cc
865 cc
845
866
846 $ hg fix -r . --working-dir
867 $ hg fix -r . --working-dir
847 $ hg cat -r . file.changed
868 $ hg cat -r . file.changed
848 AA
869 AA
849 b
870 b
850 CC
871 CC
851
872
852 $ cd ..
873 $ cd ..
853
874
854 Abort fixing revisions if there is an unfinished operation. We don't want to
875 Abort fixing revisions if there is an unfinished operation. We don't want to
855 make things worse by editing files or stripping/obsoleting things. Also abort
876 make things worse by editing files or stripping/obsoleting things. Also abort
856 fixing the working directory if there are unresolved merge conflicts.
877 fixing the working directory if there are unresolved merge conflicts.
857
878
858 $ hg init abortunresolved
879 $ hg init abortunresolved
859 $ cd abortunresolved
880 $ cd abortunresolved
860
881
861 $ echo "foo1" > foo.whole
882 $ echo "foo1" > foo.whole
862 $ hg commit -Aqm "foo 1"
883 $ hg commit -Aqm "foo 1"
863
884
864 $ hg update null
885 $ hg update null
865 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
886 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
866 $ echo "foo2" > foo.whole
887 $ echo "foo2" > foo.whole
867 $ hg commit -Aqm "foo 2"
888 $ hg commit -Aqm "foo 2"
868
889
869 $ hg --config extensions.rebase= rebase -r 1 -d 0
890 $ hg --config extensions.rebase= rebase -r 1 -d 0
870 rebasing 1:c3b6dc0e177a tip "foo 2"
891 rebasing 1:c3b6dc0e177a tip "foo 2"
871 merging foo.whole
892 merging foo.whole
872 warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
893 warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
873 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
894 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
874 [240]
895 [240]
875
896
876 $ hg --config extensions.rebase= fix --working-dir
897 $ hg --config extensions.rebase= fix --working-dir
877 abort: unresolved conflicts
898 abort: unresolved conflicts
878 (use 'hg resolve')
899 (use 'hg resolve')
879 [255]
900 [255]
880
901
881 $ hg --config extensions.rebase= fix -r .
902 $ hg --config extensions.rebase= fix -r .
882 abort: rebase in progress
903 abort: rebase in progress
883 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
904 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
884 [20]
905 [20]
885
906
886 $ cd ..
907 $ cd ..
887
908
888 When fixing a file that was renamed, we should diff against the source of the
909 When fixing a file that was renamed, we should diff against the source of the
889 rename for incremental fixing and we should correctly reproduce the rename in
910 rename for incremental fixing and we should correctly reproduce the rename in
890 the replacement revision.
911 the replacement revision.
891
912
892 $ hg init fixrenamecommit
913 $ hg init fixrenamecommit
893 $ cd fixrenamecommit
914 $ cd fixrenamecommit
894
915
895 $ printf "a\nb\nc\n" > source.changed
916 $ printf "a\nb\nc\n" > source.changed
896 $ hg commit -Aqm "source revision"
917 $ hg commit -Aqm "source revision"
897 $ hg move source.changed dest.changed
918 $ hg move source.changed dest.changed
898 $ printf "a\nb\ncc\n" > dest.changed
919 $ printf "a\nb\ncc\n" > dest.changed
899 $ hg commit -m "dest revision"
920 $ hg commit -m "dest revision"
900
921
901 $ hg fix -r .
922 $ hg fix -r .
902 $ hg log -r tip --copies --template "{file_copies}\n"
923 $ hg log -r tip --copies --template "{file_copies}\n"
903 dest.changed (source.changed)
924 dest.changed (source.changed)
904 $ hg cat -r tip dest.changed
925 $ hg cat -r tip dest.changed
905 a
926 a
906 b
927 b
907 CC
928 CC
908
929
909 $ cd ..
930 $ cd ..
910
931
911 When fixing revisions that remove files we must ensure that the replacement
932 When fixing revisions that remove files we must ensure that the replacement
912 actually removes the file, whereas it could accidentally leave it unchanged or
933 actually removes the file, whereas it could accidentally leave it unchanged or
913 write an empty string to it.
934 write an empty string to it.
914
935
915 $ hg init fixremovedfile
936 $ hg init fixremovedfile
916 $ cd fixremovedfile
937 $ cd fixremovedfile
917
938
918 $ printf "foo\n" > foo.whole
939 $ printf "foo\n" > foo.whole
919 $ printf "bar\n" > bar.whole
940 $ printf "bar\n" > bar.whole
920 $ hg commit -Aqm "add files"
941 $ hg commit -Aqm "add files"
921 $ hg remove bar.whole
942 $ hg remove bar.whole
922 $ hg commit -m "remove file"
943 $ hg commit -m "remove file"
923 $ hg status --change .
944 $ hg status --change .
924 R bar.whole
945 R bar.whole
925 $ hg fix -r . foo.whole
946 $ hg fix -r . foo.whole
926 $ hg status --change tip
947 $ hg status --change tip
927 M foo.whole
948 M foo.whole
928 R bar.whole
949 R bar.whole
929
950
930 $ cd ..
951 $ cd ..
931
952
932 If fixing a revision finds no fixes to make, no replacement revision should be
953 If fixing a revision finds no fixes to make, no replacement revision should be
933 created.
954 created.
934
955
935 $ hg init nofixesneeded
956 $ hg init nofixesneeded
936 $ cd nofixesneeded
957 $ cd nofixesneeded
937
958
938 $ printf "FOO\n" > foo.whole
959 $ printf "FOO\n" > foo.whole
939 $ hg commit -Aqm "add file"
960 $ hg commit -Aqm "add file"
940 $ hg log --template '{rev}\n'
961 $ hg log --template '{rev}\n'
941 0
962 0
942 $ hg fix -r .
963 $ hg fix -r .
943 $ hg log --template '{rev}\n'
964 $ hg log --template '{rev}\n'
944 0
965 0
945
966
946 $ cd ..
967 $ cd ..
947
968
948 If fixing a commit reverts all the changes in the commit, we replace it with a
969 If fixing a commit reverts all the changes in the commit, we replace it with a
949 commit that changes no files.
970 commit that changes no files.
950
971
951 $ hg init nochangesleft
972 $ hg init nochangesleft
952 $ cd nochangesleft
973 $ cd nochangesleft
953
974
954 $ printf "FOO\n" > foo.whole
975 $ printf "FOO\n" > foo.whole
955 $ hg commit -Aqm "add file"
976 $ hg commit -Aqm "add file"
956 $ printf "foo\n" > foo.whole
977 $ printf "foo\n" > foo.whole
957 $ hg commit -m "edit file"
978 $ hg commit -m "edit file"
958 $ hg status --change .
979 $ hg status --change .
959 M foo.whole
980 M foo.whole
960 $ hg fix -r .
981 $ hg fix -r .
961 $ hg status --change tip
982 $ hg status --change tip
962
983
963 $ cd ..
984 $ cd ..
964
985
965 If we fix a parent and child revision together, the child revision must be
986 If we fix a parent and child revision together, the child revision must be
966 replaced if the parent is replaced, even if the diffs of the child needed no
987 replaced if the parent is replaced, even if the diffs of the child needed no
967 fixes. However, we're free to not replace revisions that need no fixes and have
988 fixes. However, we're free to not replace revisions that need no fixes and have
968 no ancestors that are replaced.
989 no ancestors that are replaced.
969
990
970 $ hg init mustreplacechild
991 $ hg init mustreplacechild
971 $ cd mustreplacechild
992 $ cd mustreplacechild
972
993
973 $ printf "FOO\n" > foo.whole
994 $ printf "FOO\n" > foo.whole
974 $ hg commit -Aqm "add foo"
995 $ hg commit -Aqm "add foo"
975 $ printf "foo\n" > foo.whole
996 $ printf "foo\n" > foo.whole
976 $ hg commit -m "edit foo"
997 $ hg commit -m "edit foo"
977 $ printf "BAR\n" > bar.whole
998 $ printf "BAR\n" > bar.whole
978 $ hg commit -Aqm "add bar"
999 $ hg commit -Aqm "add bar"
979
1000
980 $ hg log --graph --template '{rev} {files}'
1001 $ hg log --graph --template '{rev} {files}'
981 @ 2 bar.whole
1002 @ 2 bar.whole
982 |
1003 |
983 o 1 foo.whole
1004 o 1 foo.whole
984 |
1005 |
985 o 0 foo.whole
1006 o 0 foo.whole
986
1007
987 $ hg fix -r 0:2
1008 $ hg fix -r 0:2
988 $ hg log --graph --template '{rev} {files}'
1009 $ hg log --graph --template '{rev} {files}'
989 o 4 bar.whole
1010 o 4 bar.whole
990 |
1011 |
991 o 3
1012 o 3
992 |
1013 |
993 | @ 2 bar.whole
1014 | @ 2 bar.whole
994 | |
1015 | |
995 | x 1 foo.whole
1016 | x 1 foo.whole
996 |/
1017 |/
997 o 0 foo.whole
1018 o 0 foo.whole
998
1019
999
1020
1000 $ cd ..
1021 $ cd ..
1001
1022
1002 It's also possible that the child needs absolutely no changes, but we still
1023 It's also possible that the child needs absolutely no changes, but we still
1003 need to replace it to update its parent. If we skipped replacing the child
1024 need to replace it to update its parent. If we skipped replacing the child
1004 because it had no file content changes, it would become an orphan for no good
1025 because it had no file content changes, it would become an orphan for no good
1005 reason.
1026 reason.
1006
1027
1007 $ hg init mustreplacechildevenifnop
1028 $ hg init mustreplacechildevenifnop
1008 $ cd mustreplacechildevenifnop
1029 $ cd mustreplacechildevenifnop
1009
1030
1010 $ printf "Foo\n" > foo.whole
1031 $ printf "Foo\n" > foo.whole
1011 $ hg commit -Aqm "add a bad foo"
1032 $ hg commit -Aqm "add a bad foo"
1012 $ printf "FOO\n" > foo.whole
1033 $ printf "FOO\n" > foo.whole
1013 $ hg commit -m "add a good foo"
1034 $ hg commit -m "add a good foo"
1014 $ hg fix -r . -r '.^'
1035 $ hg fix -r . -r '.^'
1015 $ hg log --graph --template '{rev} {desc}'
1036 $ hg log --graph --template '{rev} {desc}'
1016 o 3 add a good foo
1037 o 3 add a good foo
1017 |
1038 |
1018 o 2 add a bad foo
1039 o 2 add a bad foo
1019
1040
1020 @ 1 add a good foo
1041 @ 1 add a good foo
1021 |
1042 |
1022 x 0 add a bad foo
1043 x 0 add a bad foo
1023
1044
1024
1045
1025 $ cd ..
1046 $ cd ..
1026
1047
1027 Similar to the case above, the child revision may become empty as a result of
1048 Similar to the case above, the child revision may become empty as a result of
1028 fixing its parent. We should still create an empty replacement child.
1049 fixing its parent. We should still create an empty replacement child.
1029 TODO: determine how this should interact with ui.allowemptycommit given that
1050 TODO: determine how this should interact with ui.allowemptycommit given that
1030 the empty replacement could have children.
1051 the empty replacement could have children.
1031
1052
1032 $ hg init mustreplacechildevenifempty
1053 $ hg init mustreplacechildevenifempty
1033 $ cd mustreplacechildevenifempty
1054 $ cd mustreplacechildevenifempty
1034
1055
1035 $ printf "foo\n" > foo.whole
1056 $ printf "foo\n" > foo.whole
1036 $ hg commit -Aqm "add foo"
1057 $ hg commit -Aqm "add foo"
1037 $ printf "Foo\n" > foo.whole
1058 $ printf "Foo\n" > foo.whole
1038 $ hg commit -m "edit foo"
1059 $ hg commit -m "edit foo"
1039 $ hg fix -r . -r '.^'
1060 $ hg fix -r . -r '.^'
1040 $ hg log --graph --template '{rev} {desc}\n' --stat
1061 $ hg log --graph --template '{rev} {desc}\n' --stat
1041 o 3 edit foo
1062 o 3 edit foo
1042 |
1063 |
1043 o 2 add foo
1064 o 2 add foo
1044 foo.whole | 1 +
1065 foo.whole | 1 +
1045 1 files changed, 1 insertions(+), 0 deletions(-)
1066 1 files changed, 1 insertions(+), 0 deletions(-)
1046
1067
1047 @ 1 edit foo
1068 @ 1 edit foo
1048 | foo.whole | 2 +-
1069 | foo.whole | 2 +-
1049 | 1 files changed, 1 insertions(+), 1 deletions(-)
1070 | 1 files changed, 1 insertions(+), 1 deletions(-)
1050 |
1071 |
1051 x 0 add foo
1072 x 0 add foo
1052 foo.whole | 1 +
1073 foo.whole | 1 +
1053 1 files changed, 1 insertions(+), 0 deletions(-)
1074 1 files changed, 1 insertions(+), 0 deletions(-)
1054
1075
1055
1076
1056 $ cd ..
1077 $ cd ..
1057
1078
1058 Fixing a secret commit should replace it with another secret commit.
1079 Fixing a secret commit should replace it with another secret commit.
1059
1080
1060 $ hg init fixsecretcommit
1081 $ hg init fixsecretcommit
1061 $ cd fixsecretcommit
1082 $ cd fixsecretcommit
1062
1083
1063 $ printf "foo\n" > foo.whole
1084 $ printf "foo\n" > foo.whole
1064 $ hg commit -Aqm "add foo" --secret
1085 $ hg commit -Aqm "add foo" --secret
1065 $ hg fix -r .
1086 $ hg fix -r .
1066 $ hg log --template '{rev} {phase}\n'
1087 $ hg log --template '{rev} {phase}\n'
1067 1 secret
1088 1 secret
1068 0 secret
1089 0 secret
1069
1090
1070 $ cd ..
1091 $ cd ..
1071
1092
1072 We should also preserve phase when fixing a draft commit while the user has
1093 We should also preserve phase when fixing a draft commit while the user has
1073 their default set to secret.
1094 their default set to secret.
1074
1095
1075 $ hg init respectphasesnewcommit
1096 $ hg init respectphasesnewcommit
1076 $ cd respectphasesnewcommit
1097 $ cd respectphasesnewcommit
1077
1098
1078 $ printf "foo\n" > foo.whole
1099 $ printf "foo\n" > foo.whole
1079 $ hg commit -Aqm "add foo"
1100 $ hg commit -Aqm "add foo"
1080 $ hg --config phases.newcommit=secret fix -r .
1101 $ hg --config phases.newcommit=secret fix -r .
1081 $ hg log --template '{rev} {phase}\n'
1102 $ hg log --template '{rev} {phase}\n'
1082 1 draft
1103 1 draft
1083 0 draft
1104 0 draft
1084
1105
1085 $ cd ..
1106 $ cd ..
1086
1107
1087 Debug output should show what fixer commands are being subprocessed, which is
1108 Debug output should show what fixer commands are being subprocessed, which is
1088 useful for anyone trying to set up a new config.
1109 useful for anyone trying to set up a new config.
1089
1110
1090 $ hg init debugoutput
1111 $ hg init debugoutput
1091 $ cd debugoutput
1112 $ cd debugoutput
1092
1113
1093 $ printf "foo\nbar\nbaz\n" > foo.changed
1114 $ printf "foo\nbar\nbaz\n" > foo.changed
1094 $ hg commit -Aqm "foo"
1115 $ hg commit -Aqm "foo"
1095 $ printf "Foo\nbar\nBaz\n" > foo.changed
1116 $ printf "Foo\nbar\nBaz\n" > foo.changed
1096 $ hg --debug fix --working-dir
1117 $ hg --debug fix --working-dir
1097 subprocess: * $TESTTMP/uppercase.py 1-1 3-3 (glob)
1118 subprocess: * $TESTTMP/uppercase.py 1-1 3-3 (glob)
1098
1119
1099 $ cd ..
1120 $ cd ..
1100
1121
1101 Fixing an obsolete revision can cause divergence, so we abort unless the user
1122 Fixing an obsolete revision can cause divergence, so we abort unless the user
1102 configures to allow it. This is not yet smart enough to know whether there is a
1123 configures to allow it. This is not yet smart enough to know whether there is a
1103 successor, but even then it is not likely intentional or idiomatic to fix an
1124 successor, but even then it is not likely intentional or idiomatic to fix an
1104 obsolete revision.
1125 obsolete revision.
1105
1126
1106 $ hg init abortobsoleterev
1127 $ hg init abortobsoleterev
1107 $ cd abortobsoleterev
1128 $ cd abortobsoleterev
1108
1129
1109 $ printf "foo\n" > foo.changed
1130 $ printf "foo\n" > foo.changed
1110 $ hg commit -Aqm "foo"
1131 $ hg commit -Aqm "foo"
1111 $ hg ci --amend -m rewritten
1132 $ hg ci --amend -m rewritten
1112 $ hg --hidden fix -r 0
1133 $ hg --hidden fix -r 0
1113 abort: fixing obsolete revision could cause divergence
1134 abort: fixing obsolete revision could cause divergence
1114 [255]
1135 [255]
1115
1136
1116 $ hg --hidden fix -r 0 --config experimental.evolution.allowdivergence=true
1137 $ hg --hidden fix -r 0 --config experimental.evolution.allowdivergence=true
1117 2 new content-divergent changesets
1138 2 new content-divergent changesets
1118 $ hg cat -r tip foo.changed
1139 $ hg cat -r tip foo.changed
1119 FOO
1140 FOO
1120
1141
1121 $ cd ..
1142 $ cd ..
1122
1143
1123 Test all of the available substitution values for fixer commands.
1144 Test all of the available substitution values for fixer commands.
1124
1145
1125 $ hg init substitution
1146 $ hg init substitution
1126 $ cd substitution
1147 $ cd substitution
1127
1148
1128 $ mkdir foo
1149 $ mkdir foo
1129 $ printf "hello\ngoodbye\n" > foo/bar
1150 $ printf "hello\ngoodbye\n" > foo/bar
1130 $ hg add
1151 $ hg add
1131 adding foo/bar
1152 adding foo/bar
1132 $ hg --config "fix.fail:command=printf '%s\n' '{rootpath}' '{basename}'" \
1153 $ hg --config "fix.fail:command=printf '%s\n' '{rootpath}' '{basename}'" \
1133 > --config "fix.fail:linerange='{first}' '{last}'" \
1154 > --config "fix.fail:linerange='{first}' '{last}'" \
1134 > --config "fix.fail:pattern=foo/bar" \
1155 > --config "fix.fail:pattern=foo/bar" \
1135 > fix --working-dir
1156 > fix --working-dir
1136 $ cat foo/bar
1157 $ cat foo/bar
1137 foo/bar
1158 foo/bar
1138 bar
1159 bar
1139 1
1160 1
1140 2
1161 2
1141
1162
1142 $ cd ..
1163 $ cd ..
1143
1164
1144 The --base flag should allow picking the revisions to diff against for changed
1165 The --base flag should allow picking the revisions to diff against for changed
1145 files and incremental line formatting.
1166 files and incremental line formatting.
1146
1167
1147 $ hg init baseflag
1168 $ hg init baseflag
1148 $ cd baseflag
1169 $ cd baseflag
1149
1170
1150 $ printf "one\ntwo\n" > foo.changed
1171 $ printf "one\ntwo\n" > foo.changed
1151 $ printf "bar\n" > bar.changed
1172 $ printf "bar\n" > bar.changed
1152 $ hg commit -Aqm "first"
1173 $ hg commit -Aqm "first"
1153 $ printf "one\nTwo\n" > foo.changed
1174 $ printf "one\nTwo\n" > foo.changed
1154 $ hg commit -m "second"
1175 $ hg commit -m "second"
1155 $ hg fix -w --base .
1176 $ hg fix -w --base .
1156 $ hg status
1177 $ hg status
1157 $ hg fix -w --base null
1178 $ hg fix -w --base null
1158 $ cat foo.changed
1179 $ cat foo.changed
1159 ONE
1180 ONE
1160 TWO
1181 TWO
1161 $ cat bar.changed
1182 $ cat bar.changed
1162 BAR
1183 BAR
1163
1184
1164 $ cd ..
1185 $ cd ..
1165
1186
1166 If the user asks to fix the parent of another commit, they are asking to create
1187 If the user asks to fix the parent of another commit, they are asking to create
1167 an orphan. We must respect experimental.evolution.allowunstable.
1188 an orphan. We must respect experimental.evolution.allowunstable.
1168
1189
1169 $ hg init allowunstable
1190 $ hg init allowunstable
1170 $ cd allowunstable
1191 $ cd allowunstable
1171
1192
1172 $ printf "one\n" > foo.whole
1193 $ printf "one\n" > foo.whole
1173 $ hg commit -Aqm "first"
1194 $ hg commit -Aqm "first"
1174 $ printf "two\n" > foo.whole
1195 $ printf "two\n" > foo.whole
1175 $ hg commit -m "second"
1196 $ hg commit -m "second"
1176 $ hg --config experimental.evolution.allowunstable=False fix -r '.^'
1197 $ hg --config experimental.evolution.allowunstable=False fix -r '.^'
1177 abort: cannot fix changeset, as that will orphan 1 descendants
1198 abort: cannot fix changeset, as that will orphan 1 descendants
1178 (see 'hg help evolution.instability')
1199 (see 'hg help evolution.instability')
1179 [10]
1200 [10]
1180 $ hg fix -r '.^'
1201 $ hg fix -r '.^'
1181 1 new orphan changesets
1202 1 new orphan changesets
1182 $ hg cat -r 2 foo.whole
1203 $ hg cat -r 2 foo.whole
1183 ONE
1204 ONE
1184
1205
1185 $ cd ..
1206 $ cd ..
1186
1207
1187 The --base flag affects the set of files being fixed. So while the --whole flag
1208 The --base flag affects the set of files being fixed. So while the --whole flag
1188 makes the base irrelevant for changed line ranges, it still changes the
1209 makes the base irrelevant for changed line ranges, it still changes the
1189 meaning and effect of the command. In this example, no files or lines are fixed
1210 meaning and effect of the command. In this example, no files or lines are fixed
1190 until we specify the base, but then we do fix unchanged lines.
1211 until we specify the base, but then we do fix unchanged lines.
1191
1212
1192 $ hg init basewhole
1213 $ hg init basewhole
1193 $ cd basewhole
1214 $ cd basewhole
1194 $ printf "foo1\n" > foo.changed
1215 $ printf "foo1\n" > foo.changed
1195 $ hg commit -Aqm "first"
1216 $ hg commit -Aqm "first"
1196 $ printf "foo2\n" >> foo.changed
1217 $ printf "foo2\n" >> foo.changed
1197 $ printf "bar\n" > bar.changed
1218 $ printf "bar\n" > bar.changed
1198 $ hg commit -Aqm "second"
1219 $ hg commit -Aqm "second"
1199
1220
1200 $ hg fix --working-dir --whole
1221 $ hg fix --working-dir --whole
1201 $ cat *.changed
1222 $ cat *.changed
1202 bar
1223 bar
1203 foo1
1224 foo1
1204 foo2
1225 foo2
1205
1226
1206 $ hg fix --working-dir --base 0 --whole
1227 $ hg fix --working-dir --base 0 --whole
1207 $ cat *.changed
1228 $ cat *.changed
1208 BAR
1229 BAR
1209 FOO1
1230 FOO1
1210 FOO2
1231 FOO2
1211
1232
1212 $ cd ..
1233 $ cd ..
1213
1234
1214 The execution order of tools can be controlled. This example doesn't work if
1235 The execution order of tools can be controlled. This example doesn't work if
1215 you sort after truncating, but the config defines the correct order while the
1236 you sort after truncating, but the config defines the correct order while the
1216 definitions are out of order (which might imply the incorrect order given the
1237 definitions are out of order (which might imply the incorrect order given the
1217 implementation of fix). The goal is to use multiple tools to select the lowest
1238 implementation of fix). The goal is to use multiple tools to select the lowest
1218 5 numbers in the file.
1239 5 numbers in the file.
1219
1240
1220 $ hg init priorityexample
1241 $ hg init priorityexample
1221 $ cd priorityexample
1242 $ cd priorityexample
1222
1243
1223 $ cat >> .hg/hgrc <<EOF
1244 $ cat >> .hg/hgrc <<EOF
1224 > [fix]
1245 > [fix]
1225 > head:command = head -n 5
1246 > head:command = head -n 5
1226 > head:pattern = numbers.txt
1247 > head:pattern = numbers.txt
1227 > head:priority = 1
1248 > head:priority = 1
1228 > sort:command = sort -n
1249 > sort:command = sort -n
1229 > sort:pattern = numbers.txt
1250 > sort:pattern = numbers.txt
1230 > sort:priority = 2
1251 > sort:priority = 2
1231 > EOF
1252 > EOF
1232
1253
1233 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1254 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1234 $ hg add -q
1255 $ hg add -q
1235 $ hg fix -w
1256 $ hg fix -w
1236 $ cat numbers.txt
1257 $ cat numbers.txt
1237 0
1258 0
1238 1
1259 1
1239 2
1260 2
1240 3
1261 3
1241 4
1262 4
1242
1263
1243 And of course we should be able to break this by reversing the execution order.
1264 And of course we should be able to break this by reversing the execution order.
1244 Test negative priorities while we're at it.
1265 Test negative priorities while we're at it.
1245
1266
1246 $ cat >> .hg/hgrc <<EOF
1267 $ cat >> .hg/hgrc <<EOF
1247 > [fix]
1268 > [fix]
1248 > head:priority = -1
1269 > head:priority = -1
1249 > sort:priority = -2
1270 > sort:priority = -2
1250 > EOF
1271 > EOF
1251 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1272 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1252 $ hg fix -w
1273 $ hg fix -w
1253 $ cat numbers.txt
1274 $ cat numbers.txt
1254 2
1275 2
1255 3
1276 3
1256 6
1277 6
1257 7
1278 7
1258 8
1279 8
1259
1280
1260 $ cd ..
1281 $ cd ..
1261
1282
1262 It's possible for repeated applications of a fixer tool to create cycles in the
1283 It's possible for repeated applications of a fixer tool to create cycles in the
1263 generated content of a file. For example, two users with different versions of
1284 generated content of a file. For example, two users with different versions of
1264 a code formatter might fight over the formatting when they run hg fix. In the
1285 a code formatter might fight over the formatting when they run hg fix. In the
1265 absence of other changes, this means we could produce commits with the same
1286 absence of other changes, this means we could produce commits with the same
1266 hash in subsequent runs of hg fix. This is a problem unless we support
1287 hash in subsequent runs of hg fix. This is a problem unless we support
1267 obsolescence cycles well. We avoid this by adding an extra field to the
1288 obsolescence cycles well. We avoid this by adding an extra field to the
1268 successor which forces it to have a new hash. That's why this test creates
1289 successor which forces it to have a new hash. That's why this test creates
1269 three revisions instead of two.
1290 three revisions instead of two.
1270
1291
1271 $ hg init cyclictool
1292 $ hg init cyclictool
1272 $ cd cyclictool
1293 $ cd cyclictool
1273
1294
1274 $ cat >> .hg/hgrc <<EOF
1295 $ cat >> .hg/hgrc <<EOF
1275 > [fix]
1296 > [fix]
1276 > swapletters:command = tr ab ba
1297 > swapletters:command = tr ab ba
1277 > swapletters:pattern = foo
1298 > swapletters:pattern = foo
1278 > EOF
1299 > EOF
1279
1300
1280 $ echo ab > foo
1301 $ echo ab > foo
1281 $ hg commit -Aqm foo
1302 $ hg commit -Aqm foo
1282
1303
1283 $ hg fix -r 0
1304 $ hg fix -r 0
1284 $ hg fix -r 1
1305 $ hg fix -r 1
1285
1306
1286 $ hg cat -r 0 foo --hidden
1307 $ hg cat -r 0 foo --hidden
1287 ab
1308 ab
1288 $ hg cat -r 1 foo --hidden
1309 $ hg cat -r 1 foo --hidden
1289 ba
1310 ba
1290 $ hg cat -r 2 foo
1311 $ hg cat -r 2 foo
1291 ab
1312 ab
1292
1313
1293 $ cd ..
1314 $ cd ..
1294
1315
1295 We run fixer tools in the repo root so they can look for config files or other
1316 We run fixer tools in the repo root so they can look for config files or other
1296 important things in the working directory. This does NOT mean we are
1317 important things in the working directory. This does NOT mean we are
1297 reconstructing a working copy of every revision being fixed; we're just giving
1318 reconstructing a working copy of every revision being fixed; we're just giving
1298 the tool knowledge of the repo's location in case it can do something
1319 the tool knowledge of the repo's location in case it can do something
1299 reasonable with that.
1320 reasonable with that.
1300
1321
1301 $ hg init subprocesscwd
1322 $ hg init subprocesscwd
1302 $ cd subprocesscwd
1323 $ cd subprocesscwd
1303
1324
1304 $ cat >> .hg/hgrc <<EOF
1325 $ cat >> .hg/hgrc <<EOF
1305 > [fix]
1326 > [fix]
1306 > printcwd:command = "$PYTHON" -c "import os; print(os.getcwd())"
1327 > printcwd:command = "$PYTHON" -c "import os; print(os.getcwd())"
1307 > printcwd:pattern = relpath:foo/bar
1328 > printcwd:pattern = relpath:foo/bar
1308 > filesetpwd:command = "$PYTHON" -c "import os; print('fs: ' + os.getcwd())"
1329 > filesetpwd:command = "$PYTHON" -c "import os; print('fs: ' + os.getcwd())"
1309 > filesetpwd:pattern = set:**quux
1330 > filesetpwd:pattern = set:**quux
1310 > EOF
1331 > EOF
1311
1332
1312 $ mkdir foo
1333 $ mkdir foo
1313 $ printf "bar\n" > foo/bar
1334 $ printf "bar\n" > foo/bar
1314 $ printf "quux\n" > quux
1335 $ printf "quux\n" > quux
1315 $ hg commit -Aqm blah
1336 $ hg commit -Aqm blah
1316
1337
1317 $ hg fix -w -r . foo/bar
1338 $ hg fix -w -r . foo/bar
1318 $ hg cat -r tip foo/bar
1339 $ hg cat -r tip foo/bar
1319 $TESTTMP/subprocesscwd
1340 $TESTTMP/subprocesscwd
1320 $ cat foo/bar
1341 $ cat foo/bar
1321 $TESTTMP/subprocesscwd
1342 $TESTTMP/subprocesscwd
1322
1343
1323 $ cd foo
1344 $ cd foo
1324
1345
1325 $ hg fix -w -r . bar
1346 $ hg fix -w -r . bar
1326 $ hg cat -r tip bar ../quux
1347 $ hg cat -r tip bar ../quux
1327 $TESTTMP/subprocesscwd
1348 $TESTTMP/subprocesscwd
1328 quux
1349 quux
1329 $ cat bar ../quux
1350 $ cat bar ../quux
1330 $TESTTMP/subprocesscwd
1351 $TESTTMP/subprocesscwd
1331 quux
1352 quux
1332 $ echo modified > bar
1353 $ echo modified > bar
1333 $ hg fix -w bar
1354 $ hg fix -w bar
1334 $ cat bar
1355 $ cat bar
1335 $TESTTMP/subprocesscwd
1356 $TESTTMP/subprocesscwd
1336
1357
1337 Apparently fixing p1() and its descendants doesn't include wdir() unless
1358 Apparently fixing p1() and its descendants doesn't include wdir() unless
1338 explicitly stated.
1359 explicitly stated.
1339
1360
1340 $ hg fix -r '.::'
1361 $ hg fix -r '.::'
1341 $ hg cat -r . ../quux
1362 $ hg cat -r . ../quux
1342 quux
1363 quux
1343 $ hg cat -r tip ../quux
1364 $ hg cat -r tip ../quux
1344 fs: $TESTTMP/subprocesscwd
1365 fs: $TESTTMP/subprocesscwd
1345 $ cat ../quux
1366 $ cat ../quux
1346 quux
1367 quux
1347
1368
1348 Clean files are not fixed unless explicitly named
1369 Clean files are not fixed unless explicitly named
1349 $ echo 'dirty' > ../quux
1370 $ echo 'dirty' > ../quux
1350
1371
1351 $ hg fix --working-dir
1372 $ hg fix --working-dir
1352 $ cat ../quux
1373 $ cat ../quux
1353 fs: $TESTTMP/subprocesscwd
1374 fs: $TESTTMP/subprocesscwd
1354
1375
1355 $ cd ../..
1376 $ cd ../..
1356
1377
1357 Tools configured without a pattern are ignored. It would be too dangerous to
1378 Tools configured without a pattern are ignored. It would be too dangerous to
1358 run them on all files, because this might happen while testing a configuration
1379 run them on all files, because this might happen while testing a configuration
1359 that also deletes all of the file content. There is no reasonable subset of the
1380 that also deletes all of the file content. There is no reasonable subset of the
1360 files to use as a default. Users should be explicit about what files are
1381 files to use as a default. Users should be explicit about what files are
1361 affected by a tool. This test also confirms that we don't crash when the
1382 affected by a tool. This test also confirms that we don't crash when the
1362 pattern config is missing, and that we only warn about it once.
1383 pattern config is missing, and that we only warn about it once.
1363
1384
1364 $ hg init nopatternconfigured
1385 $ hg init nopatternconfigured
1365 $ cd nopatternconfigured
1386 $ cd nopatternconfigured
1366
1387
1367 $ printf "foo" > foo
1388 $ printf "foo" > foo
1368 $ printf "bar" > bar
1389 $ printf "bar" > bar
1369 $ hg add -q
1390 $ hg add -q
1370 $ hg fix --debug --working-dir --config "fix.nopattern:command=echo fixed"
1391 $ hg fix --debug --working-dir --config "fix.nopattern:command=echo fixed"
1371 fixer tool has no pattern configuration: nopattern
1392 fixer tool has no pattern configuration: nopattern
1372 $ cat foo bar
1393 $ cat foo bar
1373 foobar (no-eol)
1394 foobar (no-eol)
1374 $ hg fix --debug --working-dir --config "fix.nocommand:pattern=foo.bar"
1395 $ hg fix --debug --working-dir --config "fix.nocommand:pattern=foo.bar"
1375 fixer tool has no command configuration: nocommand
1396 fixer tool has no command configuration: nocommand
1376
1397
1377 $ cd ..
1398 $ cd ..
1378
1399
1379 Tools can be disabled. Disabled tools do nothing but print a debug message.
1400 Tools can be disabled. Disabled tools do nothing but print a debug message.
1380
1401
1381 $ hg init disabled
1402 $ hg init disabled
1382 $ cd disabled
1403 $ cd disabled
1383
1404
1384 $ printf "foo\n" > foo
1405 $ printf "foo\n" > foo
1385 $ hg add -q
1406 $ hg add -q
1386 $ hg fix --debug --working-dir --config "fix.disabled:command=echo fixed" \
1407 $ hg fix --debug --working-dir --config "fix.disabled:command=echo fixed" \
1387 > --config "fix.disabled:pattern=foo" \
1408 > --config "fix.disabled:pattern=foo" \
1388 > --config "fix.disabled:enabled=false"
1409 > --config "fix.disabled:enabled=false"
1389 ignoring disabled fixer tool: disabled
1410 ignoring disabled fixer tool: disabled
1390 $ cat foo
1411 $ cat foo
1391 foo
1412 foo
1392
1413
1393 $ cd ..
1414 $ cd ..
1394
1415
1395 Test that we can configure a fixer to affect all files regardless of the cwd.
1416 Test that we can configure a fixer to affect all files regardless of the cwd.
1396 The way we invoke matching must not prohibit this.
1417 The way we invoke matching must not prohibit this.
1397
1418
1398 $ hg init affectallfiles
1419 $ hg init affectallfiles
1399 $ cd affectallfiles
1420 $ cd affectallfiles
1400
1421
1401 $ mkdir foo bar
1422 $ mkdir foo bar
1402 $ printf "foo" > foo/file
1423 $ printf "foo" > foo/file
1403 $ printf "bar" > bar/file
1424 $ printf "bar" > bar/file
1404 $ printf "baz" > baz_file
1425 $ printf "baz" > baz_file
1405 $ hg add -q
1426 $ hg add -q
1406
1427
1407 $ cd bar
1428 $ cd bar
1408 $ hg fix --working-dir --config "fix.cooltool:command=echo fixed" \
1429 $ hg fix --working-dir --config "fix.cooltool:command=echo fixed" \
1409 > --config "fix.cooltool:pattern=glob:**"
1430 > --config "fix.cooltool:pattern=glob:**"
1410 $ cd ..
1431 $ cd ..
1411
1432
1412 $ cat foo/file
1433 $ cat foo/file
1413 fixed
1434 fixed
1414 $ cat bar/file
1435 $ cat bar/file
1415 fixed
1436 fixed
1416 $ cat baz_file
1437 $ cat baz_file
1417 fixed
1438 fixed
1418
1439
1419 $ cd ..
1440 $ cd ..
1420
1441
1421 Tools should be able to run on unchanged files, even if they set :linerange.
1442 Tools should be able to run on unchanged files, even if they set :linerange.
1422 This includes a corner case where deleted chunks of a file are not considered
1443 This includes a corner case where deleted chunks of a file are not considered
1423 changes.
1444 changes.
1424
1445
1425 $ hg init skipclean
1446 $ hg init skipclean
1426 $ cd skipclean
1447 $ cd skipclean
1427
1448
1428 $ printf "a\nb\nc\n" > foo
1449 $ printf "a\nb\nc\n" > foo
1429 $ printf "a\nb\nc\n" > bar
1450 $ printf "a\nb\nc\n" > bar
1430 $ printf "a\nb\nc\n" > baz
1451 $ printf "a\nb\nc\n" > baz
1431 $ hg commit -Aqm "base"
1452 $ hg commit -Aqm "base"
1432
1453
1433 $ printf "a\nc\n" > foo
1454 $ printf "a\nc\n" > foo
1434 $ printf "a\nx\nc\n" > baz
1455 $ printf "a\nx\nc\n" > baz
1435
1456
1436 $ cat >> print.py <<EOF
1457 $ cat >> print.py <<EOF
1437 > import sys
1458 > import sys
1438 > for a in sys.argv[1:]:
1459 > for a in sys.argv[1:]:
1439 > print(a)
1460 > print(a)
1440 > EOF
1461 > EOF
1441
1462
1442 $ hg fix --working-dir foo bar baz \
1463 $ hg fix --working-dir foo bar baz \
1443 > --config "fix.changedlines:command=\"$PYTHON\" print.py \"Line ranges:\"" \
1464 > --config "fix.changedlines:command=\"$PYTHON\" print.py \"Line ranges:\"" \
1444 > --config 'fix.changedlines:linerange="{first} through {last}"' \
1465 > --config 'fix.changedlines:linerange="{first} through {last}"' \
1445 > --config 'fix.changedlines:pattern=glob:**' \
1466 > --config 'fix.changedlines:pattern=glob:**' \
1446 > --config 'fix.changedlines:skipclean=false'
1467 > --config 'fix.changedlines:skipclean=false'
1447
1468
1448 $ cat foo
1469 $ cat foo
1449 Line ranges:
1470 Line ranges:
1450 $ cat bar
1471 $ cat bar
1451 Line ranges:
1472 Line ranges:
1452 $ cat baz
1473 $ cat baz
1453 Line ranges:
1474 Line ranges:
1454 2 through 2
1475 2 through 2
1455
1476
1456 $ cd ..
1477 $ cd ..
1457
1478
1458 Test various cases around merges. We were previously dropping files if they were
1479 Test various cases around merges. We were previously dropping files if they were
1459 created on only the p2 side of the merge, so let's test permutations of:
1480 created on only the p2 side of the merge, so let's test permutations of:
1460 * added, was fixed
1481 * added, was fixed
1461 * added, considered for fixing but was already good
1482 * added, considered for fixing but was already good
1462 * added, not considered for fixing
1483 * added, not considered for fixing
1463 * modified, was fixed
1484 * modified, was fixed
1464 * modified, considered for fixing but was already good
1485 * modified, considered for fixing but was already good
1465 * modified, not considered for fixing
1486 * modified, not considered for fixing
1466
1487
1467 Before the bug was fixed where we would drop files, this test demonstrated the
1488 Before the bug was fixed where we would drop files, this test demonstrated the
1468 following issues:
1489 following issues:
1469 * new_in_r1.ignored, new_in_r1_already_good.changed, and
1490 * new_in_r1.ignored, new_in_r1_already_good.changed, and
1470 > mod_in_r1_already_good.changed were NOT in the manifest for the merge commit
1491 > mod_in_r1_already_good.changed were NOT in the manifest for the merge commit
1471 * mod_in_r1.ignored had its contents from r0, NOT r1.
1492 * mod_in_r1.ignored had its contents from r0, NOT r1.
1472
1493
1473 We're also setting a named branch for every commit to demonstrate that the
1494 We're also setting a named branch for every commit to demonstrate that the
1474 branch is kept intact and there aren't issues updating to another branch in the
1495 branch is kept intact and there aren't issues updating to another branch in the
1475 middle of fix.
1496 middle of fix.
1476
1497
1477 $ hg init merge_keeps_files
1498 $ hg init merge_keeps_files
1478 $ cd merge_keeps_files
1499 $ cd merge_keeps_files
1479 $ for f in r0 mod_in_r1 mod_in_r2 mod_in_merge mod_in_child; do
1500 $ for f in r0 mod_in_r1 mod_in_r2 mod_in_merge mod_in_child; do
1480 > for c in changed whole ignored; do
1501 > for c in changed whole ignored; do
1481 > printf "hello\n" > $f.$c
1502 > printf "hello\n" > $f.$c
1482 > done
1503 > done
1483 > printf "HELLO\n" > "mod_in_${f}_already_good.changed"
1504 > printf "HELLO\n" > "mod_in_${f}_already_good.changed"
1484 > done
1505 > done
1485 $ hg branch -q r0
1506 $ hg branch -q r0
1486 $ hg ci -Aqm 'r0'
1507 $ hg ci -Aqm 'r0'
1487 $ hg phase -p
1508 $ hg phase -p
1488 $ make_test_files() {
1509 $ make_test_files() {
1489 > printf "world\n" >> "mod_in_$1.changed"
1510 > printf "world\n" >> "mod_in_$1.changed"
1490 > printf "world\n" >> "mod_in_$1.whole"
1511 > printf "world\n" >> "mod_in_$1.whole"
1491 > printf "world\n" >> "mod_in_$1.ignored"
1512 > printf "world\n" >> "mod_in_$1.ignored"
1492 > printf "WORLD\n" >> "mod_in_$1_already_good.changed"
1513 > printf "WORLD\n" >> "mod_in_$1_already_good.changed"
1493 > printf "new in $1\n" > "new_in_$1.changed"
1514 > printf "new in $1\n" > "new_in_$1.changed"
1494 > printf "new in $1\n" > "new_in_$1.whole"
1515 > printf "new in $1\n" > "new_in_$1.whole"
1495 > printf "new in $1\n" > "new_in_$1.ignored"
1516 > printf "new in $1\n" > "new_in_$1.ignored"
1496 > printf "ALREADY GOOD, NEW IN THIS REV\n" > "new_in_$1_already_good.changed"
1517 > printf "ALREADY GOOD, NEW IN THIS REV\n" > "new_in_$1_already_good.changed"
1497 > }
1518 > }
1498 $ make_test_commit() {
1519 $ make_test_commit() {
1499 > make_test_files "$1"
1520 > make_test_files "$1"
1500 > hg branch -q "$1"
1521 > hg branch -q "$1"
1501 > hg ci -Aqm "$2"
1522 > hg ci -Aqm "$2"
1502 > }
1523 > }
1503 $ make_test_commit r1 "merge me, pt1"
1524 $ make_test_commit r1 "merge me, pt1"
1504 $ hg co -q ".^"
1525 $ hg co -q ".^"
1505 $ make_test_commit r2 "merge me, pt2"
1526 $ make_test_commit r2 "merge me, pt2"
1506 $ hg merge -qr 1
1527 $ hg merge -qr 1
1507 $ make_test_commit merge "evil merge"
1528 $ make_test_commit merge "evil merge"
1508 $ make_test_commit child "child of merge"
1529 $ make_test_commit child "child of merge"
1509 $ make_test_files wdir
1530 $ make_test_files wdir
1510 $ hg fix -r 'not public()' -w
1531 $ hg fix -r 'not public()' -w
1511 $ hg log -G -T'{rev}:{shortest(node,8)}: branch:{branch} desc:{desc}'
1532 $ hg log -G -T'{rev}:{shortest(node,8)}: branch:{branch} desc:{desc}'
1512 @ 8:c22ce900: branch:child desc:child of merge
1533 @ 8:c22ce900: branch:child desc:child of merge
1513 |
1534 |
1514 o 7:5a30615a: branch:merge desc:evil merge
1535 o 7:5a30615a: branch:merge desc:evil merge
1515 |\
1536 |\
1516 | o 6:4e5acdc4: branch:r2 desc:merge me, pt2
1537 | o 6:4e5acdc4: branch:r2 desc:merge me, pt2
1517 | |
1538 | |
1518 o | 5:eea01878: branch:r1 desc:merge me, pt1
1539 o | 5:eea01878: branch:r1 desc:merge me, pt1
1519 |/
1540 |/
1520 o 0:0c548d87: branch:r0 desc:r0
1541 o 0:0c548d87: branch:r0 desc:r0
1521
1542
1522 $ hg files -r tip
1543 $ hg files -r tip
1523 mod_in_child.changed
1544 mod_in_child.changed
1524 mod_in_child.ignored
1545 mod_in_child.ignored
1525 mod_in_child.whole
1546 mod_in_child.whole
1526 mod_in_child_already_good.changed
1547 mod_in_child_already_good.changed
1527 mod_in_merge.changed
1548 mod_in_merge.changed
1528 mod_in_merge.ignored
1549 mod_in_merge.ignored
1529 mod_in_merge.whole
1550 mod_in_merge.whole
1530 mod_in_merge_already_good.changed
1551 mod_in_merge_already_good.changed
1531 mod_in_mod_in_child_already_good.changed
1552 mod_in_mod_in_child_already_good.changed
1532 mod_in_mod_in_merge_already_good.changed
1553 mod_in_mod_in_merge_already_good.changed
1533 mod_in_mod_in_r1_already_good.changed
1554 mod_in_mod_in_r1_already_good.changed
1534 mod_in_mod_in_r2_already_good.changed
1555 mod_in_mod_in_r2_already_good.changed
1535 mod_in_r0_already_good.changed
1556 mod_in_r0_already_good.changed
1536 mod_in_r1.changed
1557 mod_in_r1.changed
1537 mod_in_r1.ignored
1558 mod_in_r1.ignored
1538 mod_in_r1.whole
1559 mod_in_r1.whole
1539 mod_in_r1_already_good.changed
1560 mod_in_r1_already_good.changed
1540 mod_in_r2.changed
1561 mod_in_r2.changed
1541 mod_in_r2.ignored
1562 mod_in_r2.ignored
1542 mod_in_r2.whole
1563 mod_in_r2.whole
1543 mod_in_r2_already_good.changed
1564 mod_in_r2_already_good.changed
1544 new_in_child.changed
1565 new_in_child.changed
1545 new_in_child.ignored
1566 new_in_child.ignored
1546 new_in_child.whole
1567 new_in_child.whole
1547 new_in_child_already_good.changed
1568 new_in_child_already_good.changed
1548 new_in_merge.changed
1569 new_in_merge.changed
1549 new_in_merge.ignored
1570 new_in_merge.ignored
1550 new_in_merge.whole
1571 new_in_merge.whole
1551 new_in_merge_already_good.changed
1572 new_in_merge_already_good.changed
1552 new_in_r1.changed
1573 new_in_r1.changed
1553 new_in_r1.ignored
1574 new_in_r1.ignored
1554 new_in_r1.whole
1575 new_in_r1.whole
1555 new_in_r1_already_good.changed
1576 new_in_r1_already_good.changed
1556 new_in_r2.changed
1577 new_in_r2.changed
1557 new_in_r2.ignored
1578 new_in_r2.ignored
1558 new_in_r2.whole
1579 new_in_r2.whole
1559 new_in_r2_already_good.changed
1580 new_in_r2_already_good.changed
1560 r0.changed
1581 r0.changed
1561 r0.ignored
1582 r0.ignored
1562 r0.whole
1583 r0.whole
1563 $ for f in "$(hg files -r tip)"; do hg cat -r tip $f -T'{path}:\n{data}\n'; done
1584 $ for f in "$(hg files -r tip)"; do hg cat -r tip $f -T'{path}:\n{data}\n'; done
1564 mod_in_child.changed:
1585 mod_in_child.changed:
1565 hello
1586 hello
1566 WORLD
1587 WORLD
1567
1588
1568 mod_in_child.ignored:
1589 mod_in_child.ignored:
1569 hello
1590 hello
1570 world
1591 world
1571
1592
1572 mod_in_child.whole:
1593 mod_in_child.whole:
1573 HELLO
1594 HELLO
1574 WORLD
1595 WORLD
1575
1596
1576 mod_in_child_already_good.changed:
1597 mod_in_child_already_good.changed:
1577 WORLD
1598 WORLD
1578
1599
1579 mod_in_merge.changed:
1600 mod_in_merge.changed:
1580 hello
1601 hello
1581 WORLD
1602 WORLD
1582
1603
1583 mod_in_merge.ignored:
1604 mod_in_merge.ignored:
1584 hello
1605 hello
1585 world
1606 world
1586
1607
1587 mod_in_merge.whole:
1608 mod_in_merge.whole:
1588 HELLO
1609 HELLO
1589 WORLD
1610 WORLD
1590
1611
1591 mod_in_merge_already_good.changed:
1612 mod_in_merge_already_good.changed:
1592 WORLD
1613 WORLD
1593
1614
1594 mod_in_mod_in_child_already_good.changed:
1615 mod_in_mod_in_child_already_good.changed:
1595 HELLO
1616 HELLO
1596
1617
1597 mod_in_mod_in_merge_already_good.changed:
1618 mod_in_mod_in_merge_already_good.changed:
1598 HELLO
1619 HELLO
1599
1620
1600 mod_in_mod_in_r1_already_good.changed:
1621 mod_in_mod_in_r1_already_good.changed:
1601 HELLO
1622 HELLO
1602
1623
1603 mod_in_mod_in_r2_already_good.changed:
1624 mod_in_mod_in_r2_already_good.changed:
1604 HELLO
1625 HELLO
1605
1626
1606 mod_in_r0_already_good.changed:
1627 mod_in_r0_already_good.changed:
1607 HELLO
1628 HELLO
1608
1629
1609 mod_in_r1.changed:
1630 mod_in_r1.changed:
1610 hello
1631 hello
1611 WORLD
1632 WORLD
1612
1633
1613 mod_in_r1.ignored:
1634 mod_in_r1.ignored:
1614 hello
1635 hello
1615 world
1636 world
1616
1637
1617 mod_in_r1.whole:
1638 mod_in_r1.whole:
1618 HELLO
1639 HELLO
1619 WORLD
1640 WORLD
1620
1641
1621 mod_in_r1_already_good.changed:
1642 mod_in_r1_already_good.changed:
1622 WORLD
1643 WORLD
1623
1644
1624 mod_in_r2.changed:
1645 mod_in_r2.changed:
1625 hello
1646 hello
1626 WORLD
1647 WORLD
1627
1648
1628 mod_in_r2.ignored:
1649 mod_in_r2.ignored:
1629 hello
1650 hello
1630 world
1651 world
1631
1652
1632 mod_in_r2.whole:
1653 mod_in_r2.whole:
1633 HELLO
1654 HELLO
1634 WORLD
1655 WORLD
1635
1656
1636 mod_in_r2_already_good.changed:
1657 mod_in_r2_already_good.changed:
1637 WORLD
1658 WORLD
1638
1659
1639 new_in_child.changed:
1660 new_in_child.changed:
1640 NEW IN CHILD
1661 NEW IN CHILD
1641
1662
1642 new_in_child.ignored:
1663 new_in_child.ignored:
1643 new in child
1664 new in child
1644
1665
1645 new_in_child.whole:
1666 new_in_child.whole:
1646 NEW IN CHILD
1667 NEW IN CHILD
1647
1668
1648 new_in_child_already_good.changed:
1669 new_in_child_already_good.changed:
1649 ALREADY GOOD, NEW IN THIS REV
1670 ALREADY GOOD, NEW IN THIS REV
1650
1671
1651 new_in_merge.changed:
1672 new_in_merge.changed:
1652 NEW IN MERGE
1673 NEW IN MERGE
1653
1674
1654 new_in_merge.ignored:
1675 new_in_merge.ignored:
1655 new in merge
1676 new in merge
1656
1677
1657 new_in_merge.whole:
1678 new_in_merge.whole:
1658 NEW IN MERGE
1679 NEW IN MERGE
1659
1680
1660 new_in_merge_already_good.changed:
1681 new_in_merge_already_good.changed:
1661 ALREADY GOOD, NEW IN THIS REV
1682 ALREADY GOOD, NEW IN THIS REV
1662
1683
1663 new_in_r1.changed:
1684 new_in_r1.changed:
1664 NEW IN R1
1685 NEW IN R1
1665
1686
1666 new_in_r1.ignored:
1687 new_in_r1.ignored:
1667 new in r1
1688 new in r1
1668
1689
1669 new_in_r1.whole:
1690 new_in_r1.whole:
1670 NEW IN R1
1691 NEW IN R1
1671
1692
1672 new_in_r1_already_good.changed:
1693 new_in_r1_already_good.changed:
1673 ALREADY GOOD, NEW IN THIS REV
1694 ALREADY GOOD, NEW IN THIS REV
1674
1695
1675 new_in_r2.changed:
1696 new_in_r2.changed:
1676 NEW IN R2
1697 NEW IN R2
1677
1698
1678 new_in_r2.ignored:
1699 new_in_r2.ignored:
1679 new in r2
1700 new in r2
1680
1701
1681 new_in_r2.whole:
1702 new_in_r2.whole:
1682 NEW IN R2
1703 NEW IN R2
1683
1704
1684 new_in_r2_already_good.changed:
1705 new_in_r2_already_good.changed:
1685 ALREADY GOOD, NEW IN THIS REV
1706 ALREADY GOOD, NEW IN THIS REV
1686
1707
1687 r0.changed:
1708 r0.changed:
1688 hello
1709 hello
1689
1710
1690 r0.ignored:
1711 r0.ignored:
1691 hello
1712 hello
1692
1713
1693 r0.whole:
1714 r0.whole:
1694 hello
1715 hello
1695
1716
General Comments 0
You need to be logged in to leave comments. Login now