##// END OF EJS Templates
fix: add a test case around the effect of cwd on pattern matching...
Danny Hooper -
r42881:22c4bd7d default
parent child Browse files
Show More
@@ -1,1244 +1,1269 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 -n
176 sort:command = sort -n
177 head:command = head -n 10
177 head:command = head -n 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 Each fixer tool is allowed to return some metadata in addition to the fixed
188 Each fixer tool is allowed to return some metadata in addition to the fixed
189 file content. The metadata must be placed before the file content on stdout,
189 file content. The metadata must be placed before the file content on stdout,
190 separated from the file content by a zero byte. The metadata is parsed as a
190 separated from the file content by a zero byte. The metadata is parsed as a
191 JSON value (so, it should be UTF-8 encoded and contain no zero bytes). A fixer
191 JSON value (so, it should be UTF-8 encoded and contain no zero bytes). A fixer
192 tool is expected to produce this metadata encoding if and only if the
192 tool is expected to produce this metadata encoding if and only if the
193 :metadata suboption is true:
193 :metadata suboption is true:
194
194
195 [fix]
195 [fix]
196 tool:command = tool --prepend-json-metadata
196 tool:command = tool --prepend-json-metadata
197 tool:metadata = true
197 tool:metadata = true
198
198
199 The metadata values are passed to hooks, which can be used to print summaries
199 The metadata values are passed to hooks, which can be used to print summaries
200 or perform other post-fixing work. The supported hooks are:
200 or perform other post-fixing work. The supported hooks are:
201
201
202 "postfixfile"
202 "postfixfile"
203 Run once for each file in each revision where any fixer tools made changes
203 Run once for each file in each revision where any fixer tools made changes
204 to the file content. Provides "$HG_REV" and "$HG_PATH" to identify the file,
204 to the file content. Provides "$HG_REV" and "$HG_PATH" to identify the file,
205 and "$HG_METADATA" with a map of fixer names to metadata values from fixer
205 and "$HG_METADATA" with a map of fixer names to metadata values from fixer
206 tools that affected the file. Fixer tools that didn't affect the file have a
206 tools that affected the file. Fixer tools that didn't affect the file have a
207 valueof None. Only fixer tools that executed are present in the metadata.
207 valueof None. Only fixer tools that executed are present in the metadata.
208
208
209 "postfix"
209 "postfix"
210 Run once after all files and revisions have been handled. Provides
210 Run once after all files and revisions have been handled. Provides
211 "$HG_REPLACEMENTS" with information about what revisions were created and
211 "$HG_REPLACEMENTS" with information about what revisions were created and
212 made obsolete. Provides a boolean "$HG_WDIRWRITTEN" to indicate whether any
212 made obsolete. Provides a boolean "$HG_WDIRWRITTEN" to indicate whether any
213 files in the working copy were updated. Provides a list "$HG_METADATA"
213 files in the working copy were updated. Provides a list "$HG_METADATA"
214 mapping fixer tool names to lists of metadata values returned from
214 mapping fixer tool names to lists of metadata values returned from
215 executions that modified a file. This aggregates the same metadata
215 executions that modified a file. This aggregates the same metadata
216 previously passed to the "postfixfile" hook.
216 previously passed to the "postfixfile" hook.
217
217
218 list of commands:
218 list of commands:
219
219
220 fix rewrite file content in changesets or working directory
220 fix rewrite file content in changesets or working directory
221
221
222 (use 'hg help -v -e fix' to show built-in aliases and global options)
222 (use 'hg help -v -e fix' to show built-in aliases and global options)
223
223
224 There is no default behavior in the absence of --rev and --working-dir.
224 There is no default behavior in the absence of --rev and --working-dir.
225
225
226 $ hg init badusage
226 $ hg init badusage
227 $ cd badusage
227 $ cd badusage
228
228
229 $ hg fix
229 $ hg fix
230 abort: no changesets specified
230 abort: no changesets specified
231 (use --rev or --working-dir)
231 (use --rev or --working-dir)
232 [255]
232 [255]
233 $ hg fix --whole
233 $ hg fix --whole
234 abort: no changesets specified
234 abort: no changesets specified
235 (use --rev or --working-dir)
235 (use --rev or --working-dir)
236 [255]
236 [255]
237 $ hg fix --base 0
237 $ hg fix --base 0
238 abort: no changesets specified
238 abort: no changesets specified
239 (use --rev or --working-dir)
239 (use --rev or --working-dir)
240 [255]
240 [255]
241
241
242 Fixing a public revision isn't allowed. It should abort early enough that
242 Fixing a public revision isn't allowed. It should abort early enough that
243 nothing happens, even to the working directory.
243 nothing happens, even to the working directory.
244
244
245 $ printf "hello\n" > hello.whole
245 $ printf "hello\n" > hello.whole
246 $ hg commit -Aqm "hello"
246 $ hg commit -Aqm "hello"
247 $ hg phase -r 0 --public
247 $ hg phase -r 0 --public
248 $ hg fix -r 0
248 $ hg fix -r 0
249 abort: can't fix immutable changeset 0:6470986d2e7b
249 abort: can't fix immutable changeset 0:6470986d2e7b
250 [255]
250 [255]
251 $ hg fix -r 0 --working-dir
251 $ hg fix -r 0 --working-dir
252 abort: can't fix immutable changeset 0:6470986d2e7b
252 abort: can't fix immutable changeset 0:6470986d2e7b
253 [255]
253 [255]
254 $ hg cat -r tip hello.whole
254 $ hg cat -r tip hello.whole
255 hello
255 hello
256 $ cat hello.whole
256 $ cat hello.whole
257 hello
257 hello
258
258
259 $ cd ..
259 $ cd ..
260
260
261 Fixing a clean working directory should do nothing. Even the --whole flag
261 Fixing a clean working directory should do nothing. Even the --whole flag
262 shouldn't cause any clean files to be fixed. Specifying a clean file explicitly
262 shouldn't cause any clean files to be fixed. Specifying a clean file explicitly
263 should only fix it if the fixer always fixes the whole file. The combination of
263 should only fix it if the fixer always fixes the whole file. The combination of
264 an explicit filename and --whole should format the entire file regardless.
264 an explicit filename and --whole should format the entire file regardless.
265
265
266 $ hg init fixcleanwdir
266 $ hg init fixcleanwdir
267 $ cd fixcleanwdir
267 $ cd fixcleanwdir
268
268
269 $ printf "hello\n" > hello.changed
269 $ printf "hello\n" > hello.changed
270 $ printf "world\n" > hello.whole
270 $ printf "world\n" > hello.whole
271 $ hg commit -Aqm "foo"
271 $ hg commit -Aqm "foo"
272 $ hg fix --working-dir
272 $ hg fix --working-dir
273 $ hg diff
273 $ hg diff
274 $ hg fix --working-dir --whole
274 $ hg fix --working-dir --whole
275 $ hg diff
275 $ hg diff
276 $ hg fix --working-dir *
276 $ hg fix --working-dir *
277 $ cat *
277 $ cat *
278 hello
278 hello
279 WORLD
279 WORLD
280 $ hg revert --all --no-backup
280 $ hg revert --all --no-backup
281 reverting hello.whole
281 reverting hello.whole
282 $ hg fix --working-dir * --whole
282 $ hg fix --working-dir * --whole
283 $ cat *
283 $ cat *
284 HELLO
284 HELLO
285 WORLD
285 WORLD
286
286
287 The same ideas apply to fixing a revision, so we create a revision that doesn't
287 The same ideas apply to fixing a revision, so we create a revision that doesn't
288 modify either of the files in question and try fixing it. This also tests that
288 modify either of the files in question and try fixing it. This also tests that
289 we ignore a file that doesn't match any configured fixer.
289 we ignore a file that doesn't match any configured fixer.
290
290
291 $ hg revert --all --no-backup
291 $ hg revert --all --no-backup
292 reverting hello.changed
292 reverting hello.changed
293 reverting hello.whole
293 reverting hello.whole
294 $ printf "unimportant\n" > some.file
294 $ printf "unimportant\n" > some.file
295 $ hg commit -Aqm "some other file"
295 $ hg commit -Aqm "some other file"
296
296
297 $ hg fix -r .
297 $ hg fix -r .
298 $ hg cat -r tip *
298 $ hg cat -r tip *
299 hello
299 hello
300 world
300 world
301 unimportant
301 unimportant
302 $ hg fix -r . --whole
302 $ hg fix -r . --whole
303 $ hg cat -r tip *
303 $ hg cat -r tip *
304 hello
304 hello
305 world
305 world
306 unimportant
306 unimportant
307 $ hg fix -r . *
307 $ hg fix -r . *
308 $ hg cat -r tip *
308 $ hg cat -r tip *
309 hello
309 hello
310 WORLD
310 WORLD
311 unimportant
311 unimportant
312 $ hg fix -r . * --whole --config experimental.evolution.allowdivergence=true
312 $ hg fix -r . * --whole --config experimental.evolution.allowdivergence=true
313 2 new content-divergent changesets
313 2 new content-divergent changesets
314 $ hg cat -r tip *
314 $ hg cat -r tip *
315 HELLO
315 HELLO
316 WORLD
316 WORLD
317 unimportant
317 unimportant
318
318
319 $ cd ..
319 $ cd ..
320
320
321 Fixing the working directory should still work if there are no revisions.
321 Fixing the working directory should still work if there are no revisions.
322
322
323 $ hg init norevisions
323 $ hg init norevisions
324 $ cd norevisions
324 $ cd norevisions
325
325
326 $ printf "something\n" > something.whole
326 $ printf "something\n" > something.whole
327 $ hg add
327 $ hg add
328 adding something.whole
328 adding something.whole
329 $ hg fix --working-dir
329 $ hg fix --working-dir
330 $ cat something.whole
330 $ cat something.whole
331 SOMETHING
331 SOMETHING
332
332
333 $ cd ..
333 $ cd ..
334
334
335 Test the effect of fixing the working directory for each possible status, with
335 Test the effect of fixing the working directory for each possible status, with
336 and without providing explicit file arguments.
336 and without providing explicit file arguments.
337
337
338 $ hg init implicitlyfixstatus
338 $ hg init implicitlyfixstatus
339 $ cd implicitlyfixstatus
339 $ cd implicitlyfixstatus
340
340
341 $ printf "modified\n" > modified.whole
341 $ printf "modified\n" > modified.whole
342 $ printf "removed\n" > removed.whole
342 $ printf "removed\n" > removed.whole
343 $ printf "deleted\n" > deleted.whole
343 $ printf "deleted\n" > deleted.whole
344 $ printf "clean\n" > clean.whole
344 $ printf "clean\n" > clean.whole
345 $ printf "ignored.whole" > .hgignore
345 $ printf "ignored.whole" > .hgignore
346 $ hg commit -Aqm "stuff"
346 $ hg commit -Aqm "stuff"
347
347
348 $ printf "modified!!!\n" > modified.whole
348 $ printf "modified!!!\n" > modified.whole
349 $ printf "unknown\n" > unknown.whole
349 $ printf "unknown\n" > unknown.whole
350 $ printf "ignored\n" > ignored.whole
350 $ printf "ignored\n" > ignored.whole
351 $ printf "added\n" > added.whole
351 $ printf "added\n" > added.whole
352 $ hg add added.whole
352 $ hg add added.whole
353 $ hg remove removed.whole
353 $ hg remove removed.whole
354 $ rm deleted.whole
354 $ rm deleted.whole
355
355
356 $ hg status --all
356 $ hg status --all
357 M modified.whole
357 M modified.whole
358 A added.whole
358 A added.whole
359 R removed.whole
359 R removed.whole
360 ! deleted.whole
360 ! deleted.whole
361 ? unknown.whole
361 ? unknown.whole
362 I ignored.whole
362 I ignored.whole
363 C .hgignore
363 C .hgignore
364 C clean.whole
364 C clean.whole
365
365
366 $ hg fix --working-dir
366 $ hg fix --working-dir
367
367
368 $ hg status --all
368 $ hg status --all
369 M modified.whole
369 M modified.whole
370 A added.whole
370 A added.whole
371 R removed.whole
371 R removed.whole
372 ! deleted.whole
372 ! deleted.whole
373 ? unknown.whole
373 ? unknown.whole
374 I ignored.whole
374 I ignored.whole
375 C .hgignore
375 C .hgignore
376 C clean.whole
376 C clean.whole
377
377
378 $ cat *.whole
378 $ cat *.whole
379 ADDED
379 ADDED
380 clean
380 clean
381 ignored
381 ignored
382 MODIFIED!!!
382 MODIFIED!!!
383 unknown
383 unknown
384
384
385 $ printf "modified!!!\n" > modified.whole
385 $ printf "modified!!!\n" > modified.whole
386 $ printf "added\n" > added.whole
386 $ printf "added\n" > added.whole
387
387
388 Listing the files explicitly causes untracked files to also be fixed, but
388 Listing the files explicitly causes untracked files to also be fixed, but
389 ignored files are still unaffected.
389 ignored files are still unaffected.
390
390
391 $ hg fix --working-dir *.whole
391 $ hg fix --working-dir *.whole
392
392
393 $ hg status --all
393 $ hg status --all
394 M clean.whole
394 M clean.whole
395 M modified.whole
395 M modified.whole
396 A added.whole
396 A added.whole
397 R removed.whole
397 R removed.whole
398 ! deleted.whole
398 ! deleted.whole
399 ? unknown.whole
399 ? unknown.whole
400 I ignored.whole
400 I ignored.whole
401 C .hgignore
401 C .hgignore
402
402
403 $ cat *.whole
403 $ cat *.whole
404 ADDED
404 ADDED
405 CLEAN
405 CLEAN
406 ignored
406 ignored
407 MODIFIED!!!
407 MODIFIED!!!
408 UNKNOWN
408 UNKNOWN
409
409
410 $ cd ..
410 $ cd ..
411
411
412 Test that incremental fixing works on files with additions, deletions, and
412 Test that incremental fixing works on files with additions, deletions, and
413 changes in multiple line ranges. Note that deletions do not generally cause
413 changes in multiple line ranges. Note that deletions do not generally cause
414 neighboring lines to be fixed, so we don't return a line range for purely
414 neighboring lines to be fixed, so we don't return a line range for purely
415 deleted sections. In the future we should support a :deletion config that
415 deleted sections. In the future we should support a :deletion config that
416 allows fixers to know where deletions are located.
416 allows fixers to know where deletions are located.
417
417
418 $ hg init incrementalfixedlines
418 $ hg init incrementalfixedlines
419 $ cd incrementalfixedlines
419 $ cd incrementalfixedlines
420
420
421 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.txt
421 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.txt
422 $ hg commit -Aqm "foo"
422 $ hg commit -Aqm "foo"
423 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.txt
423 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.txt
424
424
425 $ hg --config "fix.fail:command=echo" \
425 $ hg --config "fix.fail:command=echo" \
426 > --config "fix.fail:linerange={first}:{last}" \
426 > --config "fix.fail:linerange={first}:{last}" \
427 > --config "fix.fail:pattern=foo.txt" \
427 > --config "fix.fail:pattern=foo.txt" \
428 > fix --working-dir
428 > fix --working-dir
429 $ cat foo.txt
429 $ cat foo.txt
430 1:1 4:6 8:8
430 1:1 4:6 8:8
431
431
432 $ cd ..
432 $ cd ..
433
433
434 Test that --whole fixes all lines regardless of the diffs present.
434 Test that --whole fixes all lines regardless of the diffs present.
435
435
436 $ hg init wholeignoresdiffs
436 $ hg init wholeignoresdiffs
437 $ cd wholeignoresdiffs
437 $ cd wholeignoresdiffs
438
438
439 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.changed
439 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.changed
440 $ hg commit -Aqm "foo"
440 $ hg commit -Aqm "foo"
441 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.changed
441 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.changed
442 $ hg fix --working-dir --whole
442 $ hg fix --working-dir --whole
443 $ cat foo.changed
443 $ cat foo.changed
444 ZZ
444 ZZ
445 A
445 A
446 C
446 C
447 DD
447 DD
448 EE
448 EE
449 FF
449 FF
450 F
450 F
451 GG
451 GG
452
452
453 $ cd ..
453 $ cd ..
454
454
455 We should do nothing with symlinks, and their targets should be unaffected. Any
455 We should do nothing with symlinks, and their targets should be unaffected. Any
456 other behavior would be more complicated to implement and harder to document.
456 other behavior would be more complicated to implement and harder to document.
457
457
458 #if symlink
458 #if symlink
459 $ hg init dontmesswithsymlinks
459 $ hg init dontmesswithsymlinks
460 $ cd dontmesswithsymlinks
460 $ cd dontmesswithsymlinks
461
461
462 $ printf "hello\n" > hello.whole
462 $ printf "hello\n" > hello.whole
463 $ ln -s hello.whole hellolink
463 $ ln -s hello.whole hellolink
464 $ hg add
464 $ hg add
465 adding hello.whole
465 adding hello.whole
466 adding hellolink
466 adding hellolink
467 $ hg fix --working-dir hellolink
467 $ hg fix --working-dir hellolink
468 $ hg status
468 $ hg status
469 A hello.whole
469 A hello.whole
470 A hellolink
470 A hellolink
471
471
472 $ cd ..
472 $ cd ..
473 #endif
473 #endif
474
474
475 We should allow fixers to run on binary files, even though this doesn't sound
475 We should allow fixers to run on binary files, even though this doesn't sound
476 like a common use case. There's not much benefit to disallowing it, and users
476 like a common use case. There's not much benefit to disallowing it, and users
477 can add "and not binary()" to their filesets if needed. The Mercurial
477 can add "and not binary()" to their filesets if needed. The Mercurial
478 philosophy is generally to not handle binary files specially anyway.
478 philosophy is generally to not handle binary files specially anyway.
479
479
480 $ hg init cantouchbinaryfiles
480 $ hg init cantouchbinaryfiles
481 $ cd cantouchbinaryfiles
481 $ cd cantouchbinaryfiles
482
482
483 $ printf "hello\0\n" > hello.whole
483 $ printf "hello\0\n" > hello.whole
484 $ hg add
484 $ hg add
485 adding hello.whole
485 adding hello.whole
486 $ hg fix --working-dir 'set:binary()'
486 $ hg fix --working-dir 'set:binary()'
487 $ cat hello.whole
487 $ cat hello.whole
488 HELLO\x00 (esc)
488 HELLO\x00 (esc)
489
489
490 $ cd ..
490 $ cd ..
491
491
492 We have a config for the maximum size of file we will attempt to fix. This can
492 We have a config for the maximum size of file we will attempt to fix. This can
493 be helpful to avoid running unsuspecting fixer tools on huge inputs, which
493 be helpful to avoid running unsuspecting fixer tools on huge inputs, which
494 could happen by accident without a well considered configuration. A more
494 could happen by accident without a well considered configuration. A more
495 precise configuration could use the size() fileset function if one global limit
495 precise configuration could use the size() fileset function if one global limit
496 is undesired.
496 is undesired.
497
497
498 $ hg init maxfilesize
498 $ hg init maxfilesize
499 $ cd maxfilesize
499 $ cd maxfilesize
500
500
501 $ printf "this file is huge\n" > hello.whole
501 $ printf "this file is huge\n" > hello.whole
502 $ hg add
502 $ hg add
503 adding hello.whole
503 adding hello.whole
504 $ hg --config fix.maxfilesize=10 fix --working-dir
504 $ hg --config fix.maxfilesize=10 fix --working-dir
505 ignoring file larger than 10 bytes: hello.whole
505 ignoring file larger than 10 bytes: hello.whole
506 $ cat hello.whole
506 $ cat hello.whole
507 this file is huge
507 this file is huge
508
508
509 $ cd ..
509 $ cd ..
510
510
511 If we specify a file to fix, other files should be left alone, even if they
511 If we specify a file to fix, other files should be left alone, even if they
512 have changes.
512 have changes.
513
513
514 $ hg init fixonlywhatitellyouto
514 $ hg init fixonlywhatitellyouto
515 $ cd fixonlywhatitellyouto
515 $ cd fixonlywhatitellyouto
516
516
517 $ printf "fix me!\n" > fixme.whole
517 $ printf "fix me!\n" > fixme.whole
518 $ printf "not me.\n" > notme.whole
518 $ printf "not me.\n" > notme.whole
519 $ hg add
519 $ hg add
520 adding fixme.whole
520 adding fixme.whole
521 adding notme.whole
521 adding notme.whole
522 $ hg fix --working-dir fixme.whole
522 $ hg fix --working-dir fixme.whole
523 $ cat *.whole
523 $ cat *.whole
524 FIX ME!
524 FIX ME!
525 not me.
525 not me.
526
526
527 $ cd ..
527 $ cd ..
528
528
529 Specifying a directory name should fix all its files and subdirectories.
529 Specifying a directory name should fix all its files and subdirectories.
530
530
531 $ hg init fixdirectory
531 $ hg init fixdirectory
532 $ cd fixdirectory
532 $ cd fixdirectory
533
533
534 $ mkdir -p dir1/dir2
534 $ mkdir -p dir1/dir2
535 $ printf "foo\n" > foo.whole
535 $ printf "foo\n" > foo.whole
536 $ printf "bar\n" > dir1/bar.whole
536 $ printf "bar\n" > dir1/bar.whole
537 $ printf "baz\n" > dir1/dir2/baz.whole
537 $ printf "baz\n" > dir1/dir2/baz.whole
538 $ hg add
538 $ hg add
539 adding dir1/bar.whole
539 adding dir1/bar.whole
540 adding dir1/dir2/baz.whole
540 adding dir1/dir2/baz.whole
541 adding foo.whole
541 adding foo.whole
542 $ hg fix --working-dir dir1
542 $ hg fix --working-dir dir1
543 $ cat foo.whole dir1/bar.whole dir1/dir2/baz.whole
543 $ cat foo.whole dir1/bar.whole dir1/dir2/baz.whole
544 foo
544 foo
545 BAR
545 BAR
546 BAZ
546 BAZ
547
547
548 $ cd ..
548 $ cd ..
549
549
550 Fixing a file in the working directory that needs no fixes should not actually
550 Fixing a file in the working directory that needs no fixes should not actually
551 write back to the file, so for example the mtime shouldn't change.
551 write back to the file, so for example the mtime shouldn't change.
552
552
553 $ hg init donttouchunfixedfiles
553 $ hg init donttouchunfixedfiles
554 $ cd donttouchunfixedfiles
554 $ cd donttouchunfixedfiles
555
555
556 $ printf "NO FIX NEEDED\n" > foo.whole
556 $ printf "NO FIX NEEDED\n" > foo.whole
557 $ hg add
557 $ hg add
558 adding foo.whole
558 adding foo.whole
559 $ cp -p foo.whole foo.whole.orig
559 $ cp -p foo.whole foo.whole.orig
560 $ cp -p foo.whole.orig foo.whole
560 $ cp -p foo.whole.orig foo.whole
561 $ sleep 2 # mtime has a resolution of one or two seconds.
561 $ sleep 2 # mtime has a resolution of one or two seconds.
562 $ hg fix --working-dir
562 $ hg fix --working-dir
563 $ f foo.whole.orig --newer foo.whole
563 $ f foo.whole.orig --newer foo.whole
564 foo.whole.orig: newer than foo.whole
564 foo.whole.orig: newer than foo.whole
565
565
566 $ cd ..
566 $ cd ..
567
567
568 When a fixer prints to stderr, we don't assume that it has failed. We show the
568 When a fixer prints to stderr, we don't assume that it has failed. We show the
569 error messages to the user, and we still let the fixer affect the file it was
569 error messages to the user, and we still let the fixer affect the file it was
570 fixing if its exit code is zero. Some code formatters might emit error messages
570 fixing if its exit code is zero. Some code formatters might emit error messages
571 on stderr and nothing on stdout, which would cause us the clear the file,
571 on stderr and nothing on stdout, which would cause us the clear the file,
572 except that they also exit with a non-zero code. We show the user which fixer
572 except that they also exit with a non-zero code. We show the user which fixer
573 emitted the stderr, and which revision, but we assume that the fixer will print
573 emitted the stderr, and which revision, but we assume that the fixer will print
574 the filename if it is relevant (since the issue may be non-specific). There is
574 the filename if it is relevant (since the issue may be non-specific). There is
575 also a config to abort (without affecting any files whatsoever) if we see any
575 also a config to abort (without affecting any files whatsoever) if we see any
576 tool with a non-zero exit status.
576 tool with a non-zero exit status.
577
577
578 $ hg init showstderr
578 $ hg init showstderr
579 $ cd showstderr
579 $ cd showstderr
580
580
581 $ printf "hello\n" > hello.txt
581 $ printf "hello\n" > hello.txt
582 $ hg add
582 $ hg add
583 adding hello.txt
583 adding hello.txt
584 $ cat > $TESTTMP/work.sh <<'EOF'
584 $ cat > $TESTTMP/work.sh <<'EOF'
585 > printf 'HELLO\n'
585 > printf 'HELLO\n'
586 > printf "$@: some\nerror that didn't stop the tool" >&2
586 > printf "$@: some\nerror that didn't stop the tool" >&2
587 > exit 0 # success despite the stderr output
587 > exit 0 # success despite the stderr output
588 > EOF
588 > EOF
589 $ hg --config "fix.work:command=sh $TESTTMP/work.sh {rootpath}" \
589 $ hg --config "fix.work:command=sh $TESTTMP/work.sh {rootpath}" \
590 > --config "fix.work:pattern=hello.txt" \
590 > --config "fix.work:pattern=hello.txt" \
591 > fix --working-dir
591 > fix --working-dir
592 [wdir] work: hello.txt: some
592 [wdir] work: hello.txt: some
593 [wdir] work: error that didn't stop the tool
593 [wdir] work: error that didn't stop the tool
594 $ cat hello.txt
594 $ cat hello.txt
595 HELLO
595 HELLO
596
596
597 $ printf "goodbye\n" > hello.txt
597 $ printf "goodbye\n" > hello.txt
598 $ printf "foo\n" > foo.whole
598 $ printf "foo\n" > foo.whole
599 $ hg add
599 $ hg add
600 adding foo.whole
600 adding foo.whole
601 $ cat > $TESTTMP/fail.sh <<'EOF'
601 $ cat > $TESTTMP/fail.sh <<'EOF'
602 > printf 'GOODBYE\n'
602 > printf 'GOODBYE\n'
603 > printf "$@: some\nerror that did stop the tool\n" >&2
603 > printf "$@: some\nerror that did stop the tool\n" >&2
604 > exit 42 # success despite the stdout output
604 > exit 42 # success despite the stdout output
605 > EOF
605 > EOF
606 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
606 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
607 > --config "fix.fail:pattern=hello.txt" \
607 > --config "fix.fail:pattern=hello.txt" \
608 > --config "fix.failure=abort" \
608 > --config "fix.failure=abort" \
609 > fix --working-dir
609 > fix --working-dir
610 [wdir] fail: hello.txt: some
610 [wdir] fail: hello.txt: some
611 [wdir] fail: error that did stop the tool
611 [wdir] fail: error that did stop the tool
612 abort: no fixes will be applied
612 abort: no fixes will be applied
613 (use --config fix.failure=continue to apply any successful fixes anyway)
613 (use --config fix.failure=continue to apply any successful fixes anyway)
614 [255]
614 [255]
615 $ cat hello.txt
615 $ cat hello.txt
616 goodbye
616 goodbye
617 $ cat foo.whole
617 $ cat foo.whole
618 foo
618 foo
619
619
620 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
620 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
621 > --config "fix.fail:pattern=hello.txt" \
621 > --config "fix.fail:pattern=hello.txt" \
622 > fix --working-dir
622 > fix --working-dir
623 [wdir] fail: hello.txt: some
623 [wdir] fail: hello.txt: some
624 [wdir] fail: error that did stop the tool
624 [wdir] fail: error that did stop the tool
625 $ cat hello.txt
625 $ cat hello.txt
626 goodbye
626 goodbye
627 $ cat foo.whole
627 $ cat foo.whole
628 FOO
628 FOO
629
629
630 $ hg --config "fix.fail:command=exit 42" \
630 $ hg --config "fix.fail:command=exit 42" \
631 > --config "fix.fail:pattern=hello.txt" \
631 > --config "fix.fail:pattern=hello.txt" \
632 > fix --working-dir
632 > fix --working-dir
633 [wdir] fail: exited with status 42
633 [wdir] fail: exited with status 42
634
634
635 $ cd ..
635 $ cd ..
636
636
637 Fixing the working directory and its parent revision at the same time should
637 Fixing the working directory and its parent revision at the same time should
638 check out the replacement revision for the parent. This prevents any new
638 check out the replacement revision for the parent. This prevents any new
639 uncommitted changes from appearing. We test this for a clean working directory
639 uncommitted changes from appearing. We test this for a clean working directory
640 and a dirty one. In both cases, all lines/files changed since the grandparent
640 and a dirty one. In both cases, all lines/files changed since the grandparent
641 will be fixed. The grandparent is the "baserev" for both the parent and the
641 will be fixed. The grandparent is the "baserev" for both the parent and the
642 working copy.
642 working copy.
643
643
644 $ hg init fixdotandcleanwdir
644 $ hg init fixdotandcleanwdir
645 $ cd fixdotandcleanwdir
645 $ cd fixdotandcleanwdir
646
646
647 $ printf "hello\n" > hello.whole
647 $ printf "hello\n" > hello.whole
648 $ printf "world\n" > world.whole
648 $ printf "world\n" > world.whole
649 $ hg commit -Aqm "the parent commit"
649 $ hg commit -Aqm "the parent commit"
650
650
651 $ hg parents --template '{rev} {desc}\n'
651 $ hg parents --template '{rev} {desc}\n'
652 0 the parent commit
652 0 the parent commit
653 $ hg fix --working-dir -r .
653 $ hg fix --working-dir -r .
654 $ hg parents --template '{rev} {desc}\n'
654 $ hg parents --template '{rev} {desc}\n'
655 1 the parent commit
655 1 the parent commit
656 $ hg cat -r . *.whole
656 $ hg cat -r . *.whole
657 HELLO
657 HELLO
658 WORLD
658 WORLD
659 $ cat *.whole
659 $ cat *.whole
660 HELLO
660 HELLO
661 WORLD
661 WORLD
662 $ hg status
662 $ hg status
663
663
664 $ cd ..
664 $ cd ..
665
665
666 Same test with a dirty working copy.
666 Same test with a dirty working copy.
667
667
668 $ hg init fixdotanddirtywdir
668 $ hg init fixdotanddirtywdir
669 $ cd fixdotanddirtywdir
669 $ cd fixdotanddirtywdir
670
670
671 $ printf "hello\n" > hello.whole
671 $ printf "hello\n" > hello.whole
672 $ printf "world\n" > world.whole
672 $ printf "world\n" > world.whole
673 $ hg commit -Aqm "the parent commit"
673 $ hg commit -Aqm "the parent commit"
674
674
675 $ printf "hello,\n" > hello.whole
675 $ printf "hello,\n" > hello.whole
676 $ printf "world!\n" > world.whole
676 $ printf "world!\n" > world.whole
677
677
678 $ hg parents --template '{rev} {desc}\n'
678 $ hg parents --template '{rev} {desc}\n'
679 0 the parent commit
679 0 the parent commit
680 $ hg fix --working-dir -r .
680 $ hg fix --working-dir -r .
681 $ hg parents --template '{rev} {desc}\n'
681 $ hg parents --template '{rev} {desc}\n'
682 1 the parent commit
682 1 the parent commit
683 $ hg cat -r . *.whole
683 $ hg cat -r . *.whole
684 HELLO
684 HELLO
685 WORLD
685 WORLD
686 $ cat *.whole
686 $ cat *.whole
687 HELLO,
687 HELLO,
688 WORLD!
688 WORLD!
689 $ hg status
689 $ hg status
690 M hello.whole
690 M hello.whole
691 M world.whole
691 M world.whole
692
692
693 $ cd ..
693 $ cd ..
694
694
695 When we have a chain of commits that change mutually exclusive lines of code,
695 When we have a chain of commits that change mutually exclusive lines of code,
696 we should be able to do incremental fixing that causes each commit in the chain
696 we should be able to do incremental fixing that causes each commit in the chain
697 to include fixes made to the previous commits. This prevents children from
697 to include fixes made to the previous commits. This prevents children from
698 backing out the fixes made in their parents. A dirty working directory is
698 backing out the fixes made in their parents. A dirty working directory is
699 conceptually similar to another commit in the chain.
699 conceptually similar to another commit in the chain.
700
700
701 $ hg init incrementallyfixchain
701 $ hg init incrementallyfixchain
702 $ cd incrementallyfixchain
702 $ cd incrementallyfixchain
703
703
704 $ cat > file.changed <<EOF
704 $ cat > file.changed <<EOF
705 > first
705 > first
706 > second
706 > second
707 > third
707 > third
708 > fourth
708 > fourth
709 > fifth
709 > fifth
710 > EOF
710 > EOF
711 $ hg commit -Aqm "the common ancestor (the baserev)"
711 $ hg commit -Aqm "the common ancestor (the baserev)"
712 $ cat > file.changed <<EOF
712 $ cat > file.changed <<EOF
713 > first (changed)
713 > first (changed)
714 > second
714 > second
715 > third
715 > third
716 > fourth
716 > fourth
717 > fifth
717 > fifth
718 > EOF
718 > EOF
719 $ hg commit -Aqm "the first commit to fix"
719 $ hg commit -Aqm "the first commit to fix"
720 $ cat > file.changed <<EOF
720 $ cat > file.changed <<EOF
721 > first (changed)
721 > first (changed)
722 > second
722 > second
723 > third (changed)
723 > third (changed)
724 > fourth
724 > fourth
725 > fifth
725 > fifth
726 > EOF
726 > EOF
727 $ hg commit -Aqm "the second commit to fix"
727 $ hg commit -Aqm "the second commit to fix"
728 $ cat > file.changed <<EOF
728 $ cat > file.changed <<EOF
729 > first (changed)
729 > first (changed)
730 > second
730 > second
731 > third (changed)
731 > third (changed)
732 > fourth
732 > fourth
733 > fifth (changed)
733 > fifth (changed)
734 > EOF
734 > EOF
735
735
736 $ hg fix -r . -r '.^' --working-dir
736 $ hg fix -r . -r '.^' --working-dir
737
737
738 $ hg parents --template '{rev}\n'
738 $ hg parents --template '{rev}\n'
739 4
739 4
740 $ hg cat -r '.^^' file.changed
740 $ hg cat -r '.^^' file.changed
741 first
741 first
742 second
742 second
743 third
743 third
744 fourth
744 fourth
745 fifth
745 fifth
746 $ hg cat -r '.^' file.changed
746 $ hg cat -r '.^' file.changed
747 FIRST (CHANGED)
747 FIRST (CHANGED)
748 second
748 second
749 third
749 third
750 fourth
750 fourth
751 fifth
751 fifth
752 $ hg cat -r . file.changed
752 $ hg cat -r . file.changed
753 FIRST (CHANGED)
753 FIRST (CHANGED)
754 second
754 second
755 THIRD (CHANGED)
755 THIRD (CHANGED)
756 fourth
756 fourth
757 fifth
757 fifth
758 $ cat file.changed
758 $ cat file.changed
759 FIRST (CHANGED)
759 FIRST (CHANGED)
760 second
760 second
761 THIRD (CHANGED)
761 THIRD (CHANGED)
762 fourth
762 fourth
763 FIFTH (CHANGED)
763 FIFTH (CHANGED)
764
764
765 $ cd ..
765 $ cd ..
766
766
767 If we incrementally fix a merge commit, we should fix any lines that changed
767 If we incrementally fix a merge commit, we should fix any lines that changed
768 versus either parent. You could imagine only fixing the intersection or some
768 versus either parent. You could imagine only fixing the intersection or some
769 other subset, but this is necessary if either parent is being fixed. It
769 other subset, but this is necessary if either parent is being fixed. It
770 prevents us from forgetting fixes made in either parent.
770 prevents us from forgetting fixes made in either parent.
771
771
772 $ hg init incrementallyfixmergecommit
772 $ hg init incrementallyfixmergecommit
773 $ cd incrementallyfixmergecommit
773 $ cd incrementallyfixmergecommit
774
774
775 $ printf "a\nb\nc\n" > file.changed
775 $ printf "a\nb\nc\n" > file.changed
776 $ hg commit -Aqm "ancestor"
776 $ hg commit -Aqm "ancestor"
777
777
778 $ printf "aa\nb\nc\n" > file.changed
778 $ printf "aa\nb\nc\n" > file.changed
779 $ hg commit -m "change a"
779 $ hg commit -m "change a"
780
780
781 $ hg checkout '.^'
781 $ hg checkout '.^'
782 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
782 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
783 $ printf "a\nb\ncc\n" > file.changed
783 $ printf "a\nb\ncc\n" > file.changed
784 $ hg commit -m "change c"
784 $ hg commit -m "change c"
785 created new head
785 created new head
786
786
787 $ hg merge
787 $ hg merge
788 merging file.changed
788 merging file.changed
789 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
789 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
790 (branch merge, don't forget to commit)
790 (branch merge, don't forget to commit)
791 $ hg commit -m "merge"
791 $ hg commit -m "merge"
792 $ hg cat -r . file.changed
792 $ hg cat -r . file.changed
793 aa
793 aa
794 b
794 b
795 cc
795 cc
796
796
797 $ hg fix -r . --working-dir
797 $ hg fix -r . --working-dir
798 $ hg cat -r . file.changed
798 $ hg cat -r . file.changed
799 AA
799 AA
800 b
800 b
801 CC
801 CC
802
802
803 $ cd ..
803 $ cd ..
804
804
805 Abort fixing revisions if there is an unfinished operation. We don't want to
805 Abort fixing revisions if there is an unfinished operation. We don't want to
806 make things worse by editing files or stripping/obsoleting things. Also abort
806 make things worse by editing files or stripping/obsoleting things. Also abort
807 fixing the working directory if there are unresolved merge conflicts.
807 fixing the working directory if there are unresolved merge conflicts.
808
808
809 $ hg init abortunresolved
809 $ hg init abortunresolved
810 $ cd abortunresolved
810 $ cd abortunresolved
811
811
812 $ echo "foo1" > foo.whole
812 $ echo "foo1" > foo.whole
813 $ hg commit -Aqm "foo 1"
813 $ hg commit -Aqm "foo 1"
814
814
815 $ hg update null
815 $ hg update null
816 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
816 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
817 $ echo "foo2" > foo.whole
817 $ echo "foo2" > foo.whole
818 $ hg commit -Aqm "foo 2"
818 $ hg commit -Aqm "foo 2"
819
819
820 $ hg --config extensions.rebase= rebase -r 1 -d 0
820 $ hg --config extensions.rebase= rebase -r 1 -d 0
821 rebasing 1:c3b6dc0e177a "foo 2" (tip)
821 rebasing 1:c3b6dc0e177a "foo 2" (tip)
822 merging foo.whole
822 merging foo.whole
823 warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
823 warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
824 unresolved conflicts (see hg resolve, then hg rebase --continue)
824 unresolved conflicts (see hg resolve, then hg rebase --continue)
825 [1]
825 [1]
826
826
827 $ hg --config extensions.rebase= fix --working-dir
827 $ hg --config extensions.rebase= fix --working-dir
828 abort: unresolved conflicts
828 abort: unresolved conflicts
829 (use 'hg resolve')
829 (use 'hg resolve')
830 [255]
830 [255]
831
831
832 $ hg --config extensions.rebase= fix -r .
832 $ hg --config extensions.rebase= fix -r .
833 abort: rebase in progress
833 abort: rebase in progress
834 (use 'hg rebase --continue' or 'hg rebase --abort')
834 (use 'hg rebase --continue' or 'hg rebase --abort')
835 [255]
835 [255]
836
836
837 $ cd ..
837 $ cd ..
838
838
839 When fixing a file that was renamed, we should diff against the source of the
839 When fixing a file that was renamed, we should diff against the source of the
840 rename for incremental fixing and we should correctly reproduce the rename in
840 rename for incremental fixing and we should correctly reproduce the rename in
841 the replacement revision.
841 the replacement revision.
842
842
843 $ hg init fixrenamecommit
843 $ hg init fixrenamecommit
844 $ cd fixrenamecommit
844 $ cd fixrenamecommit
845
845
846 $ printf "a\nb\nc\n" > source.changed
846 $ printf "a\nb\nc\n" > source.changed
847 $ hg commit -Aqm "source revision"
847 $ hg commit -Aqm "source revision"
848 $ hg move source.changed dest.changed
848 $ hg move source.changed dest.changed
849 $ printf "a\nb\ncc\n" > dest.changed
849 $ printf "a\nb\ncc\n" > dest.changed
850 $ hg commit -m "dest revision"
850 $ hg commit -m "dest revision"
851
851
852 $ hg fix -r .
852 $ hg fix -r .
853 $ hg log -r tip --copies --template "{file_copies}\n"
853 $ hg log -r tip --copies --template "{file_copies}\n"
854 dest.changed (source.changed)
854 dest.changed (source.changed)
855 $ hg cat -r tip dest.changed
855 $ hg cat -r tip dest.changed
856 a
856 a
857 b
857 b
858 CC
858 CC
859
859
860 $ cd ..
860 $ cd ..
861
861
862 When fixing revisions that remove files we must ensure that the replacement
862 When fixing revisions that remove files we must ensure that the replacement
863 actually removes the file, whereas it could accidentally leave it unchanged or
863 actually removes the file, whereas it could accidentally leave it unchanged or
864 write an empty string to it.
864 write an empty string to it.
865
865
866 $ hg init fixremovedfile
866 $ hg init fixremovedfile
867 $ cd fixremovedfile
867 $ cd fixremovedfile
868
868
869 $ printf "foo\n" > foo.whole
869 $ printf "foo\n" > foo.whole
870 $ printf "bar\n" > bar.whole
870 $ printf "bar\n" > bar.whole
871 $ hg commit -Aqm "add files"
871 $ hg commit -Aqm "add files"
872 $ hg remove bar.whole
872 $ hg remove bar.whole
873 $ hg commit -m "remove file"
873 $ hg commit -m "remove file"
874 $ hg status --change .
874 $ hg status --change .
875 R bar.whole
875 R bar.whole
876 $ hg fix -r . foo.whole
876 $ hg fix -r . foo.whole
877 $ hg status --change tip
877 $ hg status --change tip
878 M foo.whole
878 M foo.whole
879 R bar.whole
879 R bar.whole
880
880
881 $ cd ..
881 $ cd ..
882
882
883 If fixing a revision finds no fixes to make, no replacement revision should be
883 If fixing a revision finds no fixes to make, no replacement revision should be
884 created.
884 created.
885
885
886 $ hg init nofixesneeded
886 $ hg init nofixesneeded
887 $ cd nofixesneeded
887 $ cd nofixesneeded
888
888
889 $ printf "FOO\n" > foo.whole
889 $ printf "FOO\n" > foo.whole
890 $ hg commit -Aqm "add file"
890 $ hg commit -Aqm "add file"
891 $ hg log --template '{rev}\n'
891 $ hg log --template '{rev}\n'
892 0
892 0
893 $ hg fix -r .
893 $ hg fix -r .
894 $ hg log --template '{rev}\n'
894 $ hg log --template '{rev}\n'
895 0
895 0
896
896
897 $ cd ..
897 $ cd ..
898
898
899 If fixing a commit reverts all the changes in the commit, we replace it with a
899 If fixing a commit reverts all the changes in the commit, we replace it with a
900 commit that changes no files.
900 commit that changes no files.
901
901
902 $ hg init nochangesleft
902 $ hg init nochangesleft
903 $ cd nochangesleft
903 $ cd nochangesleft
904
904
905 $ printf "FOO\n" > foo.whole
905 $ printf "FOO\n" > foo.whole
906 $ hg commit -Aqm "add file"
906 $ hg commit -Aqm "add file"
907 $ printf "foo\n" > foo.whole
907 $ printf "foo\n" > foo.whole
908 $ hg commit -m "edit file"
908 $ hg commit -m "edit file"
909 $ hg status --change .
909 $ hg status --change .
910 M foo.whole
910 M foo.whole
911 $ hg fix -r .
911 $ hg fix -r .
912 $ hg status --change tip
912 $ hg status --change tip
913
913
914 $ cd ..
914 $ cd ..
915
915
916 If we fix a parent and child revision together, the child revision must be
916 If we fix a parent and child revision together, the child revision must be
917 replaced if the parent is replaced, even if the diffs of the child needed no
917 replaced if the parent is replaced, even if the diffs of the child needed no
918 fixes. However, we're free to not replace revisions that need no fixes and have
918 fixes. However, we're free to not replace revisions that need no fixes and have
919 no ancestors that are replaced.
919 no ancestors that are replaced.
920
920
921 $ hg init mustreplacechild
921 $ hg init mustreplacechild
922 $ cd mustreplacechild
922 $ cd mustreplacechild
923
923
924 $ printf "FOO\n" > foo.whole
924 $ printf "FOO\n" > foo.whole
925 $ hg commit -Aqm "add foo"
925 $ hg commit -Aqm "add foo"
926 $ printf "foo\n" > foo.whole
926 $ printf "foo\n" > foo.whole
927 $ hg commit -m "edit foo"
927 $ hg commit -m "edit foo"
928 $ printf "BAR\n" > bar.whole
928 $ printf "BAR\n" > bar.whole
929 $ hg commit -Aqm "add bar"
929 $ hg commit -Aqm "add bar"
930
930
931 $ hg log --graph --template '{rev} {files}'
931 $ hg log --graph --template '{rev} {files}'
932 @ 2 bar.whole
932 @ 2 bar.whole
933 |
933 |
934 o 1 foo.whole
934 o 1 foo.whole
935 |
935 |
936 o 0 foo.whole
936 o 0 foo.whole
937
937
938 $ hg fix -r 0:2
938 $ hg fix -r 0:2
939 $ hg log --graph --template '{rev} {files}'
939 $ hg log --graph --template '{rev} {files}'
940 o 4 bar.whole
940 o 4 bar.whole
941 |
941 |
942 o 3
942 o 3
943 |
943 |
944 | @ 2 bar.whole
944 | @ 2 bar.whole
945 | |
945 | |
946 | x 1 foo.whole
946 | x 1 foo.whole
947 |/
947 |/
948 o 0 foo.whole
948 o 0 foo.whole
949
949
950
950
951 $ cd ..
951 $ cd ..
952
952
953 It's also possible that the child needs absolutely no changes, but we still
953 It's also possible that the child needs absolutely no changes, but we still
954 need to replace it to update its parent. If we skipped replacing the child
954 need to replace it to update its parent. If we skipped replacing the child
955 because it had no file content changes, it would become an orphan for no good
955 because it had no file content changes, it would become an orphan for no good
956 reason.
956 reason.
957
957
958 $ hg init mustreplacechildevenifnop
958 $ hg init mustreplacechildevenifnop
959 $ cd mustreplacechildevenifnop
959 $ cd mustreplacechildevenifnop
960
960
961 $ printf "Foo\n" > foo.whole
961 $ printf "Foo\n" > foo.whole
962 $ hg commit -Aqm "add a bad foo"
962 $ hg commit -Aqm "add a bad foo"
963 $ printf "FOO\n" > foo.whole
963 $ printf "FOO\n" > foo.whole
964 $ hg commit -m "add a good foo"
964 $ hg commit -m "add a good foo"
965 $ hg fix -r . -r '.^'
965 $ hg fix -r . -r '.^'
966 $ hg log --graph --template '{rev} {desc}'
966 $ hg log --graph --template '{rev} {desc}'
967 o 3 add a good foo
967 o 3 add a good foo
968 |
968 |
969 o 2 add a bad foo
969 o 2 add a bad foo
970
970
971 @ 1 add a good foo
971 @ 1 add a good foo
972 |
972 |
973 x 0 add a bad foo
973 x 0 add a bad foo
974
974
975
975
976 $ cd ..
976 $ cd ..
977
977
978 Similar to the case above, the child revision may become empty as a result of
978 Similar to the case above, the child revision may become empty as a result of
979 fixing its parent. We should still create an empty replacement child.
979 fixing its parent. We should still create an empty replacement child.
980 TODO: determine how this should interact with ui.allowemptycommit given that
980 TODO: determine how this should interact with ui.allowemptycommit given that
981 the empty replacement could have children.
981 the empty replacement could have children.
982
982
983 $ hg init mustreplacechildevenifempty
983 $ hg init mustreplacechildevenifempty
984 $ cd mustreplacechildevenifempty
984 $ cd mustreplacechildevenifempty
985
985
986 $ printf "foo\n" > foo.whole
986 $ printf "foo\n" > foo.whole
987 $ hg commit -Aqm "add foo"
987 $ hg commit -Aqm "add foo"
988 $ printf "Foo\n" > foo.whole
988 $ printf "Foo\n" > foo.whole
989 $ hg commit -m "edit foo"
989 $ hg commit -m "edit foo"
990 $ hg fix -r . -r '.^'
990 $ hg fix -r . -r '.^'
991 $ hg log --graph --template '{rev} {desc}\n' --stat
991 $ hg log --graph --template '{rev} {desc}\n' --stat
992 o 3 edit foo
992 o 3 edit foo
993 |
993 |
994 o 2 add foo
994 o 2 add foo
995 foo.whole | 1 +
995 foo.whole | 1 +
996 1 files changed, 1 insertions(+), 0 deletions(-)
996 1 files changed, 1 insertions(+), 0 deletions(-)
997
997
998 @ 1 edit foo
998 @ 1 edit foo
999 | foo.whole | 2 +-
999 | foo.whole | 2 +-
1000 | 1 files changed, 1 insertions(+), 1 deletions(-)
1000 | 1 files changed, 1 insertions(+), 1 deletions(-)
1001 |
1001 |
1002 x 0 add foo
1002 x 0 add foo
1003 foo.whole | 1 +
1003 foo.whole | 1 +
1004 1 files changed, 1 insertions(+), 0 deletions(-)
1004 1 files changed, 1 insertions(+), 0 deletions(-)
1005
1005
1006
1006
1007 $ cd ..
1007 $ cd ..
1008
1008
1009 Fixing a secret commit should replace it with another secret commit.
1009 Fixing a secret commit should replace it with another secret commit.
1010
1010
1011 $ hg init fixsecretcommit
1011 $ hg init fixsecretcommit
1012 $ cd fixsecretcommit
1012 $ cd fixsecretcommit
1013
1013
1014 $ printf "foo\n" > foo.whole
1014 $ printf "foo\n" > foo.whole
1015 $ hg commit -Aqm "add foo" --secret
1015 $ hg commit -Aqm "add foo" --secret
1016 $ hg fix -r .
1016 $ hg fix -r .
1017 $ hg log --template '{rev} {phase}\n'
1017 $ hg log --template '{rev} {phase}\n'
1018 1 secret
1018 1 secret
1019 0 secret
1019 0 secret
1020
1020
1021 $ cd ..
1021 $ cd ..
1022
1022
1023 We should also preserve phase when fixing a draft commit while the user has
1023 We should also preserve phase when fixing a draft commit while the user has
1024 their default set to secret.
1024 their default set to secret.
1025
1025
1026 $ hg init respectphasesnewcommit
1026 $ hg init respectphasesnewcommit
1027 $ cd respectphasesnewcommit
1027 $ cd respectphasesnewcommit
1028
1028
1029 $ printf "foo\n" > foo.whole
1029 $ printf "foo\n" > foo.whole
1030 $ hg commit -Aqm "add foo"
1030 $ hg commit -Aqm "add foo"
1031 $ hg --config phases.newcommit=secret fix -r .
1031 $ hg --config phases.newcommit=secret fix -r .
1032 $ hg log --template '{rev} {phase}\n'
1032 $ hg log --template '{rev} {phase}\n'
1033 1 draft
1033 1 draft
1034 0 draft
1034 0 draft
1035
1035
1036 $ cd ..
1036 $ cd ..
1037
1037
1038 Debug output should show what fixer commands are being subprocessed, which is
1038 Debug output should show what fixer commands are being subprocessed, which is
1039 useful for anyone trying to set up a new config.
1039 useful for anyone trying to set up a new config.
1040
1040
1041 $ hg init debugoutput
1041 $ hg init debugoutput
1042 $ cd debugoutput
1042 $ cd debugoutput
1043
1043
1044 $ printf "foo\nbar\nbaz\n" > foo.changed
1044 $ printf "foo\nbar\nbaz\n" > foo.changed
1045 $ hg commit -Aqm "foo"
1045 $ hg commit -Aqm "foo"
1046 $ printf "Foo\nbar\nBaz\n" > foo.changed
1046 $ printf "Foo\nbar\nBaz\n" > foo.changed
1047 $ hg --debug fix --working-dir
1047 $ hg --debug fix --working-dir
1048 subprocess: * $TESTTMP/uppercase.py 1-1 3-3 (glob)
1048 subprocess: * $TESTTMP/uppercase.py 1-1 3-3 (glob)
1049
1049
1050 $ cd ..
1050 $ cd ..
1051
1051
1052 Fixing an obsolete revision can cause divergence, so we abort unless the user
1052 Fixing an obsolete revision can cause divergence, so we abort unless the user
1053 configures to allow it. This is not yet smart enough to know whether there is a
1053 configures to allow it. This is not yet smart enough to know whether there is a
1054 successor, but even then it is not likely intentional or idiomatic to fix an
1054 successor, but even then it is not likely intentional or idiomatic to fix an
1055 obsolete revision.
1055 obsolete revision.
1056
1056
1057 $ hg init abortobsoleterev
1057 $ hg init abortobsoleterev
1058 $ cd abortobsoleterev
1058 $ cd abortobsoleterev
1059
1059
1060 $ printf "foo\n" > foo.changed
1060 $ printf "foo\n" > foo.changed
1061 $ hg commit -Aqm "foo"
1061 $ hg commit -Aqm "foo"
1062 $ hg debugobsolete `hg parents --template '{node}'`
1062 $ hg debugobsolete `hg parents --template '{node}'`
1063 obsoleted 1 changesets
1063 obsoleted 1 changesets
1064 $ hg --hidden fix -r 0
1064 $ hg --hidden fix -r 0
1065 abort: fixing obsolete revision could cause divergence
1065 abort: fixing obsolete revision could cause divergence
1066 [255]
1066 [255]
1067
1067
1068 $ hg --hidden fix -r 0 --config experimental.evolution.allowdivergence=true
1068 $ hg --hidden fix -r 0 --config experimental.evolution.allowdivergence=true
1069 $ hg cat -r tip foo.changed
1069 $ hg cat -r tip foo.changed
1070 FOO
1070 FOO
1071
1071
1072 $ cd ..
1072 $ cd ..
1073
1073
1074 Test all of the available substitution values for fixer commands.
1074 Test all of the available substitution values for fixer commands.
1075
1075
1076 $ hg init substitution
1076 $ hg init substitution
1077 $ cd substitution
1077 $ cd substitution
1078
1078
1079 $ mkdir foo
1079 $ mkdir foo
1080 $ printf "hello\ngoodbye\n" > foo/bar
1080 $ printf "hello\ngoodbye\n" > foo/bar
1081 $ hg add
1081 $ hg add
1082 adding foo/bar
1082 adding foo/bar
1083 $ hg --config "fix.fail:command=printf '%s\n' '{rootpath}' '{basename}'" \
1083 $ hg --config "fix.fail:command=printf '%s\n' '{rootpath}' '{basename}'" \
1084 > --config "fix.fail:linerange='{first}' '{last}'" \
1084 > --config "fix.fail:linerange='{first}' '{last}'" \
1085 > --config "fix.fail:pattern=foo/bar" \
1085 > --config "fix.fail:pattern=foo/bar" \
1086 > fix --working-dir
1086 > fix --working-dir
1087 $ cat foo/bar
1087 $ cat foo/bar
1088 foo/bar
1088 foo/bar
1089 bar
1089 bar
1090 1
1090 1
1091 2
1091 2
1092
1092
1093 $ cd ..
1093 $ cd ..
1094
1094
1095 The --base flag should allow picking the revisions to diff against for changed
1095 The --base flag should allow picking the revisions to diff against for changed
1096 files and incremental line formatting.
1096 files and incremental line formatting.
1097
1097
1098 $ hg init baseflag
1098 $ hg init baseflag
1099 $ cd baseflag
1099 $ cd baseflag
1100
1100
1101 $ printf "one\ntwo\n" > foo.changed
1101 $ printf "one\ntwo\n" > foo.changed
1102 $ printf "bar\n" > bar.changed
1102 $ printf "bar\n" > bar.changed
1103 $ hg commit -Aqm "first"
1103 $ hg commit -Aqm "first"
1104 $ printf "one\nTwo\n" > foo.changed
1104 $ printf "one\nTwo\n" > foo.changed
1105 $ hg commit -m "second"
1105 $ hg commit -m "second"
1106 $ hg fix -w --base .
1106 $ hg fix -w --base .
1107 $ hg status
1107 $ hg status
1108 $ hg fix -w --base null
1108 $ hg fix -w --base null
1109 $ cat foo.changed
1109 $ cat foo.changed
1110 ONE
1110 ONE
1111 TWO
1111 TWO
1112 $ cat bar.changed
1112 $ cat bar.changed
1113 BAR
1113 BAR
1114
1114
1115 $ cd ..
1115 $ cd ..
1116
1116
1117 If the user asks to fix the parent of another commit, they are asking to create
1117 If the user asks to fix the parent of another commit, they are asking to create
1118 an orphan. We must respect experimental.evolution.allowunstable.
1118 an orphan. We must respect experimental.evolution.allowunstable.
1119
1119
1120 $ hg init allowunstable
1120 $ hg init allowunstable
1121 $ cd allowunstable
1121 $ cd allowunstable
1122
1122
1123 $ printf "one\n" > foo.whole
1123 $ printf "one\n" > foo.whole
1124 $ hg commit -Aqm "first"
1124 $ hg commit -Aqm "first"
1125 $ printf "two\n" > foo.whole
1125 $ printf "two\n" > foo.whole
1126 $ hg commit -m "second"
1126 $ hg commit -m "second"
1127 $ hg --config experimental.evolution.allowunstable=False fix -r '.^'
1127 $ hg --config experimental.evolution.allowunstable=False fix -r '.^'
1128 abort: can only fix a changeset together with all its descendants
1128 abort: can only fix a changeset together with all its descendants
1129 [255]
1129 [255]
1130 $ hg fix -r '.^'
1130 $ hg fix -r '.^'
1131 1 new orphan changesets
1131 1 new orphan changesets
1132 $ hg cat -r 2 foo.whole
1132 $ hg cat -r 2 foo.whole
1133 ONE
1133 ONE
1134
1134
1135 $ cd ..
1135 $ cd ..
1136
1136
1137 The --base flag affects the set of files being fixed. So while the --whole flag
1137 The --base flag affects the set of files being fixed. So while the --whole flag
1138 makes the base irrelevant for changed line ranges, it still changes the
1138 makes the base irrelevant for changed line ranges, it still changes the
1139 meaning and effect of the command. In this example, no files or lines are fixed
1139 meaning and effect of the command. In this example, no files or lines are fixed
1140 until we specify the base, but then we do fix unchanged lines.
1140 until we specify the base, but then we do fix unchanged lines.
1141
1141
1142 $ hg init basewhole
1142 $ hg init basewhole
1143 $ cd basewhole
1143 $ cd basewhole
1144 $ printf "foo1\n" > foo.changed
1144 $ printf "foo1\n" > foo.changed
1145 $ hg commit -Aqm "first"
1145 $ hg commit -Aqm "first"
1146 $ printf "foo2\n" >> foo.changed
1146 $ printf "foo2\n" >> foo.changed
1147 $ printf "bar\n" > bar.changed
1147 $ printf "bar\n" > bar.changed
1148 $ hg commit -Aqm "second"
1148 $ hg commit -Aqm "second"
1149
1149
1150 $ hg fix --working-dir --whole
1150 $ hg fix --working-dir --whole
1151 $ cat *.changed
1151 $ cat *.changed
1152 bar
1152 bar
1153 foo1
1153 foo1
1154 foo2
1154 foo2
1155
1155
1156 $ hg fix --working-dir --base 0 --whole
1156 $ hg fix --working-dir --base 0 --whole
1157 $ cat *.changed
1157 $ cat *.changed
1158 BAR
1158 BAR
1159 FOO1
1159 FOO1
1160 FOO2
1160 FOO2
1161
1161
1162 $ cd ..
1162 $ cd ..
1163
1163
1164 The execution order of tools can be controlled. This example doesn't work if
1164 The execution order of tools can be controlled. This example doesn't work if
1165 you sort after truncating, but the config defines the correct order while the
1165 you sort after truncating, but the config defines the correct order while the
1166 definitions are out of order (which might imply the incorrect order given the
1166 definitions are out of order (which might imply the incorrect order given the
1167 implementation of fix). The goal is to use multiple tools to select the lowest
1167 implementation of fix). The goal is to use multiple tools to select the lowest
1168 5 numbers in the file.
1168 5 numbers in the file.
1169
1169
1170 $ hg init priorityexample
1170 $ hg init priorityexample
1171 $ cd priorityexample
1171 $ cd priorityexample
1172
1172
1173 $ cat >> .hg/hgrc <<EOF
1173 $ cat >> .hg/hgrc <<EOF
1174 > [fix]
1174 > [fix]
1175 > head:command = head -n 5
1175 > head:command = head -n 5
1176 > head:pattern = numbers.txt
1176 > head:pattern = numbers.txt
1177 > head:priority = 1
1177 > head:priority = 1
1178 > sort:command = sort -n
1178 > sort:command = sort -n
1179 > sort:pattern = numbers.txt
1179 > sort:pattern = numbers.txt
1180 > sort:priority = 2
1180 > sort:priority = 2
1181 > EOF
1181 > EOF
1182
1182
1183 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1183 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1184 $ hg add -q
1184 $ hg add -q
1185 $ hg fix -w
1185 $ hg fix -w
1186 $ cat numbers.txt
1186 $ cat numbers.txt
1187 0
1187 0
1188 1
1188 1
1189 2
1189 2
1190 3
1190 3
1191 4
1191 4
1192
1192
1193 And of course we should be able to break this by reversing the execution order.
1193 And of course we should be able to break this by reversing the execution order.
1194 Test negative priorities while we're at it.
1194 Test negative priorities while we're at it.
1195
1195
1196 $ cat >> .hg/hgrc <<EOF
1196 $ cat >> .hg/hgrc <<EOF
1197 > [fix]
1197 > [fix]
1198 > head:priority = -1
1198 > head:priority = -1
1199 > sort:priority = -2
1199 > sort:priority = -2
1200 > EOF
1200 > EOF
1201 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1201 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1202 $ hg fix -w
1202 $ hg fix -w
1203 $ cat numbers.txt
1203 $ cat numbers.txt
1204 2
1204 2
1205 3
1205 3
1206 6
1206 6
1207 7
1207 7
1208 8
1208 8
1209
1209
1210 $ cd ..
1210 $ cd ..
1211
1211
1212 It's possible for repeated applications of a fixer tool to create cycles in the
1212 It's possible for repeated applications of a fixer tool to create cycles in the
1213 generated content of a file. For example, two users with different versions of
1213 generated content of a file. For example, two users with different versions of
1214 a code formatter might fight over the formatting when they run hg fix. In the
1214 a code formatter might fight over the formatting when they run hg fix. In the
1215 absence of other changes, this means we could produce commits with the same
1215 absence of other changes, this means we could produce commits with the same
1216 hash in subsequent runs of hg fix. This is a problem unless we support
1216 hash in subsequent runs of hg fix. This is a problem unless we support
1217 obsolescence cycles well. We avoid this by adding an extra field to the
1217 obsolescence cycles well. We avoid this by adding an extra field to the
1218 successor which forces it to have a new hash. That's why this test creates
1218 successor which forces it to have a new hash. That's why this test creates
1219 three revisions instead of two.
1219 three revisions instead of two.
1220
1220
1221 $ hg init cyclictool
1221 $ hg init cyclictool
1222 $ cd cyclictool
1222 $ cd cyclictool
1223
1223
1224 $ cat >> .hg/hgrc <<EOF
1224 $ cat >> .hg/hgrc <<EOF
1225 > [fix]
1225 > [fix]
1226 > swapletters:command = tr ab ba
1226 > swapletters:command = tr ab ba
1227 > swapletters:pattern = foo
1227 > swapletters:pattern = foo
1228 > EOF
1228 > EOF
1229
1229
1230 $ echo ab > foo
1230 $ echo ab > foo
1231 $ hg commit -Aqm foo
1231 $ hg commit -Aqm foo
1232
1232
1233 $ hg fix -r 0
1233 $ hg fix -r 0
1234 $ hg fix -r 1
1234 $ hg fix -r 1
1235
1235
1236 $ hg cat -r 0 foo --hidden
1236 $ hg cat -r 0 foo --hidden
1237 ab
1237 ab
1238 $ hg cat -r 1 foo --hidden
1238 $ hg cat -r 1 foo --hidden
1239 ba
1239 ba
1240 $ hg cat -r 2 foo
1240 $ hg cat -r 2 foo
1241 ab
1241 ab
1242
1242
1243 $ cd ..
1243 $ cd ..
1244
1244
1245 Test that we can configure a fixer to affect all files regardless of the cwd.
1246 The way we invoke matching must not prohibit this.
1247
1248 $ hg init affectallfiles
1249 $ cd affectallfiles
1250
1251 $ mkdir foo bar
1252 $ printf "foo" > foo/file
1253 $ printf "bar" > bar/file
1254 $ printf "baz" > baz_file
1255 $ hg add -q
1256
1257 $ cd bar
1258 $ hg fix --working-dir --config "fix.cooltool:command=echo fixed" \
1259 > --config "fix.cooltool:pattern=rootglob:**"
1260 $ cd ..
1261
1262 $ cat foo/file
1263 fixed
1264 $ cat bar/file
1265 fixed
1266 $ cat baz_file
1267 fixed
1268
1269 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now