##// END OF EJS Templates
cleanup: use revision numbers instead of hashes in test output...
Danny Hooper -
r40603:19e1c262 default
parent child Browse files
Show More
@@ -1,1197 +1,1197 b''
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 sys
6 > import sys
7 > from mercurial.utils.procutil import setbinary
7 > from mercurial.utils.procutil import setbinary
8 > setbinary(sys.stdin)
8 > setbinary(sys.stdin)
9 > setbinary(sys.stdout)
9 > setbinary(sys.stdout)
10 > lines = set()
10 > lines = set()
11 > for arg in sys.argv[1:]:
11 > for arg in sys.argv[1:]:
12 > if arg == 'all':
12 > if arg == 'all':
13 > sys.stdout.write(sys.stdin.read().upper())
13 > sys.stdout.write(sys.stdin.read().upper())
14 > sys.exit(0)
14 > sys.exit(0)
15 > else:
15 > else:
16 > first, last = arg.split('-')
16 > first, last = arg.split('-')
17 > lines.update(range(int(first), int(last) + 1))
17 > lines.update(range(int(first), int(last) + 1))
18 > for i, line in enumerate(sys.stdin.readlines()):
18 > for i, line in enumerate(sys.stdin.readlines()):
19 > if i + 1 in lines:
19 > if i + 1 in lines:
20 > sys.stdout.write(line.upper())
20 > sys.stdout.write(line.upper())
21 > else:
21 > else:
22 > sys.stdout.write(line)
22 > sys.stdout.write(line)
23 > EOF
23 > EOF
24 $ TESTLINES="foo\nbar\nbaz\nqux\n"
24 $ TESTLINES="foo\nbar\nbaz\nqux\n"
25 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY
25 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY
26 foo
26 foo
27 bar
27 bar
28 baz
28 baz
29 qux
29 qux
30 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY all
30 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY all
31 FOO
31 FOO
32 BAR
32 BAR
33 BAZ
33 BAZ
34 QUX
34 QUX
35 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 1-1
35 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 1-1
36 FOO
36 FOO
37 bar
37 bar
38 baz
38 baz
39 qux
39 qux
40 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 1-2
40 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 1-2
41 FOO
41 FOO
42 BAR
42 BAR
43 baz
43 baz
44 qux
44 qux
45 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 2-3
45 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 2-3
46 foo
46 foo
47 BAR
47 BAR
48 BAZ
48 BAZ
49 qux
49 qux
50 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 2-2 4-4
50 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 2-2 4-4
51 foo
51 foo
52 BAR
52 BAR
53 baz
53 baz
54 QUX
54 QUX
55
55
56 Set up the config with two simple fixers: one that fixes specific line ranges,
56 Set up the config with two simple fixers: one that fixes specific line ranges,
57 and one that always fixes the whole file. They both "fix" files by converting
57 and one that always fixes the whole file. They both "fix" files by converting
58 letters to uppercase. They use different file extensions, so each test case can
58 letters to uppercase. They use different file extensions, so each test case can
59 choose which behavior to use by naming files.
59 choose which behavior to use by naming files.
60
60
61 $ cat >> $HGRCPATH <<EOF
61 $ cat >> $HGRCPATH <<EOF
62 > [extensions]
62 > [extensions]
63 > fix =
63 > fix =
64 > [experimental]
64 > [experimental]
65 > evolution.createmarkers=True
65 > evolution.createmarkers=True
66 > evolution.allowunstable=True
66 > evolution.allowunstable=True
67 > [fix]
67 > [fix]
68 > uppercase-whole-file:command="$PYTHON" $UPPERCASEPY all
68 > uppercase-whole-file:command="$PYTHON" $UPPERCASEPY all
69 > uppercase-whole-file:pattern=set:**.whole
69 > uppercase-whole-file:pattern=set:**.whole
70 > uppercase-changed-lines:command="$PYTHON" $UPPERCASEPY
70 > uppercase-changed-lines:command="$PYTHON" $UPPERCASEPY
71 > uppercase-changed-lines:linerange={first}-{last}
71 > uppercase-changed-lines:linerange={first}-{last}
72 > uppercase-changed-lines:pattern=set:**.changed
72 > uppercase-changed-lines:pattern=set:**.changed
73 > EOF
73 > EOF
74
74
75 Help text for fix.
75 Help text for fix.
76
76
77 $ hg help fix
77 $ hg help fix
78 hg fix [OPTION]... [FILE]...
78 hg fix [OPTION]... [FILE]...
79
79
80 rewrite file content in changesets or working directory
80 rewrite file content in changesets or working directory
81
81
82 Runs any configured tools to fix the content of files. Only affects files
82 Runs any configured tools to fix the content of files. Only affects files
83 with changes, unless file arguments are provided. Only affects changed
83 with changes, unless file arguments are provided. Only affects changed
84 lines of files, unless the --whole flag is used. Some tools may always
84 lines of files, unless the --whole flag is used. Some tools may always
85 affect the whole file regardless of --whole.
85 affect the whole file regardless of --whole.
86
86
87 If revisions are specified with --rev, those revisions will be checked,
87 If revisions are specified with --rev, those revisions will be checked,
88 and they may be replaced with new revisions that have fixed file content.
88 and they may be replaced with new revisions that have fixed file content.
89 It is desirable to specify all descendants of each specified revision, so
89 It is desirable to specify all descendants of each specified revision, so
90 that the fixes propagate to the descendants. If all descendants are fixed
90 that the fixes propagate to the descendants. If all descendants are fixed
91 at the same time, no merging, rebasing, or evolution will be required.
91 at the same time, no merging, rebasing, or evolution will be required.
92
92
93 If --working-dir is used, files with uncommitted changes in the working
93 If --working-dir is used, files with uncommitted changes in the working
94 copy will be fixed. If the checked-out revision is also fixed, the working
94 copy will be fixed. If the checked-out revision is also fixed, the working
95 directory will update to the replacement revision.
95 directory will update to the replacement revision.
96
96
97 When determining what lines of each file to fix at each revision, the
97 When determining what lines of each file to fix at each revision, the
98 whole set of revisions being fixed is considered, so that fixes to earlier
98 whole set of revisions being fixed is considered, so that fixes to earlier
99 revisions are not forgotten in later ones. The --base flag can be used to
99 revisions are not forgotten in later ones. The --base flag can be used to
100 override this default behavior, though it is not usually desirable to do
100 override this default behavior, though it is not usually desirable to do
101 so.
101 so.
102
102
103 (use 'hg help -e fix' to show help for the fix extension)
103 (use 'hg help -e fix' to show help for the fix extension)
104
104
105 options ([+] can be repeated):
105 options ([+] can be repeated):
106
106
107 --all fix all non-public non-obsolete revisions
107 --all fix all non-public non-obsolete revisions
108 --base REV [+] revisions to diff against (overrides automatic selection,
108 --base REV [+] revisions to diff against (overrides automatic selection,
109 and applies to every revision being fixed)
109 and applies to every revision being fixed)
110 -r --rev REV [+] revisions to fix
110 -r --rev REV [+] revisions to fix
111 -w --working-dir fix the working directory
111 -w --working-dir fix the working directory
112 --whole always fix every line of a file
112 --whole always fix every line of a file
113
113
114 (some details hidden, use --verbose to show complete help)
114 (some details hidden, use --verbose to show complete help)
115
115
116 $ hg help -e fix
116 $ hg help -e fix
117 fix extension - rewrite file content in changesets or working copy
117 fix extension - rewrite file content in changesets or working copy
118 (EXPERIMENTAL)
118 (EXPERIMENTAL)
119
119
120 Provides a command that runs configured tools on the contents of modified
120 Provides a command that runs configured tools on the contents of modified
121 files, writing back any fixes to the working copy or replacing changesets.
121 files, writing back any fixes to the working copy or replacing changesets.
122
122
123 Here is an example configuration that causes 'hg fix' to apply automatic
123 Here is an example configuration that causes 'hg fix' to apply automatic
124 formatting fixes to modified lines in C++ code:
124 formatting fixes to modified lines in C++ code:
125
125
126 [fix]
126 [fix]
127 clang-format:command=clang-format --assume-filename={rootpath}
127 clang-format:command=clang-format --assume-filename={rootpath}
128 clang-format:linerange=--lines={first}:{last}
128 clang-format:linerange=--lines={first}:{last}
129 clang-format:pattern=set:**.cpp or **.hpp
129 clang-format:pattern=set:**.cpp or **.hpp
130
130
131 The :command suboption forms the first part of the shell command that will be
131 The :command suboption forms the first part of the shell command that will be
132 used to fix a file. The content of the file is passed on standard input, and
132 used to fix a file. The content of the file is passed on standard input, and
133 the fixed file content is expected on standard output. Any output on standard
133 the fixed file content is expected on standard output. Any output on standard
134 error will be displayed as a warning. If the exit status is not zero, the file
134 error will be displayed as a warning. If the exit status is not zero, the file
135 will not be affected. A placeholder warning is displayed if there is a non-
135 will not be affected. A placeholder warning is displayed if there is a non-
136 zero exit status but no standard error output. Some values may be substituted
136 zero exit status but no standard error output. Some values may be substituted
137 into the command:
137 into the command:
138
138
139 {rootpath} The path of the file being fixed, relative to the repo root
139 {rootpath} The path of the file being fixed, relative to the repo root
140 {basename} The name of the file being fixed, without the directory path
140 {basename} The name of the file being fixed, without the directory path
141
141
142 If the :linerange suboption is set, the tool will only be run if there are
142 If the :linerange suboption is set, the tool will only be run if there are
143 changed lines in a file. The value of this suboption is appended to the shell
143 changed lines in a file. The value of this suboption is appended to the shell
144 command once for every range of changed lines in the file. Some values may be
144 command once for every range of changed lines in the file. Some values may be
145 substituted into the command:
145 substituted into the command:
146
146
147 {first} The 1-based line number of the first line in the modified range
147 {first} The 1-based line number of the first line in the modified range
148 {last} The 1-based line number of the last line in the modified range
148 {last} The 1-based line number of the last line in the modified range
149
149
150 The :pattern suboption determines which files will be passed through each
150 The :pattern suboption determines which files will be passed through each
151 configured tool. See 'hg help patterns' for possible values. If there are file
151 configured tool. See 'hg help patterns' for possible values. If there are file
152 arguments to 'hg fix', the intersection of these patterns is used.
152 arguments to 'hg fix', the intersection of these patterns is used.
153
153
154 There is also a configurable limit for the maximum size of file that will be
154 There is also a configurable limit for the maximum size of file that will be
155 processed by 'hg fix':
155 processed by 'hg fix':
156
156
157 [fix]
157 [fix]
158 maxfilesize = 2MB
158 maxfilesize = 2MB
159
159
160 Normally, execution of configured tools will continue after a failure
160 Normally, execution of configured tools will continue after a failure
161 (indicated by a non-zero exit status). It can also be configured to abort
161 (indicated by a non-zero exit status). It can also be configured to abort
162 after the first such failure, so that no files will be affected if any tool
162 after the first such failure, so that no files will be affected if any tool
163 fails. This abort will also cause 'hg fix' to exit with a non-zero status:
163 fails. This abort will also cause 'hg fix' to exit with a non-zero status:
164
164
165 [fix]
165 [fix]
166 failure = abort
166 failure = abort
167
167
168 When multiple tools are configured to affect a file, they execute in an order
168 When multiple tools are configured to affect a file, they execute in an order
169 defined by the :priority suboption. The priority suboption has a default value
169 defined by the :priority suboption. The priority suboption has a default value
170 of zero for each tool. Tools are executed in order of descending priority. The
170 of zero for each tool. Tools are executed in order of descending priority. The
171 execution order of tools with equal priority is unspecified. For example, you
171 execution order of tools with equal priority is unspecified. For example, you
172 could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers
172 could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers
173 in a text file by ensuring that 'sort' runs before 'head':
173 in a text file by ensuring that 'sort' runs before 'head':
174
174
175 [fix]
175 [fix]
176 sort:command = sort --numeric-sort
176 sort:command = sort --numeric-sort
177 head:command = head --lines=10
177 head:command = head --lines=10
178 sort:pattern = numbers.txt
178 sort:pattern = numbers.txt
179 head:pattern = numbers.txt
179 head:pattern = numbers.txt
180 sort:priority = 2
180 sort:priority = 2
181 head:priority = 1
181 head:priority = 1
182
182
183 To account for changes made by each tool, the line numbers used for
183 To account for changes made by each tool, the line numbers used for
184 incremental formatting are recomputed before executing the next tool. So, each
184 incremental formatting are recomputed before executing the next tool. So, each
185 tool may see different values for the arguments added by the :linerange
185 tool may see different values for the arguments added by the :linerange
186 suboption.
186 suboption.
187
187
188 list of commands:
188 list of commands:
189
189
190 fix rewrite file content in changesets or working directory
190 fix rewrite file content in changesets or working directory
191
191
192 (use 'hg help -v -e fix' to show built-in aliases and global options)
192 (use 'hg help -v -e fix' to show built-in aliases and global options)
193
193
194 There is no default behavior in the absence of --rev and --working-dir.
194 There is no default behavior in the absence of --rev and --working-dir.
195
195
196 $ hg init badusage
196 $ hg init badusage
197 $ cd badusage
197 $ cd badusage
198
198
199 $ hg fix
199 $ hg fix
200 abort: no changesets specified
200 abort: no changesets specified
201 (use --rev or --working-dir)
201 (use --rev or --working-dir)
202 [255]
202 [255]
203 $ hg fix --whole
203 $ hg fix --whole
204 abort: no changesets specified
204 abort: no changesets specified
205 (use --rev or --working-dir)
205 (use --rev or --working-dir)
206 [255]
206 [255]
207 $ hg fix --base 0
207 $ hg fix --base 0
208 abort: no changesets specified
208 abort: no changesets specified
209 (use --rev or --working-dir)
209 (use --rev or --working-dir)
210 [255]
210 [255]
211
211
212 Fixing a public revision isn't allowed. It should abort early enough that
212 Fixing a public revision isn't allowed. It should abort early enough that
213 nothing happens, even to the working directory.
213 nothing happens, even to the working directory.
214
214
215 $ printf "hello\n" > hello.whole
215 $ printf "hello\n" > hello.whole
216 $ hg commit -Aqm "hello"
216 $ hg commit -Aqm "hello"
217 $ hg phase -r 0 --public
217 $ hg phase -r 0 --public
218 $ hg fix -r 0
218 $ hg fix -r 0
219 abort: can't fix immutable changeset 0:6470986d2e7b
219 abort: can't fix immutable changeset 0:6470986d2e7b
220 [255]
220 [255]
221 $ hg fix -r 0 --working-dir
221 $ hg fix -r 0 --working-dir
222 abort: can't fix immutable changeset 0:6470986d2e7b
222 abort: can't fix immutable changeset 0:6470986d2e7b
223 [255]
223 [255]
224 $ hg cat -r tip hello.whole
224 $ hg cat -r tip hello.whole
225 hello
225 hello
226 $ cat hello.whole
226 $ cat hello.whole
227 hello
227 hello
228
228
229 $ cd ..
229 $ cd ..
230
230
231 Fixing a clean working directory should do nothing. Even the --whole flag
231 Fixing a clean working directory should do nothing. Even the --whole flag
232 shouldn't cause any clean files to be fixed. Specifying a clean file explicitly
232 shouldn't cause any clean files to be fixed. Specifying a clean file explicitly
233 should only fix it if the fixer always fixes the whole file. The combination of
233 should only fix it if the fixer always fixes the whole file. The combination of
234 an explicit filename and --whole should format the entire file regardless.
234 an explicit filename and --whole should format the entire file regardless.
235
235
236 $ hg init fixcleanwdir
236 $ hg init fixcleanwdir
237 $ cd fixcleanwdir
237 $ cd fixcleanwdir
238
238
239 $ printf "hello\n" > hello.changed
239 $ printf "hello\n" > hello.changed
240 $ printf "world\n" > hello.whole
240 $ printf "world\n" > hello.whole
241 $ hg commit -Aqm "foo"
241 $ hg commit -Aqm "foo"
242 $ hg fix --working-dir
242 $ hg fix --working-dir
243 $ hg diff
243 $ hg diff
244 $ hg fix --working-dir --whole
244 $ hg fix --working-dir --whole
245 $ hg diff
245 $ hg diff
246 $ hg fix --working-dir *
246 $ hg fix --working-dir *
247 $ cat *
247 $ cat *
248 hello
248 hello
249 WORLD
249 WORLD
250 $ hg revert --all --no-backup
250 $ hg revert --all --no-backup
251 reverting hello.whole
251 reverting hello.whole
252 $ hg fix --working-dir * --whole
252 $ hg fix --working-dir * --whole
253 $ cat *
253 $ cat *
254 HELLO
254 HELLO
255 WORLD
255 WORLD
256
256
257 The same ideas apply to fixing a revision, so we create a revision that doesn't
257 The same ideas apply to fixing a revision, so we create a revision that doesn't
258 modify either of the files in question and try fixing it. This also tests that
258 modify either of the files in question and try fixing it. This also tests that
259 we ignore a file that doesn't match any configured fixer.
259 we ignore a file that doesn't match any configured fixer.
260
260
261 $ hg revert --all --no-backup
261 $ hg revert --all --no-backup
262 reverting hello.changed
262 reverting hello.changed
263 reverting hello.whole
263 reverting hello.whole
264 $ printf "unimportant\n" > some.file
264 $ printf "unimportant\n" > some.file
265 $ hg commit -Aqm "some other file"
265 $ hg commit -Aqm "some other file"
266
266
267 $ hg fix -r .
267 $ hg fix -r .
268 $ hg cat -r tip *
268 $ hg cat -r tip *
269 hello
269 hello
270 world
270 world
271 unimportant
271 unimportant
272 $ hg fix -r . --whole
272 $ hg fix -r . --whole
273 $ hg cat -r tip *
273 $ hg cat -r tip *
274 hello
274 hello
275 world
275 world
276 unimportant
276 unimportant
277 $ hg fix -r . *
277 $ hg fix -r . *
278 $ hg cat -r tip *
278 $ hg cat -r tip *
279 hello
279 hello
280 WORLD
280 WORLD
281 unimportant
281 unimportant
282 $ hg fix -r . * --whole --config experimental.evolution.allowdivergence=true
282 $ hg fix -r . * --whole --config experimental.evolution.allowdivergence=true
283 2 new content-divergent changesets
283 2 new content-divergent changesets
284 $ hg cat -r tip *
284 $ hg cat -r tip *
285 HELLO
285 HELLO
286 WORLD
286 WORLD
287 unimportant
287 unimportant
288
288
289 $ cd ..
289 $ cd ..
290
290
291 Fixing the working directory should still work if there are no revisions.
291 Fixing the working directory should still work if there are no revisions.
292
292
293 $ hg init norevisions
293 $ hg init norevisions
294 $ cd norevisions
294 $ cd norevisions
295
295
296 $ printf "something\n" > something.whole
296 $ printf "something\n" > something.whole
297 $ hg add
297 $ hg add
298 adding something.whole
298 adding something.whole
299 $ hg fix --working-dir
299 $ hg fix --working-dir
300 $ cat something.whole
300 $ cat something.whole
301 SOMETHING
301 SOMETHING
302
302
303 $ cd ..
303 $ cd ..
304
304
305 Test the effect of fixing the working directory for each possible status, with
305 Test the effect of fixing the working directory for each possible status, with
306 and without providing explicit file arguments.
306 and without providing explicit file arguments.
307
307
308 $ hg init implicitlyfixstatus
308 $ hg init implicitlyfixstatus
309 $ cd implicitlyfixstatus
309 $ cd implicitlyfixstatus
310
310
311 $ printf "modified\n" > modified.whole
311 $ printf "modified\n" > modified.whole
312 $ printf "removed\n" > removed.whole
312 $ printf "removed\n" > removed.whole
313 $ printf "deleted\n" > deleted.whole
313 $ printf "deleted\n" > deleted.whole
314 $ printf "clean\n" > clean.whole
314 $ printf "clean\n" > clean.whole
315 $ printf "ignored.whole" > .hgignore
315 $ printf "ignored.whole" > .hgignore
316 $ hg commit -Aqm "stuff"
316 $ hg commit -Aqm "stuff"
317
317
318 $ printf "modified!!!\n" > modified.whole
318 $ printf "modified!!!\n" > modified.whole
319 $ printf "unknown\n" > unknown.whole
319 $ printf "unknown\n" > unknown.whole
320 $ printf "ignored\n" > ignored.whole
320 $ printf "ignored\n" > ignored.whole
321 $ printf "added\n" > added.whole
321 $ printf "added\n" > added.whole
322 $ hg add added.whole
322 $ hg add added.whole
323 $ hg remove removed.whole
323 $ hg remove removed.whole
324 $ rm deleted.whole
324 $ rm deleted.whole
325
325
326 $ hg status --all
326 $ hg status --all
327 M modified.whole
327 M modified.whole
328 A added.whole
328 A added.whole
329 R removed.whole
329 R removed.whole
330 ! deleted.whole
330 ! deleted.whole
331 ? unknown.whole
331 ? unknown.whole
332 I ignored.whole
332 I ignored.whole
333 C .hgignore
333 C .hgignore
334 C clean.whole
334 C clean.whole
335
335
336 $ hg fix --working-dir
336 $ hg fix --working-dir
337
337
338 $ hg status --all
338 $ hg status --all
339 M modified.whole
339 M modified.whole
340 A added.whole
340 A added.whole
341 R removed.whole
341 R removed.whole
342 ! deleted.whole
342 ! deleted.whole
343 ? unknown.whole
343 ? unknown.whole
344 I ignored.whole
344 I ignored.whole
345 C .hgignore
345 C .hgignore
346 C clean.whole
346 C clean.whole
347
347
348 $ cat *.whole
348 $ cat *.whole
349 ADDED
349 ADDED
350 clean
350 clean
351 ignored
351 ignored
352 MODIFIED!!!
352 MODIFIED!!!
353 unknown
353 unknown
354
354
355 $ printf "modified!!!\n" > modified.whole
355 $ printf "modified!!!\n" > modified.whole
356 $ printf "added\n" > added.whole
356 $ printf "added\n" > added.whole
357 $ hg fix --working-dir *.whole
357 $ hg fix --working-dir *.whole
358
358
359 $ hg status --all
359 $ hg status --all
360 M clean.whole
360 M clean.whole
361 M modified.whole
361 M modified.whole
362 A added.whole
362 A added.whole
363 R removed.whole
363 R removed.whole
364 ! deleted.whole
364 ! deleted.whole
365 ? unknown.whole
365 ? unknown.whole
366 I ignored.whole
366 I ignored.whole
367 C .hgignore
367 C .hgignore
368
368
369 It would be better if this also fixed the unknown file.
369 It would be better if this also fixed the unknown file.
370 $ cat *.whole
370 $ cat *.whole
371 ADDED
371 ADDED
372 CLEAN
372 CLEAN
373 ignored
373 ignored
374 MODIFIED!!!
374 MODIFIED!!!
375 unknown
375 unknown
376
376
377 $ cd ..
377 $ cd ..
378
378
379 Test that incremental fixing works on files with additions, deletions, and
379 Test that incremental fixing works on files with additions, deletions, and
380 changes in multiple line ranges. Note that deletions do not generally cause
380 changes in multiple line ranges. Note that deletions do not generally cause
381 neighboring lines to be fixed, so we don't return a line range for purely
381 neighboring lines to be fixed, so we don't return a line range for purely
382 deleted sections. In the future we should support a :deletion config that
382 deleted sections. In the future we should support a :deletion config that
383 allows fixers to know where deletions are located.
383 allows fixers to know where deletions are located.
384
384
385 $ hg init incrementalfixedlines
385 $ hg init incrementalfixedlines
386 $ cd incrementalfixedlines
386 $ cd incrementalfixedlines
387
387
388 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.txt
388 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.txt
389 $ hg commit -Aqm "foo"
389 $ hg commit -Aqm "foo"
390 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.txt
390 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.txt
391
391
392 $ hg --config "fix.fail:command=echo" \
392 $ hg --config "fix.fail:command=echo" \
393 > --config "fix.fail:linerange={first}:{last}" \
393 > --config "fix.fail:linerange={first}:{last}" \
394 > --config "fix.fail:pattern=foo.txt" \
394 > --config "fix.fail:pattern=foo.txt" \
395 > fix --working-dir
395 > fix --working-dir
396 $ cat foo.txt
396 $ cat foo.txt
397 1:1 4:6 8:8
397 1:1 4:6 8:8
398
398
399 $ cd ..
399 $ cd ..
400
400
401 Test that --whole fixes all lines regardless of the diffs present.
401 Test that --whole fixes all lines regardless of the diffs present.
402
402
403 $ hg init wholeignoresdiffs
403 $ hg init wholeignoresdiffs
404 $ cd wholeignoresdiffs
404 $ cd wholeignoresdiffs
405
405
406 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.changed
406 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.changed
407 $ hg commit -Aqm "foo"
407 $ hg commit -Aqm "foo"
408 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.changed
408 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.changed
409 $ hg fix --working-dir --whole
409 $ hg fix --working-dir --whole
410 $ cat foo.changed
410 $ cat foo.changed
411 ZZ
411 ZZ
412 A
412 A
413 C
413 C
414 DD
414 DD
415 EE
415 EE
416 FF
416 FF
417 F
417 F
418 GG
418 GG
419
419
420 $ cd ..
420 $ cd ..
421
421
422 We should do nothing with symlinks, and their targets should be unaffected. Any
422 We should do nothing with symlinks, and their targets should be unaffected. Any
423 other behavior would be more complicated to implement and harder to document.
423 other behavior would be more complicated to implement and harder to document.
424
424
425 #if symlink
425 #if symlink
426 $ hg init dontmesswithsymlinks
426 $ hg init dontmesswithsymlinks
427 $ cd dontmesswithsymlinks
427 $ cd dontmesswithsymlinks
428
428
429 $ printf "hello\n" > hello.whole
429 $ printf "hello\n" > hello.whole
430 $ ln -s hello.whole hellolink
430 $ ln -s hello.whole hellolink
431 $ hg add
431 $ hg add
432 adding hello.whole
432 adding hello.whole
433 adding hellolink
433 adding hellolink
434 $ hg fix --working-dir hellolink
434 $ hg fix --working-dir hellolink
435 $ hg status
435 $ hg status
436 A hello.whole
436 A hello.whole
437 A hellolink
437 A hellolink
438
438
439 $ cd ..
439 $ cd ..
440 #endif
440 #endif
441
441
442 We should allow fixers to run on binary files, even though this doesn't sound
442 We should allow fixers to run on binary files, even though this doesn't sound
443 like a common use case. There's not much benefit to disallowing it, and users
443 like a common use case. There's not much benefit to disallowing it, and users
444 can add "and not binary()" to their filesets if needed. The Mercurial
444 can add "and not binary()" to their filesets if needed. The Mercurial
445 philosophy is generally to not handle binary files specially anyway.
445 philosophy is generally to not handle binary files specially anyway.
446
446
447 $ hg init cantouchbinaryfiles
447 $ hg init cantouchbinaryfiles
448 $ cd cantouchbinaryfiles
448 $ cd cantouchbinaryfiles
449
449
450 $ printf "hello\0\n" > hello.whole
450 $ printf "hello\0\n" > hello.whole
451 $ hg add
451 $ hg add
452 adding hello.whole
452 adding hello.whole
453 $ hg fix --working-dir 'set:binary()'
453 $ hg fix --working-dir 'set:binary()'
454 $ cat hello.whole
454 $ cat hello.whole
455 HELLO\x00 (esc)
455 HELLO\x00 (esc)
456
456
457 $ cd ..
457 $ cd ..
458
458
459 We have a config for the maximum size of file we will attempt to fix. This can
459 We have a config for the maximum size of file we will attempt to fix. This can
460 be helpful to avoid running unsuspecting fixer tools on huge inputs, which
460 be helpful to avoid running unsuspecting fixer tools on huge inputs, which
461 could happen by accident without a well considered configuration. A more
461 could happen by accident without a well considered configuration. A more
462 precise configuration could use the size() fileset function if one global limit
462 precise configuration could use the size() fileset function if one global limit
463 is undesired.
463 is undesired.
464
464
465 $ hg init maxfilesize
465 $ hg init maxfilesize
466 $ cd maxfilesize
466 $ cd maxfilesize
467
467
468 $ printf "this file is huge\n" > hello.whole
468 $ printf "this file is huge\n" > hello.whole
469 $ hg add
469 $ hg add
470 adding hello.whole
470 adding hello.whole
471 $ hg --config fix.maxfilesize=10 fix --working-dir
471 $ hg --config fix.maxfilesize=10 fix --working-dir
472 ignoring file larger than 10 bytes: hello.whole
472 ignoring file larger than 10 bytes: hello.whole
473 $ cat hello.whole
473 $ cat hello.whole
474 this file is huge
474 this file is huge
475
475
476 $ cd ..
476 $ cd ..
477
477
478 If we specify a file to fix, other files should be left alone, even if they
478 If we specify a file to fix, other files should be left alone, even if they
479 have changes.
479 have changes.
480
480
481 $ hg init fixonlywhatitellyouto
481 $ hg init fixonlywhatitellyouto
482 $ cd fixonlywhatitellyouto
482 $ cd fixonlywhatitellyouto
483
483
484 $ printf "fix me!\n" > fixme.whole
484 $ printf "fix me!\n" > fixme.whole
485 $ printf "not me.\n" > notme.whole
485 $ printf "not me.\n" > notme.whole
486 $ hg add
486 $ hg add
487 adding fixme.whole
487 adding fixme.whole
488 adding notme.whole
488 adding notme.whole
489 $ hg fix --working-dir fixme.whole
489 $ hg fix --working-dir fixme.whole
490 $ cat *.whole
490 $ cat *.whole
491 FIX ME!
491 FIX ME!
492 not me.
492 not me.
493
493
494 $ cd ..
494 $ cd ..
495
495
496 Specifying a directory name should fix all its files and subdirectories.
496 Specifying a directory name should fix all its files and subdirectories.
497
497
498 $ hg init fixdirectory
498 $ hg init fixdirectory
499 $ cd fixdirectory
499 $ cd fixdirectory
500
500
501 $ mkdir -p dir1/dir2
501 $ mkdir -p dir1/dir2
502 $ printf "foo\n" > foo.whole
502 $ printf "foo\n" > foo.whole
503 $ printf "bar\n" > dir1/bar.whole
503 $ printf "bar\n" > dir1/bar.whole
504 $ printf "baz\n" > dir1/dir2/baz.whole
504 $ printf "baz\n" > dir1/dir2/baz.whole
505 $ hg add
505 $ hg add
506 adding dir1/bar.whole
506 adding dir1/bar.whole
507 adding dir1/dir2/baz.whole
507 adding dir1/dir2/baz.whole
508 adding foo.whole
508 adding foo.whole
509 $ hg fix --working-dir dir1
509 $ hg fix --working-dir dir1
510 $ cat foo.whole dir1/bar.whole dir1/dir2/baz.whole
510 $ cat foo.whole dir1/bar.whole dir1/dir2/baz.whole
511 foo
511 foo
512 BAR
512 BAR
513 BAZ
513 BAZ
514
514
515 $ cd ..
515 $ cd ..
516
516
517 Fixing a file in the working directory that needs no fixes should not actually
517 Fixing a file in the working directory that needs no fixes should not actually
518 write back to the file, so for example the mtime shouldn't change.
518 write back to the file, so for example the mtime shouldn't change.
519
519
520 $ hg init donttouchunfixedfiles
520 $ hg init donttouchunfixedfiles
521 $ cd donttouchunfixedfiles
521 $ cd donttouchunfixedfiles
522
522
523 $ printf "NO FIX NEEDED\n" > foo.whole
523 $ printf "NO FIX NEEDED\n" > foo.whole
524 $ hg add
524 $ hg add
525 adding foo.whole
525 adding foo.whole
526 $ cp -p foo.whole foo.whole.orig
526 $ cp -p foo.whole foo.whole.orig
527 $ cp -p foo.whole.orig foo.whole
527 $ cp -p foo.whole.orig foo.whole
528 $ sleep 2 # mtime has a resolution of one or two seconds.
528 $ sleep 2 # mtime has a resolution of one or two seconds.
529 $ hg fix --working-dir
529 $ hg fix --working-dir
530 $ f foo.whole.orig --newer foo.whole
530 $ f foo.whole.orig --newer foo.whole
531 foo.whole.orig: newer than foo.whole
531 foo.whole.orig: newer than foo.whole
532
532
533 $ cd ..
533 $ cd ..
534
534
535 When a fixer prints to stderr, we don't assume that it has failed. We show the
535 When a fixer prints to stderr, we don't assume that it has failed. We show the
536 error messages to the user, and we still let the fixer affect the file it was
536 error messages to the user, and we still let the fixer affect the file it was
537 fixing if its exit code is zero. Some code formatters might emit error messages
537 fixing if its exit code is zero. Some code formatters might emit error messages
538 on stderr and nothing on stdout, which would cause us the clear the file,
538 on stderr and nothing on stdout, which would cause us the clear the file,
539 except that they also exit with a non-zero code. We show the user which fixer
539 except that they also exit with a non-zero code. We show the user which fixer
540 emitted the stderr, and which revision, but we assume that the fixer will print
540 emitted the stderr, and which revision, but we assume that the fixer will print
541 the filename if it is relevant (since the issue may be non-specific). There is
541 the filename if it is relevant (since the issue may be non-specific). There is
542 also a config to abort (without affecting any files whatsoever) if we see any
542 also a config to abort (without affecting any files whatsoever) if we see any
543 tool with a non-zero exit status.
543 tool with a non-zero exit status.
544
544
545 $ hg init showstderr
545 $ hg init showstderr
546 $ cd showstderr
546 $ cd showstderr
547
547
548 $ printf "hello\n" > hello.txt
548 $ printf "hello\n" > hello.txt
549 $ hg add
549 $ hg add
550 adding hello.txt
550 adding hello.txt
551 $ cat > $TESTTMP/work.sh <<'EOF'
551 $ cat > $TESTTMP/work.sh <<'EOF'
552 > printf 'HELLO\n'
552 > printf 'HELLO\n'
553 > printf "$@: some\nerror that didn't stop the tool" >&2
553 > printf "$@: some\nerror that didn't stop the tool" >&2
554 > exit 0 # success despite the stderr output
554 > exit 0 # success despite the stderr output
555 > EOF
555 > EOF
556 $ hg --config "fix.work:command=sh $TESTTMP/work.sh {rootpath}" \
556 $ hg --config "fix.work:command=sh $TESTTMP/work.sh {rootpath}" \
557 > --config "fix.work:pattern=hello.txt" \
557 > --config "fix.work:pattern=hello.txt" \
558 > fix --working-dir
558 > fix --working-dir
559 [wdir] work: hello.txt: some
559 [wdir] work: hello.txt: some
560 [wdir] work: error that didn't stop the tool
560 [wdir] work: error that didn't stop the tool
561 $ cat hello.txt
561 $ cat hello.txt
562 HELLO
562 HELLO
563
563
564 $ printf "goodbye\n" > hello.txt
564 $ printf "goodbye\n" > hello.txt
565 $ printf "foo\n" > foo.whole
565 $ printf "foo\n" > foo.whole
566 $ hg add
566 $ hg add
567 adding foo.whole
567 adding foo.whole
568 $ cat > $TESTTMP/fail.sh <<'EOF'
568 $ cat > $TESTTMP/fail.sh <<'EOF'
569 > printf 'GOODBYE\n'
569 > printf 'GOODBYE\n'
570 > printf "$@: some\nerror that did stop the tool\n" >&2
570 > printf "$@: some\nerror that did stop the tool\n" >&2
571 > exit 42 # success despite the stdout output
571 > exit 42 # success despite the stdout output
572 > EOF
572 > EOF
573 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
573 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
574 > --config "fix.fail:pattern=hello.txt" \
574 > --config "fix.fail:pattern=hello.txt" \
575 > --config "fix.failure=abort" \
575 > --config "fix.failure=abort" \
576 > fix --working-dir
576 > fix --working-dir
577 [wdir] fail: hello.txt: some
577 [wdir] fail: hello.txt: some
578 [wdir] fail: error that did stop the tool
578 [wdir] fail: error that did stop the tool
579 abort: no fixes will be applied
579 abort: no fixes will be applied
580 (use --config fix.failure=continue to apply any successful fixes anyway)
580 (use --config fix.failure=continue to apply any successful fixes anyway)
581 [255]
581 [255]
582 $ cat hello.txt
582 $ cat hello.txt
583 goodbye
583 goodbye
584 $ cat foo.whole
584 $ cat foo.whole
585 foo
585 foo
586
586
587 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
587 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
588 > --config "fix.fail:pattern=hello.txt" \
588 > --config "fix.fail:pattern=hello.txt" \
589 > fix --working-dir
589 > fix --working-dir
590 [wdir] fail: hello.txt: some
590 [wdir] fail: hello.txt: some
591 [wdir] fail: error that did stop the tool
591 [wdir] fail: error that did stop the tool
592 $ cat hello.txt
592 $ cat hello.txt
593 goodbye
593 goodbye
594 $ cat foo.whole
594 $ cat foo.whole
595 FOO
595 FOO
596
596
597 $ hg --config "fix.fail:command=exit 42" \
597 $ hg --config "fix.fail:command=exit 42" \
598 > --config "fix.fail:pattern=hello.txt" \
598 > --config "fix.fail:pattern=hello.txt" \
599 > fix --working-dir
599 > fix --working-dir
600 [wdir] fail: exited with status 42
600 [wdir] fail: exited with status 42
601
601
602 $ cd ..
602 $ cd ..
603
603
604 Fixing the working directory and its parent revision at the same time should
604 Fixing the working directory and its parent revision at the same time should
605 check out the replacement revision for the parent. This prevents any new
605 check out the replacement revision for the parent. This prevents any new
606 uncommitted changes from appearing. We test this for a clean working directory
606 uncommitted changes from appearing. We test this for a clean working directory
607 and a dirty one. In both cases, all lines/files changed since the grandparent
607 and a dirty one. In both cases, all lines/files changed since the grandparent
608 will be fixed. The grandparent is the "baserev" for both the parent and the
608 will be fixed. The grandparent is the "baserev" for both the parent and the
609 working copy.
609 working copy.
610
610
611 $ hg init fixdotandcleanwdir
611 $ hg init fixdotandcleanwdir
612 $ cd fixdotandcleanwdir
612 $ cd fixdotandcleanwdir
613
613
614 $ printf "hello\n" > hello.whole
614 $ printf "hello\n" > hello.whole
615 $ printf "world\n" > world.whole
615 $ printf "world\n" > world.whole
616 $ hg commit -Aqm "the parent commit"
616 $ hg commit -Aqm "the parent commit"
617
617
618 $ hg parents --template '{rev} {desc}\n'
618 $ hg parents --template '{rev} {desc}\n'
619 0 the parent commit
619 0 the parent commit
620 $ hg fix --working-dir -r .
620 $ hg fix --working-dir -r .
621 $ hg parents --template '{rev} {desc}\n'
621 $ hg parents --template '{rev} {desc}\n'
622 1 the parent commit
622 1 the parent commit
623 $ hg cat -r . *.whole
623 $ hg cat -r . *.whole
624 HELLO
624 HELLO
625 WORLD
625 WORLD
626 $ cat *.whole
626 $ cat *.whole
627 HELLO
627 HELLO
628 WORLD
628 WORLD
629 $ hg status
629 $ hg status
630
630
631 $ cd ..
631 $ cd ..
632
632
633 Same test with a dirty working copy.
633 Same test with a dirty working copy.
634
634
635 $ hg init fixdotanddirtywdir
635 $ hg init fixdotanddirtywdir
636 $ cd fixdotanddirtywdir
636 $ cd fixdotanddirtywdir
637
637
638 $ printf "hello\n" > hello.whole
638 $ printf "hello\n" > hello.whole
639 $ printf "world\n" > world.whole
639 $ printf "world\n" > world.whole
640 $ hg commit -Aqm "the parent commit"
640 $ hg commit -Aqm "the parent commit"
641
641
642 $ printf "hello,\n" > hello.whole
642 $ printf "hello,\n" > hello.whole
643 $ printf "world!\n" > world.whole
643 $ printf "world!\n" > world.whole
644
644
645 $ hg parents --template '{rev} {desc}\n'
645 $ hg parents --template '{rev} {desc}\n'
646 0 the parent commit
646 0 the parent commit
647 $ hg fix --working-dir -r .
647 $ hg fix --working-dir -r .
648 $ hg parents --template '{rev} {desc}\n'
648 $ hg parents --template '{rev} {desc}\n'
649 1 the parent commit
649 1 the parent commit
650 $ hg cat -r . *.whole
650 $ hg cat -r . *.whole
651 HELLO
651 HELLO
652 WORLD
652 WORLD
653 $ cat *.whole
653 $ cat *.whole
654 HELLO,
654 HELLO,
655 WORLD!
655 WORLD!
656 $ hg status
656 $ hg status
657 M hello.whole
657 M hello.whole
658 M world.whole
658 M world.whole
659
659
660 $ cd ..
660 $ cd ..
661
661
662 When we have a chain of commits that change mutually exclusive lines of code,
662 When we have a chain of commits that change mutually exclusive lines of code,
663 we should be able to do incremental fixing that causes each commit in the chain
663 we should be able to do incremental fixing that causes each commit in the chain
664 to include fixes made to the previous commits. This prevents children from
664 to include fixes made to the previous commits. This prevents children from
665 backing out the fixes made in their parents. A dirty working directory is
665 backing out the fixes made in their parents. A dirty working directory is
666 conceptually similar to another commit in the chain.
666 conceptually similar to another commit in the chain.
667
667
668 $ hg init incrementallyfixchain
668 $ hg init incrementallyfixchain
669 $ cd incrementallyfixchain
669 $ cd incrementallyfixchain
670
670
671 $ cat > file.changed <<EOF
671 $ cat > file.changed <<EOF
672 > first
672 > first
673 > second
673 > second
674 > third
674 > third
675 > fourth
675 > fourth
676 > fifth
676 > fifth
677 > EOF
677 > EOF
678 $ hg commit -Aqm "the common ancestor (the baserev)"
678 $ hg commit -Aqm "the common ancestor (the baserev)"
679 $ cat > file.changed <<EOF
679 $ cat > file.changed <<EOF
680 > first (changed)
680 > first (changed)
681 > second
681 > second
682 > third
682 > third
683 > fourth
683 > fourth
684 > fifth
684 > fifth
685 > EOF
685 > EOF
686 $ hg commit -Aqm "the first commit to fix"
686 $ hg commit -Aqm "the first commit to fix"
687 $ cat > file.changed <<EOF
687 $ cat > file.changed <<EOF
688 > first (changed)
688 > first (changed)
689 > second
689 > second
690 > third (changed)
690 > third (changed)
691 > fourth
691 > fourth
692 > fifth
692 > fifth
693 > EOF
693 > EOF
694 $ hg commit -Aqm "the second commit to fix"
694 $ hg commit -Aqm "the second commit to fix"
695 $ cat > file.changed <<EOF
695 $ cat > file.changed <<EOF
696 > first (changed)
696 > first (changed)
697 > second
697 > second
698 > third (changed)
698 > third (changed)
699 > fourth
699 > fourth
700 > fifth (changed)
700 > fifth (changed)
701 > EOF
701 > EOF
702
702
703 $ hg fix -r . -r '.^' --working-dir
703 $ hg fix -r . -r '.^' --working-dir
704
704
705 $ hg parents --template '{rev}\n'
705 $ hg parents --template '{rev}\n'
706 4
706 4
707 $ hg cat -r '.^^' file.changed
707 $ hg cat -r '.^^' file.changed
708 first
708 first
709 second
709 second
710 third
710 third
711 fourth
711 fourth
712 fifth
712 fifth
713 $ hg cat -r '.^' file.changed
713 $ hg cat -r '.^' file.changed
714 FIRST (CHANGED)
714 FIRST (CHANGED)
715 second
715 second
716 third
716 third
717 fourth
717 fourth
718 fifth
718 fifth
719 $ hg cat -r . file.changed
719 $ hg cat -r . file.changed
720 FIRST (CHANGED)
720 FIRST (CHANGED)
721 second
721 second
722 THIRD (CHANGED)
722 THIRD (CHANGED)
723 fourth
723 fourth
724 fifth
724 fifth
725 $ cat file.changed
725 $ cat file.changed
726 FIRST (CHANGED)
726 FIRST (CHANGED)
727 second
727 second
728 THIRD (CHANGED)
728 THIRD (CHANGED)
729 fourth
729 fourth
730 FIFTH (CHANGED)
730 FIFTH (CHANGED)
731
731
732 $ cd ..
732 $ cd ..
733
733
734 If we incrementally fix a merge commit, we should fix any lines that changed
734 If we incrementally fix a merge commit, we should fix any lines that changed
735 versus either parent. You could imagine only fixing the intersection or some
735 versus either parent. You could imagine only fixing the intersection or some
736 other subset, but this is necessary if either parent is being fixed. It
736 other subset, but this is necessary if either parent is being fixed. It
737 prevents us from forgetting fixes made in either parent.
737 prevents us from forgetting fixes made in either parent.
738
738
739 $ hg init incrementallyfixmergecommit
739 $ hg init incrementallyfixmergecommit
740 $ cd incrementallyfixmergecommit
740 $ cd incrementallyfixmergecommit
741
741
742 $ printf "a\nb\nc\n" > file.changed
742 $ printf "a\nb\nc\n" > file.changed
743 $ hg commit -Aqm "ancestor"
743 $ hg commit -Aqm "ancestor"
744
744
745 $ printf "aa\nb\nc\n" > file.changed
745 $ printf "aa\nb\nc\n" > file.changed
746 $ hg commit -m "change a"
746 $ hg commit -m "change a"
747
747
748 $ hg checkout '.^'
748 $ hg checkout '.^'
749 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
749 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
750 $ printf "a\nb\ncc\n" > file.changed
750 $ printf "a\nb\ncc\n" > file.changed
751 $ hg commit -m "change c"
751 $ hg commit -m "change c"
752 created new head
752 created new head
753
753
754 $ hg merge
754 $ hg merge
755 merging file.changed
755 merging file.changed
756 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
756 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
757 (branch merge, don't forget to commit)
757 (branch merge, don't forget to commit)
758 $ hg commit -m "merge"
758 $ hg commit -m "merge"
759 $ hg cat -r . file.changed
759 $ hg cat -r . file.changed
760 aa
760 aa
761 b
761 b
762 cc
762 cc
763
763
764 $ hg fix -r . --working-dir
764 $ hg fix -r . --working-dir
765 $ hg cat -r . file.changed
765 $ hg cat -r . file.changed
766 AA
766 AA
767 b
767 b
768 CC
768 CC
769
769
770 $ cd ..
770 $ cd ..
771
771
772 Abort fixing revisions if there is an unfinished operation. We don't want to
772 Abort fixing revisions if there is an unfinished operation. We don't want to
773 make things worse by editing files or stripping/obsoleting things. Also abort
773 make things worse by editing files or stripping/obsoleting things. Also abort
774 fixing the working directory if there are unresolved merge conflicts.
774 fixing the working directory if there are unresolved merge conflicts.
775
775
776 $ hg init abortunresolved
776 $ hg init abortunresolved
777 $ cd abortunresolved
777 $ cd abortunresolved
778
778
779 $ echo "foo1" > foo.whole
779 $ echo "foo1" > foo.whole
780 $ hg commit -Aqm "foo 1"
780 $ hg commit -Aqm "foo 1"
781
781
782 $ hg update null
782 $ hg update null
783 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
783 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
784 $ echo "foo2" > foo.whole
784 $ echo "foo2" > foo.whole
785 $ hg commit -Aqm "foo 2"
785 $ hg commit -Aqm "foo 2"
786
786
787 $ hg --config extensions.rebase= rebase -r 1 -d 0
787 $ hg --config extensions.rebase= rebase -r 1 -d 0
788 rebasing 1:c3b6dc0e177a "foo 2" (tip)
788 rebasing 1:c3b6dc0e177a "foo 2" (tip)
789 merging foo.whole
789 merging foo.whole
790 warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
790 warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
791 unresolved conflicts (see hg resolve, then hg rebase --continue)
791 unresolved conflicts (see hg resolve, then hg rebase --continue)
792 [1]
792 [1]
793
793
794 $ hg --config extensions.rebase= fix --working-dir
794 $ hg --config extensions.rebase= fix --working-dir
795 abort: unresolved conflicts
795 abort: unresolved conflicts
796 (use 'hg resolve')
796 (use 'hg resolve')
797 [255]
797 [255]
798
798
799 $ hg --config extensions.rebase= fix -r .
799 $ hg --config extensions.rebase= fix -r .
800 abort: rebase in progress
800 abort: rebase in progress
801 (use 'hg rebase --continue' or 'hg rebase --abort')
801 (use 'hg rebase --continue' or 'hg rebase --abort')
802 [255]
802 [255]
803
803
804 When fixing a file that was renamed, we should diff against the source of the
804 When fixing a file that was renamed, we should diff against the source of the
805 rename for incremental fixing and we should correctly reproduce the rename in
805 rename for incremental fixing and we should correctly reproduce the rename in
806 the replacement revision.
806 the replacement revision.
807
807
808 $ hg init fixrenamecommit
808 $ hg init fixrenamecommit
809 $ cd fixrenamecommit
809 $ cd fixrenamecommit
810
810
811 $ printf "a\nb\nc\n" > source.changed
811 $ printf "a\nb\nc\n" > source.changed
812 $ hg commit -Aqm "source revision"
812 $ hg commit -Aqm "source revision"
813 $ hg move source.changed dest.changed
813 $ hg move source.changed dest.changed
814 $ printf "a\nb\ncc\n" > dest.changed
814 $ printf "a\nb\ncc\n" > dest.changed
815 $ hg commit -m "dest revision"
815 $ hg commit -m "dest revision"
816
816
817 $ hg fix -r .
817 $ hg fix -r .
818 $ hg log -r tip --copies --template "{file_copies}\n"
818 $ hg log -r tip --copies --template "{file_copies}\n"
819 dest.changed (source.changed)
819 dest.changed (source.changed)
820 $ hg cat -r tip dest.changed
820 $ hg cat -r tip dest.changed
821 a
821 a
822 b
822 b
823 CC
823 CC
824
824
825 $ cd ..
825 $ cd ..
826
826
827 When fixing revisions that remove files we must ensure that the replacement
827 When fixing revisions that remove files we must ensure that the replacement
828 actually removes the file, whereas it could accidentally leave it unchanged or
828 actually removes the file, whereas it could accidentally leave it unchanged or
829 write an empty string to it.
829 write an empty string to it.
830
830
831 $ hg init fixremovedfile
831 $ hg init fixremovedfile
832 $ cd fixremovedfile
832 $ cd fixremovedfile
833
833
834 $ printf "foo\n" > foo.whole
834 $ printf "foo\n" > foo.whole
835 $ printf "bar\n" > bar.whole
835 $ printf "bar\n" > bar.whole
836 $ hg commit -Aqm "add files"
836 $ hg commit -Aqm "add files"
837 $ hg remove bar.whole
837 $ hg remove bar.whole
838 $ hg commit -m "remove file"
838 $ hg commit -m "remove file"
839 $ hg status --change .
839 $ hg status --change .
840 R bar.whole
840 R bar.whole
841 $ hg fix -r . foo.whole
841 $ hg fix -r . foo.whole
842 $ hg status --change tip
842 $ hg status --change tip
843 M foo.whole
843 M foo.whole
844 R bar.whole
844 R bar.whole
845
845
846 $ cd ..
846 $ cd ..
847
847
848 If fixing a revision finds no fixes to make, no replacement revision should be
848 If fixing a revision finds no fixes to make, no replacement revision should be
849 created.
849 created.
850
850
851 $ hg init nofixesneeded
851 $ hg init nofixesneeded
852 $ cd nofixesneeded
852 $ cd nofixesneeded
853
853
854 $ printf "FOO\n" > foo.whole
854 $ printf "FOO\n" > foo.whole
855 $ hg commit -Aqm "add file"
855 $ hg commit -Aqm "add file"
856 $ hg log --template '{rev}\n'
856 $ hg log --template '{rev}\n'
857 0
857 0
858 $ hg fix -r .
858 $ hg fix -r .
859 $ hg log --template '{rev}\n'
859 $ hg log --template '{rev}\n'
860 0
860 0
861
861
862 $ cd ..
862 $ cd ..
863
863
864 If fixing a commit reverts all the changes in the commit, we replace it with a
864 If fixing a commit reverts all the changes in the commit, we replace it with a
865 commit that changes no files.
865 commit that changes no files.
866
866
867 $ hg init nochangesleft
867 $ hg init nochangesleft
868 $ cd nochangesleft
868 $ cd nochangesleft
869
869
870 $ printf "FOO\n" > foo.whole
870 $ printf "FOO\n" > foo.whole
871 $ hg commit -Aqm "add file"
871 $ hg commit -Aqm "add file"
872 $ printf "foo\n" > foo.whole
872 $ printf "foo\n" > foo.whole
873 $ hg commit -m "edit file"
873 $ hg commit -m "edit file"
874 $ hg status --change .
874 $ hg status --change .
875 M foo.whole
875 M foo.whole
876 $ hg fix -r .
876 $ hg fix -r .
877 $ hg status --change tip
877 $ hg status --change tip
878
878
879 $ cd ..
879 $ cd ..
880
880
881 If we fix a parent and child revision together, the child revision must be
881 If we fix a parent and child revision together, the child revision must be
882 replaced if the parent is replaced, even if the diffs of the child needed no
882 replaced if the parent is replaced, even if the diffs of the child needed no
883 fixes. However, we're free to not replace revisions that need no fixes and have
883 fixes. However, we're free to not replace revisions that need no fixes and have
884 no ancestors that are replaced.
884 no ancestors that are replaced.
885
885
886 $ hg init mustreplacechild
886 $ hg init mustreplacechild
887 $ cd mustreplacechild
887 $ cd mustreplacechild
888
888
889 $ printf "FOO\n" > foo.whole
889 $ printf "FOO\n" > foo.whole
890 $ hg commit -Aqm "add foo"
890 $ hg commit -Aqm "add foo"
891 $ printf "foo\n" > foo.whole
891 $ printf "foo\n" > foo.whole
892 $ hg commit -m "edit foo"
892 $ hg commit -m "edit foo"
893 $ printf "BAR\n" > bar.whole
893 $ printf "BAR\n" > bar.whole
894 $ hg commit -Aqm "add bar"
894 $ hg commit -Aqm "add bar"
895
895
896 $ hg log --graph --template '{node|shortest} {files}'
896 $ hg log --graph --template '{rev} {files}'
897 @ bc05 bar.whole
897 @ 2 bar.whole
898 |
898 |
899 o 4fd2 foo.whole
899 o 1 foo.whole
900 |
900 |
901 o f9ac foo.whole
901 o 0 foo.whole
902
902
903 $ hg fix -r 0:2
903 $ hg fix -r 0:2
904 $ hg log --graph --template '{node|shortest} {files}'
904 $ hg log --graph --template '{rev} {files}'
905 o b4e2 bar.whole
905 o 4 bar.whole
906 |
906 |
907 o 59f4
907 o 3
908 |
908 |
909 | @ bc05 bar.whole
909 | @ 2 bar.whole
910 | |
910 | |
911 | x 4fd2 foo.whole
911 | x 1 foo.whole
912 |/
912 |/
913 o f9ac foo.whole
913 o 0 foo.whole
914
914
915
915
916 $ cd ..
916 $ cd ..
917
917
918 It's also possible that the child needs absolutely no changes, but we still
918 It's also possible that the child needs absolutely no changes, but we still
919 need to replace it to update its parent. If we skipped replacing the child
919 need to replace it to update its parent. If we skipped replacing the child
920 because it had no file content changes, it would become an orphan for no good
920 because it had no file content changes, it would become an orphan for no good
921 reason.
921 reason.
922
922
923 $ hg init mustreplacechildevenifnop
923 $ hg init mustreplacechildevenifnop
924 $ cd mustreplacechildevenifnop
924 $ cd mustreplacechildevenifnop
925
925
926 $ printf "Foo\n" > foo.whole
926 $ printf "Foo\n" > foo.whole
927 $ hg commit -Aqm "add a bad foo"
927 $ hg commit -Aqm "add a bad foo"
928 $ printf "FOO\n" > foo.whole
928 $ printf "FOO\n" > foo.whole
929 $ hg commit -m "add a good foo"
929 $ hg commit -m "add a good foo"
930 $ hg fix -r . -r '.^'
930 $ hg fix -r . -r '.^'
931 $ hg log --graph --template '{rev} {desc}'
931 $ hg log --graph --template '{rev} {desc}'
932 o 3 add a good foo
932 o 3 add a good foo
933 |
933 |
934 o 2 add a bad foo
934 o 2 add a bad foo
935
935
936 @ 1 add a good foo
936 @ 1 add a good foo
937 |
937 |
938 x 0 add a bad foo
938 x 0 add a bad foo
939
939
940
940
941 $ cd ..
941 $ cd ..
942
942
943 Similar to the case above, the child revision may become empty as a result of
943 Similar to the case above, the child revision may become empty as a result of
944 fixing its parent. We should still create an empty replacement child.
944 fixing its parent. We should still create an empty replacement child.
945 TODO: determine how this should interact with ui.allowemptycommit given that
945 TODO: determine how this should interact with ui.allowemptycommit given that
946 the empty replacement could have children.
946 the empty replacement could have children.
947
947
948 $ hg init mustreplacechildevenifempty
948 $ hg init mustreplacechildevenifempty
949 $ cd mustreplacechildevenifempty
949 $ cd mustreplacechildevenifempty
950
950
951 $ printf "foo\n" > foo.whole
951 $ printf "foo\n" > foo.whole
952 $ hg commit -Aqm "add foo"
952 $ hg commit -Aqm "add foo"
953 $ printf "Foo\n" > foo.whole
953 $ printf "Foo\n" > foo.whole
954 $ hg commit -m "edit foo"
954 $ hg commit -m "edit foo"
955 $ hg fix -r . -r '.^'
955 $ hg fix -r . -r '.^'
956 $ hg log --graph --template '{rev} {desc}\n' --stat
956 $ hg log --graph --template '{rev} {desc}\n' --stat
957 o 3 edit foo
957 o 3 edit foo
958 |
958 |
959 o 2 add foo
959 o 2 add foo
960 foo.whole | 1 +
960 foo.whole | 1 +
961 1 files changed, 1 insertions(+), 0 deletions(-)
961 1 files changed, 1 insertions(+), 0 deletions(-)
962
962
963 @ 1 edit foo
963 @ 1 edit foo
964 | foo.whole | 2 +-
964 | foo.whole | 2 +-
965 | 1 files changed, 1 insertions(+), 1 deletions(-)
965 | 1 files changed, 1 insertions(+), 1 deletions(-)
966 |
966 |
967 x 0 add foo
967 x 0 add foo
968 foo.whole | 1 +
968 foo.whole | 1 +
969 1 files changed, 1 insertions(+), 0 deletions(-)
969 1 files changed, 1 insertions(+), 0 deletions(-)
970
970
971
971
972 $ cd ..
972 $ cd ..
973
973
974 Fixing a secret commit should replace it with another secret commit.
974 Fixing a secret commit should replace it with another secret commit.
975
975
976 $ hg init fixsecretcommit
976 $ hg init fixsecretcommit
977 $ cd fixsecretcommit
977 $ cd fixsecretcommit
978
978
979 $ printf "foo\n" > foo.whole
979 $ printf "foo\n" > foo.whole
980 $ hg commit -Aqm "add foo" --secret
980 $ hg commit -Aqm "add foo" --secret
981 $ hg fix -r .
981 $ hg fix -r .
982 $ hg log --template '{rev} {phase}\n'
982 $ hg log --template '{rev} {phase}\n'
983 1 secret
983 1 secret
984 0 secret
984 0 secret
985
985
986 $ cd ..
986 $ cd ..
987
987
988 We should also preserve phase when fixing a draft commit while the user has
988 We should also preserve phase when fixing a draft commit while the user has
989 their default set to secret.
989 their default set to secret.
990
990
991 $ hg init respectphasesnewcommit
991 $ hg init respectphasesnewcommit
992 $ cd respectphasesnewcommit
992 $ cd respectphasesnewcommit
993
993
994 $ printf "foo\n" > foo.whole
994 $ printf "foo\n" > foo.whole
995 $ hg commit -Aqm "add foo"
995 $ hg commit -Aqm "add foo"
996 $ hg --config phases.newcommit=secret fix -r .
996 $ hg --config phases.newcommit=secret fix -r .
997 $ hg log --template '{rev} {phase}\n'
997 $ hg log --template '{rev} {phase}\n'
998 1 draft
998 1 draft
999 0 draft
999 0 draft
1000
1000
1001 $ cd ..
1001 $ cd ..
1002
1002
1003 Debug output should show what fixer commands are being subprocessed, which is
1003 Debug output should show what fixer commands are being subprocessed, which is
1004 useful for anyone trying to set up a new config.
1004 useful for anyone trying to set up a new config.
1005
1005
1006 $ hg init debugoutput
1006 $ hg init debugoutput
1007 $ cd debugoutput
1007 $ cd debugoutput
1008
1008
1009 $ printf "foo\nbar\nbaz\n" > foo.changed
1009 $ printf "foo\nbar\nbaz\n" > foo.changed
1010 $ hg commit -Aqm "foo"
1010 $ hg commit -Aqm "foo"
1011 $ printf "Foo\nbar\nBaz\n" > foo.changed
1011 $ printf "Foo\nbar\nBaz\n" > foo.changed
1012 $ hg --debug fix --working-dir
1012 $ hg --debug fix --working-dir
1013 subprocess: * $TESTTMP/uppercase.py 1-1 3-3 (glob)
1013 subprocess: * $TESTTMP/uppercase.py 1-1 3-3 (glob)
1014
1014
1015 $ cd ..
1015 $ cd ..
1016
1016
1017 Fixing an obsolete revision can cause divergence, so we abort unless the user
1017 Fixing an obsolete revision can cause divergence, so we abort unless the user
1018 configures to allow it. This is not yet smart enough to know whether there is a
1018 configures to allow it. This is not yet smart enough to know whether there is a
1019 successor, but even then it is not likely intentional or idiomatic to fix an
1019 successor, but even then it is not likely intentional or idiomatic to fix an
1020 obsolete revision.
1020 obsolete revision.
1021
1021
1022 $ hg init abortobsoleterev
1022 $ hg init abortobsoleterev
1023 $ cd abortobsoleterev
1023 $ cd abortobsoleterev
1024
1024
1025 $ printf "foo\n" > foo.changed
1025 $ printf "foo\n" > foo.changed
1026 $ hg commit -Aqm "foo"
1026 $ hg commit -Aqm "foo"
1027 $ hg debugobsolete `hg parents --template '{node}'`
1027 $ hg debugobsolete `hg parents --template '{node}'`
1028 obsoleted 1 changesets
1028 obsoleted 1 changesets
1029 $ hg --hidden fix -r 0
1029 $ hg --hidden fix -r 0
1030 abort: fixing obsolete revision could cause divergence
1030 abort: fixing obsolete revision could cause divergence
1031 [255]
1031 [255]
1032
1032
1033 $ hg --hidden fix -r 0 --config experimental.evolution.allowdivergence=true
1033 $ hg --hidden fix -r 0 --config experimental.evolution.allowdivergence=true
1034 $ hg cat -r tip foo.changed
1034 $ hg cat -r tip foo.changed
1035 FOO
1035 FOO
1036
1036
1037 $ cd ..
1037 $ cd ..
1038
1038
1039 Test all of the available substitution values for fixer commands.
1039 Test all of the available substitution values for fixer commands.
1040
1040
1041 $ hg init substitution
1041 $ hg init substitution
1042 $ cd substitution
1042 $ cd substitution
1043
1043
1044 $ mkdir foo
1044 $ mkdir foo
1045 $ printf "hello\ngoodbye\n" > foo/bar
1045 $ printf "hello\ngoodbye\n" > foo/bar
1046 $ hg add
1046 $ hg add
1047 adding foo/bar
1047 adding foo/bar
1048 $ hg --config "fix.fail:command=printf '%s\n' '{rootpath}' '{basename}'" \
1048 $ hg --config "fix.fail:command=printf '%s\n' '{rootpath}' '{basename}'" \
1049 > --config "fix.fail:linerange='{first}' '{last}'" \
1049 > --config "fix.fail:linerange='{first}' '{last}'" \
1050 > --config "fix.fail:pattern=foo/bar" \
1050 > --config "fix.fail:pattern=foo/bar" \
1051 > fix --working-dir
1051 > fix --working-dir
1052 $ cat foo/bar
1052 $ cat foo/bar
1053 foo/bar
1053 foo/bar
1054 bar
1054 bar
1055 1
1055 1
1056 2
1056 2
1057
1057
1058 $ cd ..
1058 $ cd ..
1059
1059
1060 The --base flag should allow picking the revisions to diff against for changed
1060 The --base flag should allow picking the revisions to diff against for changed
1061 files and incremental line formatting.
1061 files and incremental line formatting.
1062
1062
1063 $ hg init baseflag
1063 $ hg init baseflag
1064 $ cd baseflag
1064 $ cd baseflag
1065
1065
1066 $ printf "one\ntwo\n" > foo.changed
1066 $ printf "one\ntwo\n" > foo.changed
1067 $ printf "bar\n" > bar.changed
1067 $ printf "bar\n" > bar.changed
1068 $ hg commit -Aqm "first"
1068 $ hg commit -Aqm "first"
1069 $ printf "one\nTwo\n" > foo.changed
1069 $ printf "one\nTwo\n" > foo.changed
1070 $ hg commit -m "second"
1070 $ hg commit -m "second"
1071 $ hg fix -w --base .
1071 $ hg fix -w --base .
1072 $ hg status
1072 $ hg status
1073 $ hg fix -w --base null
1073 $ hg fix -w --base null
1074 $ cat foo.changed
1074 $ cat foo.changed
1075 ONE
1075 ONE
1076 TWO
1076 TWO
1077 $ cat bar.changed
1077 $ cat bar.changed
1078 BAR
1078 BAR
1079
1079
1080 $ cd ..
1080 $ cd ..
1081
1081
1082 If the user asks to fix the parent of another commit, they are asking to create
1082 If the user asks to fix the parent of another commit, they are asking to create
1083 an orphan. We must respect experimental.evolution.allowunstable.
1083 an orphan. We must respect experimental.evolution.allowunstable.
1084
1084
1085 $ hg init allowunstable
1085 $ hg init allowunstable
1086 $ cd allowunstable
1086 $ cd allowunstable
1087
1087
1088 $ printf "one\n" > foo.whole
1088 $ printf "one\n" > foo.whole
1089 $ hg commit -Aqm "first"
1089 $ hg commit -Aqm "first"
1090 $ printf "two\n" > foo.whole
1090 $ printf "two\n" > foo.whole
1091 $ hg commit -m "second"
1091 $ hg commit -m "second"
1092 $ hg --config experimental.evolution.allowunstable=False fix -r '.^'
1092 $ hg --config experimental.evolution.allowunstable=False fix -r '.^'
1093 abort: can only fix a changeset together with all its descendants
1093 abort: can only fix a changeset together with all its descendants
1094 [255]
1094 [255]
1095 $ hg fix -r '.^'
1095 $ hg fix -r '.^'
1096 1 new orphan changesets
1096 1 new orphan changesets
1097 $ hg cat -r 2 foo.whole
1097 $ hg cat -r 2 foo.whole
1098 ONE
1098 ONE
1099
1099
1100 $ cd ..
1100 $ cd ..
1101
1101
1102 The --base flag affects the set of files being fixed. So while the --whole flag
1102 The --base flag affects the set of files being fixed. So while the --whole flag
1103 makes the base irrelevant for changed line ranges, it still changes the
1103 makes the base irrelevant for changed line ranges, it still changes the
1104 meaning and effect of the command. In this example, no files or lines are fixed
1104 meaning and effect of the command. In this example, no files or lines are fixed
1105 until we specify the base, but then we do fix unchanged lines.
1105 until we specify the base, but then we do fix unchanged lines.
1106
1106
1107 $ hg init basewhole
1107 $ hg init basewhole
1108 $ cd basewhole
1108 $ cd basewhole
1109 $ printf "foo1\n" > foo.changed
1109 $ printf "foo1\n" > foo.changed
1110 $ hg commit -Aqm "first"
1110 $ hg commit -Aqm "first"
1111 $ printf "foo2\n" >> foo.changed
1111 $ printf "foo2\n" >> foo.changed
1112 $ printf "bar\n" > bar.changed
1112 $ printf "bar\n" > bar.changed
1113 $ hg commit -Aqm "second"
1113 $ hg commit -Aqm "second"
1114
1114
1115 $ hg fix --working-dir --whole
1115 $ hg fix --working-dir --whole
1116 $ cat *.changed
1116 $ cat *.changed
1117 bar
1117 bar
1118 foo1
1118 foo1
1119 foo2
1119 foo2
1120
1120
1121 $ hg fix --working-dir --base 0 --whole
1121 $ hg fix --working-dir --base 0 --whole
1122 $ cat *.changed
1122 $ cat *.changed
1123 BAR
1123 BAR
1124 FOO1
1124 FOO1
1125 FOO2
1125 FOO2
1126
1126
1127 $ cd ..
1127 $ cd ..
1128
1128
1129 The :fileset subconfig was a misnomer, so we renamed it to :pattern. We will
1129 The :fileset subconfig was a misnomer, so we renamed it to :pattern. We will
1130 still accept :fileset by itself as if it were :pattern, but this will issue a
1130 still accept :fileset by itself as if it were :pattern, but this will issue a
1131 warning.
1131 warning.
1132
1132
1133 $ hg init filesetispattern
1133 $ hg init filesetispattern
1134 $ cd filesetispattern
1134 $ cd filesetispattern
1135
1135
1136 $ printf "foo\n" > foo.whole
1136 $ printf "foo\n" > foo.whole
1137 $ printf "first\nsecond\n" > bar.txt
1137 $ printf "first\nsecond\n" > bar.txt
1138 $ hg add -q
1138 $ hg add -q
1139 $ hg fix -w --config fix.sometool:fileset=bar.txt \
1139 $ hg fix -w --config fix.sometool:fileset=bar.txt \
1140 > --config fix.sometool:command="sort -r"
1140 > --config fix.sometool:command="sort -r"
1141 the fix.tool:fileset config name is deprecated; please rename it to fix.tool:pattern
1141 the fix.tool:fileset config name is deprecated; please rename it to fix.tool:pattern
1142
1142
1143 $ cat foo.whole
1143 $ cat foo.whole
1144 FOO
1144 FOO
1145 $ cat bar.txt
1145 $ cat bar.txt
1146 second
1146 second
1147 first
1147 first
1148
1148
1149 $ cd ..
1149 $ cd ..
1150
1150
1151 The execution order of tools can be controlled. This example doesn't work if
1151 The execution order of tools can be controlled. This example doesn't work if
1152 you sort after truncating, but the config defines the correct order while the
1152 you sort after truncating, but the config defines the correct order while the
1153 definitions are out of order (which might imply the incorrect order given the
1153 definitions are out of order (which might imply the incorrect order given the
1154 implementation of fix). The goal is to use multiple tools to select the lowest
1154 implementation of fix). The goal is to use multiple tools to select the lowest
1155 5 numbers in the file.
1155 5 numbers in the file.
1156
1156
1157 $ hg init priorityexample
1157 $ hg init priorityexample
1158 $ cd priorityexample
1158 $ cd priorityexample
1159
1159
1160 $ cat >> .hg/hgrc <<EOF
1160 $ cat >> .hg/hgrc <<EOF
1161 > [fix]
1161 > [fix]
1162 > head:command = head --lines=5
1162 > head:command = head --lines=5
1163 > head:pattern = numbers.txt
1163 > head:pattern = numbers.txt
1164 > head:priority = 1
1164 > head:priority = 1
1165 > sort:command = sort --numeric-sort
1165 > sort:command = sort --numeric-sort
1166 > sort:pattern = numbers.txt
1166 > sort:pattern = numbers.txt
1167 > sort:priority = 2
1167 > sort:priority = 2
1168 > EOF
1168 > EOF
1169
1169
1170 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1170 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1171 $ hg add -q
1171 $ hg add -q
1172 $ hg fix -w
1172 $ hg fix -w
1173 $ cat numbers.txt
1173 $ cat numbers.txt
1174 0
1174 0
1175 1
1175 1
1176 2
1176 2
1177 3
1177 3
1178 4
1178 4
1179
1179
1180 And of course we should be able to break this by reversing the execution order.
1180 And of course we should be able to break this by reversing the execution order.
1181 Test negative priorities while we're at it.
1181 Test negative priorities while we're at it.
1182
1182
1183 $ cat >> .hg/hgrc <<EOF
1183 $ cat >> .hg/hgrc <<EOF
1184 > [fix]
1184 > [fix]
1185 > head:priority = -1
1185 > head:priority = -1
1186 > sort:priority = -2
1186 > sort:priority = -2
1187 > EOF
1187 > EOF
1188 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1188 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1189 $ hg fix -w
1189 $ hg fix -w
1190 $ cat numbers.txt
1190 $ cat numbers.txt
1191 2
1191 2
1192 3
1192 3
1193 6
1193 6
1194 7
1194 7
1195 8
1195 8
1196
1196
1197 $ cd ..
1197 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now