##// END OF EJS Templates
test-fix: normalize precision of mtime copied by 'cp -p'...
Yuya Nishihara -
r37827:80695628 stable
parent child Browse files
Show More
@@ -1,1028 +1,1029 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:fileset=set:**.whole
69 > uppercase-whole-file:fileset=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:fileset=set:**.changed
72 > uppercase-changed-lines:fileset=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:fileset=set:**.cpp or **.hpp
129 clang-format:fileset=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. If there is any output
133 the fixed file content is expected on standard output. If there is any output
134 on standard error, the file will not be affected. Some values may be
134 on standard error, the file will not be affected. Some values may be
135 substituted into the command:
135 substituted into the command:
136
136
137 {rootpath} The path of the file being fixed, relative to the repo root
137 {rootpath} The path of the file being fixed, relative to the repo root
138 {basename} The name of the file being fixed, without the directory path
138 {basename} The name of the file being fixed, without the directory path
139
139
140 If the :linerange suboption is set, the tool will only be run if there are
140 If the :linerange suboption is set, the tool will only be run if there are
141 changed lines in a file. The value of this suboption is appended to the shell
141 changed lines in a file. The value of this suboption is appended to the shell
142 command once for every range of changed lines in the file. Some values may be
142 command once for every range of changed lines in the file. Some values may be
143 substituted into the command:
143 substituted into the command:
144
144
145 {first} The 1-based line number of the first line in the modified range
145 {first} The 1-based line number of the first line in the modified range
146 {last} The 1-based line number of the last line in the modified range
146 {last} The 1-based line number of the last line in the modified range
147
147
148 The :fileset suboption determines which files will be passed through each
148 The :fileset suboption determines which files will be passed through each
149 configured tool. See 'hg help fileset' for possible values. If there are file
149 configured tool. See 'hg help fileset' for possible values. If there are file
150 arguments to 'hg fix', the intersection of these filesets is used.
150 arguments to 'hg fix', the intersection of these filesets is used.
151
151
152 There is also a configurable limit for the maximum size of file that will be
152 There is also a configurable limit for the maximum size of file that will be
153 processed by 'hg fix':
153 processed by 'hg fix':
154
154
155 [fix]
155 [fix]
156 maxfilesize=2MB
156 maxfilesize=2MB
157
157
158 list of commands:
158 list of commands:
159
159
160 fix rewrite file content in changesets or working directory
160 fix rewrite file content in changesets or working directory
161
161
162 (use 'hg help -v -e fix' to show built-in aliases and global options)
162 (use 'hg help -v -e fix' to show built-in aliases and global options)
163
163
164 There is no default behavior in the absence of --rev and --working-dir.
164 There is no default behavior in the absence of --rev and --working-dir.
165
165
166 $ hg init badusage
166 $ hg init badusage
167 $ cd badusage
167 $ cd badusage
168
168
169 $ hg fix
169 $ hg fix
170 abort: no changesets specified
170 abort: no changesets specified
171 (use --rev or --working-dir)
171 (use --rev or --working-dir)
172 [255]
172 [255]
173 $ hg fix --whole
173 $ hg fix --whole
174 abort: no changesets specified
174 abort: no changesets specified
175 (use --rev or --working-dir)
175 (use --rev or --working-dir)
176 [255]
176 [255]
177 $ hg fix --base 0
177 $ hg fix --base 0
178 abort: no changesets specified
178 abort: no changesets specified
179 (use --rev or --working-dir)
179 (use --rev or --working-dir)
180 [255]
180 [255]
181
181
182 Fixing a public revision isn't allowed. It should abort early enough that
182 Fixing a public revision isn't allowed. It should abort early enough that
183 nothing happens, even to the working directory.
183 nothing happens, even to the working directory.
184
184
185 $ printf "hello\n" > hello.whole
185 $ printf "hello\n" > hello.whole
186 $ hg commit -Aqm "hello"
186 $ hg commit -Aqm "hello"
187 $ hg phase -r 0 --public
187 $ hg phase -r 0 --public
188 $ hg fix -r 0
188 $ hg fix -r 0
189 abort: can't fix immutable changeset 0:6470986d2e7b
189 abort: can't fix immutable changeset 0:6470986d2e7b
190 [255]
190 [255]
191 $ hg fix -r 0 --working-dir
191 $ hg fix -r 0 --working-dir
192 abort: can't fix immutable changeset 0:6470986d2e7b
192 abort: can't fix immutable changeset 0:6470986d2e7b
193 [255]
193 [255]
194 $ hg cat -r tip hello.whole
194 $ hg cat -r tip hello.whole
195 hello
195 hello
196 $ cat hello.whole
196 $ cat hello.whole
197 hello
197 hello
198
198
199 $ cd ..
199 $ cd ..
200
200
201 Fixing a clean working directory should do nothing. Even the --whole flag
201 Fixing a clean working directory should do nothing. Even the --whole flag
202 shouldn't cause any clean files to be fixed. Specifying a clean file explicitly
202 shouldn't cause any clean files to be fixed. Specifying a clean file explicitly
203 should only fix it if the fixer always fixes the whole file. The combination of
203 should only fix it if the fixer always fixes the whole file. The combination of
204 an explicit filename and --whole should format the entire file regardless.
204 an explicit filename and --whole should format the entire file regardless.
205
205
206 $ hg init fixcleanwdir
206 $ hg init fixcleanwdir
207 $ cd fixcleanwdir
207 $ cd fixcleanwdir
208
208
209 $ printf "hello\n" > hello.changed
209 $ printf "hello\n" > hello.changed
210 $ printf "world\n" > hello.whole
210 $ printf "world\n" > hello.whole
211 $ hg commit -Aqm "foo"
211 $ hg commit -Aqm "foo"
212 $ hg fix --working-dir
212 $ hg fix --working-dir
213 $ hg diff
213 $ hg diff
214 $ hg fix --working-dir --whole
214 $ hg fix --working-dir --whole
215 $ hg diff
215 $ hg diff
216 $ hg fix --working-dir *
216 $ hg fix --working-dir *
217 $ cat *
217 $ cat *
218 hello
218 hello
219 WORLD
219 WORLD
220 $ hg revert --all --no-backup
220 $ hg revert --all --no-backup
221 reverting hello.whole
221 reverting hello.whole
222 $ hg fix --working-dir * --whole
222 $ hg fix --working-dir * --whole
223 $ cat *
223 $ cat *
224 HELLO
224 HELLO
225 WORLD
225 WORLD
226
226
227 The same ideas apply to fixing a revision, so we create a revision that doesn't
227 The same ideas apply to fixing a revision, so we create a revision that doesn't
228 modify either of the files in question and try fixing it. This also tests that
228 modify either of the files in question and try fixing it. This also tests that
229 we ignore a file that doesn't match any configured fixer.
229 we ignore a file that doesn't match any configured fixer.
230
230
231 $ hg revert --all --no-backup
231 $ hg revert --all --no-backup
232 reverting hello.changed
232 reverting hello.changed
233 reverting hello.whole
233 reverting hello.whole
234 $ printf "unimportant\n" > some.file
234 $ printf "unimportant\n" > some.file
235 $ hg commit -Aqm "some other file"
235 $ hg commit -Aqm "some other file"
236
236
237 $ hg fix -r .
237 $ hg fix -r .
238 $ hg cat -r tip *
238 $ hg cat -r tip *
239 hello
239 hello
240 world
240 world
241 unimportant
241 unimportant
242 $ hg fix -r . --whole
242 $ hg fix -r . --whole
243 $ hg cat -r tip *
243 $ hg cat -r tip *
244 hello
244 hello
245 world
245 world
246 unimportant
246 unimportant
247 $ hg fix -r . *
247 $ hg fix -r . *
248 $ hg cat -r tip *
248 $ hg cat -r tip *
249 hello
249 hello
250 WORLD
250 WORLD
251 unimportant
251 unimportant
252 $ hg fix -r . * --whole --config experimental.evolution.allowdivergence=true
252 $ hg fix -r . * --whole --config experimental.evolution.allowdivergence=true
253 2 new content-divergent changesets
253 2 new content-divergent changesets
254 $ hg cat -r tip *
254 $ hg cat -r tip *
255 HELLO
255 HELLO
256 WORLD
256 WORLD
257 unimportant
257 unimportant
258
258
259 $ cd ..
259 $ cd ..
260
260
261 Fixing the working directory should still work if there are no revisions.
261 Fixing the working directory should still work if there are no revisions.
262
262
263 $ hg init norevisions
263 $ hg init norevisions
264 $ cd norevisions
264 $ cd norevisions
265
265
266 $ printf "something\n" > something.whole
266 $ printf "something\n" > something.whole
267 $ hg add
267 $ hg add
268 adding something.whole
268 adding something.whole
269 $ hg fix --working-dir
269 $ hg fix --working-dir
270 $ cat something.whole
270 $ cat something.whole
271 SOMETHING
271 SOMETHING
272
272
273 $ cd ..
273 $ cd ..
274
274
275 Test the effect of fixing the working directory for each possible status, with
275 Test the effect of fixing the working directory for each possible status, with
276 and without providing explicit file arguments.
276 and without providing explicit file arguments.
277
277
278 $ hg init implicitlyfixstatus
278 $ hg init implicitlyfixstatus
279 $ cd implicitlyfixstatus
279 $ cd implicitlyfixstatus
280
280
281 $ printf "modified\n" > modified.whole
281 $ printf "modified\n" > modified.whole
282 $ printf "removed\n" > removed.whole
282 $ printf "removed\n" > removed.whole
283 $ printf "deleted\n" > deleted.whole
283 $ printf "deleted\n" > deleted.whole
284 $ printf "clean\n" > clean.whole
284 $ printf "clean\n" > clean.whole
285 $ printf "ignored.whole" > .hgignore
285 $ printf "ignored.whole" > .hgignore
286 $ hg commit -Aqm "stuff"
286 $ hg commit -Aqm "stuff"
287
287
288 $ printf "modified!!!\n" > modified.whole
288 $ printf "modified!!!\n" > modified.whole
289 $ printf "unknown\n" > unknown.whole
289 $ printf "unknown\n" > unknown.whole
290 $ printf "ignored\n" > ignored.whole
290 $ printf "ignored\n" > ignored.whole
291 $ printf "added\n" > added.whole
291 $ printf "added\n" > added.whole
292 $ hg add added.whole
292 $ hg add added.whole
293 $ hg remove removed.whole
293 $ hg remove removed.whole
294 $ rm deleted.whole
294 $ rm deleted.whole
295
295
296 $ hg status --all
296 $ hg status --all
297 M modified.whole
297 M modified.whole
298 A added.whole
298 A added.whole
299 R removed.whole
299 R removed.whole
300 ! deleted.whole
300 ! deleted.whole
301 ? unknown.whole
301 ? unknown.whole
302 I ignored.whole
302 I ignored.whole
303 C .hgignore
303 C .hgignore
304 C clean.whole
304 C clean.whole
305
305
306 $ hg fix --working-dir
306 $ hg fix --working-dir
307
307
308 $ hg status --all
308 $ hg status --all
309 M modified.whole
309 M modified.whole
310 A added.whole
310 A added.whole
311 R removed.whole
311 R removed.whole
312 ! deleted.whole
312 ! deleted.whole
313 ? unknown.whole
313 ? unknown.whole
314 I ignored.whole
314 I ignored.whole
315 C .hgignore
315 C .hgignore
316 C clean.whole
316 C clean.whole
317
317
318 $ cat *.whole
318 $ cat *.whole
319 ADDED
319 ADDED
320 clean
320 clean
321 ignored
321 ignored
322 MODIFIED!!!
322 MODIFIED!!!
323 unknown
323 unknown
324
324
325 $ printf "modified!!!\n" > modified.whole
325 $ printf "modified!!!\n" > modified.whole
326 $ printf "added\n" > added.whole
326 $ printf "added\n" > added.whole
327 $ hg fix --working-dir *.whole
327 $ hg fix --working-dir *.whole
328
328
329 $ hg status --all
329 $ hg status --all
330 M clean.whole
330 M clean.whole
331 M modified.whole
331 M modified.whole
332 A added.whole
332 A added.whole
333 R removed.whole
333 R removed.whole
334 ! deleted.whole
334 ! deleted.whole
335 ? unknown.whole
335 ? unknown.whole
336 I ignored.whole
336 I ignored.whole
337 C .hgignore
337 C .hgignore
338
338
339 It would be better if this also fixed the unknown file.
339 It would be better if this also fixed the unknown file.
340 $ cat *.whole
340 $ cat *.whole
341 ADDED
341 ADDED
342 CLEAN
342 CLEAN
343 ignored
343 ignored
344 MODIFIED!!!
344 MODIFIED!!!
345 unknown
345 unknown
346
346
347 $ cd ..
347 $ cd ..
348
348
349 Test that incremental fixing works on files with additions, deletions, and
349 Test that incremental fixing works on files with additions, deletions, and
350 changes in multiple line ranges. Note that deletions do not generally cause
350 changes in multiple line ranges. Note that deletions do not generally cause
351 neighboring lines to be fixed, so we don't return a line range for purely
351 neighboring lines to be fixed, so we don't return a line range for purely
352 deleted sections. In the future we should support a :deletion config that
352 deleted sections. In the future we should support a :deletion config that
353 allows fixers to know where deletions are located.
353 allows fixers to know where deletions are located.
354
354
355 $ hg init incrementalfixedlines
355 $ hg init incrementalfixedlines
356 $ cd incrementalfixedlines
356 $ cd incrementalfixedlines
357
357
358 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.txt
358 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.txt
359 $ hg commit -Aqm "foo"
359 $ hg commit -Aqm "foo"
360 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.txt
360 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.txt
361
361
362 $ hg --config "fix.fail:command=echo" \
362 $ hg --config "fix.fail:command=echo" \
363 > --config "fix.fail:linerange={first}:{last}" \
363 > --config "fix.fail:linerange={first}:{last}" \
364 > --config "fix.fail:fileset=foo.txt" \
364 > --config "fix.fail:fileset=foo.txt" \
365 > fix --working-dir
365 > fix --working-dir
366 $ cat foo.txt
366 $ cat foo.txt
367 1:1 4:6 8:8
367 1:1 4:6 8:8
368
368
369 $ cd ..
369 $ cd ..
370
370
371 Test that --whole fixes all lines regardless of the diffs present.
371 Test that --whole fixes all lines regardless of the diffs present.
372
372
373 $ hg init wholeignoresdiffs
373 $ hg init wholeignoresdiffs
374 $ cd wholeignoresdiffs
374 $ cd wholeignoresdiffs
375
375
376 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.changed
376 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.changed
377 $ hg commit -Aqm "foo"
377 $ hg commit -Aqm "foo"
378 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.changed
378 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.changed
379 $ hg fix --working-dir --whole
379 $ hg fix --working-dir --whole
380 $ cat foo.changed
380 $ cat foo.changed
381 ZZ
381 ZZ
382 A
382 A
383 C
383 C
384 DD
384 DD
385 EE
385 EE
386 FF
386 FF
387 F
387 F
388 GG
388 GG
389
389
390 $ cd ..
390 $ cd ..
391
391
392 We should do nothing with symlinks, and their targets should be unaffected. Any
392 We should do nothing with symlinks, and their targets should be unaffected. Any
393 other behavior would be more complicated to implement and harder to document.
393 other behavior would be more complicated to implement and harder to document.
394
394
395 #if symlink
395 #if symlink
396 $ hg init dontmesswithsymlinks
396 $ hg init dontmesswithsymlinks
397 $ cd dontmesswithsymlinks
397 $ cd dontmesswithsymlinks
398
398
399 $ printf "hello\n" > hello.whole
399 $ printf "hello\n" > hello.whole
400 $ ln -s hello.whole hellolink
400 $ ln -s hello.whole hellolink
401 $ hg add
401 $ hg add
402 adding hello.whole
402 adding hello.whole
403 adding hellolink
403 adding hellolink
404 $ hg fix --working-dir hellolink
404 $ hg fix --working-dir hellolink
405 $ hg status
405 $ hg status
406 A hello.whole
406 A hello.whole
407 A hellolink
407 A hellolink
408
408
409 $ cd ..
409 $ cd ..
410 #endif
410 #endif
411
411
412 We should allow fixers to run on binary files, even though this doesn't sound
412 We should allow fixers to run on binary files, even though this doesn't sound
413 like a common use case. There's not much benefit to disallowing it, and users
413 like a common use case. There's not much benefit to disallowing it, and users
414 can add "and not binary()" to their filesets if needed. The Mercurial
414 can add "and not binary()" to their filesets if needed. The Mercurial
415 philosophy is generally to not handle binary files specially anyway.
415 philosophy is generally to not handle binary files specially anyway.
416
416
417 $ hg init cantouchbinaryfiles
417 $ hg init cantouchbinaryfiles
418 $ cd cantouchbinaryfiles
418 $ cd cantouchbinaryfiles
419
419
420 $ printf "hello\0\n" > hello.whole
420 $ printf "hello\0\n" > hello.whole
421 $ hg add
421 $ hg add
422 adding hello.whole
422 adding hello.whole
423 $ hg fix --working-dir 'set:binary()'
423 $ hg fix --working-dir 'set:binary()'
424 $ cat hello.whole
424 $ cat hello.whole
425 HELLO\x00 (esc)
425 HELLO\x00 (esc)
426
426
427 $ cd ..
427 $ cd ..
428
428
429 We have a config for the maximum size of file we will attempt to fix. This can
429 We have a config for the maximum size of file we will attempt to fix. This can
430 be helpful to avoid running unsuspecting fixer tools on huge inputs, which
430 be helpful to avoid running unsuspecting fixer tools on huge inputs, which
431 could happen by accident without a well considered configuration. A more
431 could happen by accident without a well considered configuration. A more
432 precise configuration could use the size() fileset function if one global limit
432 precise configuration could use the size() fileset function if one global limit
433 is undesired.
433 is undesired.
434
434
435 $ hg init maxfilesize
435 $ hg init maxfilesize
436 $ cd maxfilesize
436 $ cd maxfilesize
437
437
438 $ printf "this file is huge\n" > hello.whole
438 $ printf "this file is huge\n" > hello.whole
439 $ hg add
439 $ hg add
440 adding hello.whole
440 adding hello.whole
441 $ hg --config fix.maxfilesize=10 fix --working-dir
441 $ hg --config fix.maxfilesize=10 fix --working-dir
442 ignoring file larger than 10 bytes: hello.whole
442 ignoring file larger than 10 bytes: hello.whole
443 $ cat hello.whole
443 $ cat hello.whole
444 this file is huge
444 this file is huge
445
445
446 $ cd ..
446 $ cd ..
447
447
448 If we specify a file to fix, other files should be left alone, even if they
448 If we specify a file to fix, other files should be left alone, even if they
449 have changes.
449 have changes.
450
450
451 $ hg init fixonlywhatitellyouto
451 $ hg init fixonlywhatitellyouto
452 $ cd fixonlywhatitellyouto
452 $ cd fixonlywhatitellyouto
453
453
454 $ printf "fix me!\n" > fixme.whole
454 $ printf "fix me!\n" > fixme.whole
455 $ printf "not me.\n" > notme.whole
455 $ printf "not me.\n" > notme.whole
456 $ hg add
456 $ hg add
457 adding fixme.whole
457 adding fixme.whole
458 adding notme.whole
458 adding notme.whole
459 $ hg fix --working-dir fixme.whole
459 $ hg fix --working-dir fixme.whole
460 $ cat *.whole
460 $ cat *.whole
461 FIX ME!
461 FIX ME!
462 not me.
462 not me.
463
463
464 $ cd ..
464 $ cd ..
465
465
466 Specifying a directory name should fix all its files and subdirectories.
466 Specifying a directory name should fix all its files and subdirectories.
467
467
468 $ hg init fixdirectory
468 $ hg init fixdirectory
469 $ cd fixdirectory
469 $ cd fixdirectory
470
470
471 $ mkdir -p dir1/dir2
471 $ mkdir -p dir1/dir2
472 $ printf "foo\n" > foo.whole
472 $ printf "foo\n" > foo.whole
473 $ printf "bar\n" > dir1/bar.whole
473 $ printf "bar\n" > dir1/bar.whole
474 $ printf "baz\n" > dir1/dir2/baz.whole
474 $ printf "baz\n" > dir1/dir2/baz.whole
475 $ hg add
475 $ hg add
476 adding dir1/bar.whole
476 adding dir1/bar.whole
477 adding dir1/dir2/baz.whole
477 adding dir1/dir2/baz.whole
478 adding foo.whole
478 adding foo.whole
479 $ hg fix --working-dir dir1
479 $ hg fix --working-dir dir1
480 $ cat foo.whole dir1/bar.whole dir1/dir2/baz.whole
480 $ cat foo.whole dir1/bar.whole dir1/dir2/baz.whole
481 foo
481 foo
482 BAR
482 BAR
483 BAZ
483 BAZ
484
484
485 $ cd ..
485 $ cd ..
486
486
487 Fixing a file in the working directory that needs no fixes should not actually
487 Fixing a file in the working directory that needs no fixes should not actually
488 write back to the file, so for example the mtime shouldn't change.
488 write back to the file, so for example the mtime shouldn't change.
489
489
490 $ hg init donttouchunfixedfiles
490 $ hg init donttouchunfixedfiles
491 $ cd donttouchunfixedfiles
491 $ cd donttouchunfixedfiles
492
492
493 $ printf "NO FIX NEEDED\n" > foo.whole
493 $ printf "NO FIX NEEDED\n" > foo.whole
494 $ hg add
494 $ hg add
495 adding foo.whole
495 adding foo.whole
496 $ cp -p foo.whole foo.whole.orig
496 $ cp -p foo.whole foo.whole.orig
497 $ cp -p foo.whole.orig foo.whole
497 $ sleep 2 # mtime has a resolution of one or two seconds.
498 $ sleep 2 # mtime has a resolution of one or two seconds.
498 $ hg fix --working-dir
499 $ hg fix --working-dir
499 $ f foo.whole.orig --newer foo.whole
500 $ f foo.whole.orig --newer foo.whole
500 foo.whole.orig: newer than foo.whole
501 foo.whole.orig: newer than foo.whole
501
502
502 $ cd ..
503 $ cd ..
503
504
504 When a fixer prints to stderr, we assume that it has failed. We should show the
505 When a fixer prints to stderr, we assume that it has failed. We should show the
505 error messages to the user, and we should not let the failing fixer affect the
506 error messages to the user, and we should not let the failing fixer affect the
506 file it was fixing (many code formatters might emit error messages on stderr
507 file it was fixing (many code formatters might emit error messages on stderr
507 and nothing on stdout, which would cause us the clear the file). We show the
508 and nothing on stdout, which would cause us the clear the file). We show the
508 user which fixer failed and which revision, but we assume that the fixer will
509 user which fixer failed and which revision, but we assume that the fixer will
509 print the filename if it is relevant.
510 print the filename if it is relevant.
510
511
511 $ hg init showstderr
512 $ hg init showstderr
512 $ cd showstderr
513 $ cd showstderr
513
514
514 $ printf "hello\n" > hello.txt
515 $ printf "hello\n" > hello.txt
515 $ hg add
516 $ hg add
516 adding hello.txt
517 adding hello.txt
517 $ cat >> $TESTTMP/cmd.sh <<'EOF'
518 $ cat >> $TESTTMP/cmd.sh <<'EOF'
518 > printf 'HELLO\n'
519 > printf 'HELLO\n'
519 > printf "$@: some\nerror" >&2
520 > printf "$@: some\nerror" >&2
520 > EOF
521 > EOF
521 $ hg --config "fix.fail:command=sh $TESTTMP/cmd.sh {rootpath}" \
522 $ hg --config "fix.fail:command=sh $TESTTMP/cmd.sh {rootpath}" \
522 > --config "fix.fail:fileset=hello.txt" \
523 > --config "fix.fail:fileset=hello.txt" \
523 > fix --working-dir
524 > fix --working-dir
524 [wdir] fail: hello.txt: some
525 [wdir] fail: hello.txt: some
525 [wdir] fail: error
526 [wdir] fail: error
526 $ cat hello.txt
527 $ cat hello.txt
527 hello
528 hello
528
529
529 $ cd ..
530 $ cd ..
530
531
531 Fixing the working directory and its parent revision at the same time should
532 Fixing the working directory and its parent revision at the same time should
532 check out the replacement revision for the parent. This prevents any new
533 check out the replacement revision for the parent. This prevents any new
533 uncommitted changes from appearing. We test this for a clean working directory
534 uncommitted changes from appearing. We test this for a clean working directory
534 and a dirty one. In both cases, all lines/files changed since the grandparent
535 and a dirty one. In both cases, all lines/files changed since the grandparent
535 will be fixed. The grandparent is the "baserev" for both the parent and the
536 will be fixed. The grandparent is the "baserev" for both the parent and the
536 working copy.
537 working copy.
537
538
538 $ hg init fixdotandcleanwdir
539 $ hg init fixdotandcleanwdir
539 $ cd fixdotandcleanwdir
540 $ cd fixdotandcleanwdir
540
541
541 $ printf "hello\n" > hello.whole
542 $ printf "hello\n" > hello.whole
542 $ printf "world\n" > world.whole
543 $ printf "world\n" > world.whole
543 $ hg commit -Aqm "the parent commit"
544 $ hg commit -Aqm "the parent commit"
544
545
545 $ hg parents --template '{rev} {desc}\n'
546 $ hg parents --template '{rev} {desc}\n'
546 0 the parent commit
547 0 the parent commit
547 $ hg fix --working-dir -r .
548 $ hg fix --working-dir -r .
548 $ hg parents --template '{rev} {desc}\n'
549 $ hg parents --template '{rev} {desc}\n'
549 1 the parent commit
550 1 the parent commit
550 $ hg cat -r . *.whole
551 $ hg cat -r . *.whole
551 HELLO
552 HELLO
552 WORLD
553 WORLD
553 $ cat *.whole
554 $ cat *.whole
554 HELLO
555 HELLO
555 WORLD
556 WORLD
556 $ hg status
557 $ hg status
557
558
558 $ cd ..
559 $ cd ..
559
560
560 Same test with a dirty working copy.
561 Same test with a dirty working copy.
561
562
562 $ hg init fixdotanddirtywdir
563 $ hg init fixdotanddirtywdir
563 $ cd fixdotanddirtywdir
564 $ cd fixdotanddirtywdir
564
565
565 $ printf "hello\n" > hello.whole
566 $ printf "hello\n" > hello.whole
566 $ printf "world\n" > world.whole
567 $ printf "world\n" > world.whole
567 $ hg commit -Aqm "the parent commit"
568 $ hg commit -Aqm "the parent commit"
568
569
569 $ printf "hello,\n" > hello.whole
570 $ printf "hello,\n" > hello.whole
570 $ printf "world!\n" > world.whole
571 $ printf "world!\n" > world.whole
571
572
572 $ hg parents --template '{rev} {desc}\n'
573 $ hg parents --template '{rev} {desc}\n'
573 0 the parent commit
574 0 the parent commit
574 $ hg fix --working-dir -r .
575 $ hg fix --working-dir -r .
575 $ hg parents --template '{rev} {desc}\n'
576 $ hg parents --template '{rev} {desc}\n'
576 1 the parent commit
577 1 the parent commit
577 $ hg cat -r . *.whole
578 $ hg cat -r . *.whole
578 HELLO
579 HELLO
579 WORLD
580 WORLD
580 $ cat *.whole
581 $ cat *.whole
581 HELLO,
582 HELLO,
582 WORLD!
583 WORLD!
583 $ hg status
584 $ hg status
584 M hello.whole
585 M hello.whole
585 M world.whole
586 M world.whole
586
587
587 $ cd ..
588 $ cd ..
588
589
589 When we have a chain of commits that change mutually exclusive lines of code,
590 When we have a chain of commits that change mutually exclusive lines of code,
590 we should be able to do incremental fixing that causes each commit in the chain
591 we should be able to do incremental fixing that causes each commit in the chain
591 to include fixes made to the previous commits. This prevents children from
592 to include fixes made to the previous commits. This prevents children from
592 backing out the fixes made in their parents. A dirty working directory is
593 backing out the fixes made in their parents. A dirty working directory is
593 conceptually similar to another commit in the chain.
594 conceptually similar to another commit in the chain.
594
595
595 $ hg init incrementallyfixchain
596 $ hg init incrementallyfixchain
596 $ cd incrementallyfixchain
597 $ cd incrementallyfixchain
597
598
598 $ cat > file.changed <<EOF
599 $ cat > file.changed <<EOF
599 > first
600 > first
600 > second
601 > second
601 > third
602 > third
602 > fourth
603 > fourth
603 > fifth
604 > fifth
604 > EOF
605 > EOF
605 $ hg commit -Aqm "the common ancestor (the baserev)"
606 $ hg commit -Aqm "the common ancestor (the baserev)"
606 $ cat > file.changed <<EOF
607 $ cat > file.changed <<EOF
607 > first (changed)
608 > first (changed)
608 > second
609 > second
609 > third
610 > third
610 > fourth
611 > fourth
611 > fifth
612 > fifth
612 > EOF
613 > EOF
613 $ hg commit -Aqm "the first commit to fix"
614 $ hg commit -Aqm "the first commit to fix"
614 $ cat > file.changed <<EOF
615 $ cat > file.changed <<EOF
615 > first (changed)
616 > first (changed)
616 > second
617 > second
617 > third (changed)
618 > third (changed)
618 > fourth
619 > fourth
619 > fifth
620 > fifth
620 > EOF
621 > EOF
621 $ hg commit -Aqm "the second commit to fix"
622 $ hg commit -Aqm "the second commit to fix"
622 $ cat > file.changed <<EOF
623 $ cat > file.changed <<EOF
623 > first (changed)
624 > first (changed)
624 > second
625 > second
625 > third (changed)
626 > third (changed)
626 > fourth
627 > fourth
627 > fifth (changed)
628 > fifth (changed)
628 > EOF
629 > EOF
629
630
630 $ hg fix -r . -r '.^' --working-dir
631 $ hg fix -r . -r '.^' --working-dir
631
632
632 $ hg parents --template '{rev}\n'
633 $ hg parents --template '{rev}\n'
633 4
634 4
634 $ hg cat -r '.^^' file.changed
635 $ hg cat -r '.^^' file.changed
635 first
636 first
636 second
637 second
637 third
638 third
638 fourth
639 fourth
639 fifth
640 fifth
640 $ hg cat -r '.^' file.changed
641 $ hg cat -r '.^' file.changed
641 FIRST (CHANGED)
642 FIRST (CHANGED)
642 second
643 second
643 third
644 third
644 fourth
645 fourth
645 fifth
646 fifth
646 $ hg cat -r . file.changed
647 $ hg cat -r . file.changed
647 FIRST (CHANGED)
648 FIRST (CHANGED)
648 second
649 second
649 THIRD (CHANGED)
650 THIRD (CHANGED)
650 fourth
651 fourth
651 fifth
652 fifth
652 $ cat file.changed
653 $ cat file.changed
653 FIRST (CHANGED)
654 FIRST (CHANGED)
654 second
655 second
655 THIRD (CHANGED)
656 THIRD (CHANGED)
656 fourth
657 fourth
657 FIFTH (CHANGED)
658 FIFTH (CHANGED)
658
659
659 $ cd ..
660 $ cd ..
660
661
661 If we incrementally fix a merge commit, we should fix any lines that changed
662 If we incrementally fix a merge commit, we should fix any lines that changed
662 versus either parent. You could imagine only fixing the intersection or some
663 versus either parent. You could imagine only fixing the intersection or some
663 other subset, but this is necessary if either parent is being fixed. It
664 other subset, but this is necessary if either parent is being fixed. It
664 prevents us from forgetting fixes made in either parent.
665 prevents us from forgetting fixes made in either parent.
665
666
666 $ hg init incrementallyfixmergecommit
667 $ hg init incrementallyfixmergecommit
667 $ cd incrementallyfixmergecommit
668 $ cd incrementallyfixmergecommit
668
669
669 $ printf "a\nb\nc\n" > file.changed
670 $ printf "a\nb\nc\n" > file.changed
670 $ hg commit -Aqm "ancestor"
671 $ hg commit -Aqm "ancestor"
671
672
672 $ printf "aa\nb\nc\n" > file.changed
673 $ printf "aa\nb\nc\n" > file.changed
673 $ hg commit -m "change a"
674 $ hg commit -m "change a"
674
675
675 $ hg checkout '.^'
676 $ hg checkout '.^'
676 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
677 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
677 $ printf "a\nb\ncc\n" > file.changed
678 $ printf "a\nb\ncc\n" > file.changed
678 $ hg commit -m "change c"
679 $ hg commit -m "change c"
679 created new head
680 created new head
680
681
681 $ hg merge
682 $ hg merge
682 merging file.changed
683 merging file.changed
683 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
684 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
684 (branch merge, don't forget to commit)
685 (branch merge, don't forget to commit)
685 $ hg commit -m "merge"
686 $ hg commit -m "merge"
686 $ hg cat -r . file.changed
687 $ hg cat -r . file.changed
687 aa
688 aa
688 b
689 b
689 cc
690 cc
690
691
691 $ hg fix -r . --working-dir
692 $ hg fix -r . --working-dir
692 $ hg cat -r . file.changed
693 $ hg cat -r . file.changed
693 AA
694 AA
694 b
695 b
695 CC
696 CC
696
697
697 $ cd ..
698 $ cd ..
698
699
699 Abort fixing revisions if there is an unfinished operation. We don't want to
700 Abort fixing revisions if there is an unfinished operation. We don't want to
700 make things worse by editing files or stripping/obsoleting things. Also abort
701 make things worse by editing files or stripping/obsoleting things. Also abort
701 fixing the working directory if there are unresolved merge conflicts.
702 fixing the working directory if there are unresolved merge conflicts.
702
703
703 $ hg init abortunresolved
704 $ hg init abortunresolved
704 $ cd abortunresolved
705 $ cd abortunresolved
705
706
706 $ echo "foo1" > foo.whole
707 $ echo "foo1" > foo.whole
707 $ hg commit -Aqm "foo 1"
708 $ hg commit -Aqm "foo 1"
708
709
709 $ hg update null
710 $ hg update null
710 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
711 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
711 $ echo "foo2" > foo.whole
712 $ echo "foo2" > foo.whole
712 $ hg commit -Aqm "foo 2"
713 $ hg commit -Aqm "foo 2"
713
714
714 $ hg --config extensions.rebase= rebase -r 1 -d 0
715 $ hg --config extensions.rebase= rebase -r 1 -d 0
715 rebasing 1:c3b6dc0e177a "foo 2" (tip)
716 rebasing 1:c3b6dc0e177a "foo 2" (tip)
716 merging foo.whole
717 merging foo.whole
717 warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
718 warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
718 unresolved conflicts (see hg resolve, then hg rebase --continue)
719 unresolved conflicts (see hg resolve, then hg rebase --continue)
719 [1]
720 [1]
720
721
721 $ hg --config extensions.rebase= fix --working-dir
722 $ hg --config extensions.rebase= fix --working-dir
722 abort: unresolved conflicts
723 abort: unresolved conflicts
723 (use 'hg resolve')
724 (use 'hg resolve')
724 [255]
725 [255]
725
726
726 $ hg --config extensions.rebase= fix -r .
727 $ hg --config extensions.rebase= fix -r .
727 abort: rebase in progress
728 abort: rebase in progress
728 (use 'hg rebase --continue' or 'hg rebase --abort')
729 (use 'hg rebase --continue' or 'hg rebase --abort')
729 [255]
730 [255]
730
731
731 When fixing a file that was renamed, we should diff against the source of the
732 When fixing a file that was renamed, we should diff against the source of the
732 rename for incremental fixing and we should correctly reproduce the rename in
733 rename for incremental fixing and we should correctly reproduce the rename in
733 the replacement revision.
734 the replacement revision.
734
735
735 $ hg init fixrenamecommit
736 $ hg init fixrenamecommit
736 $ cd fixrenamecommit
737 $ cd fixrenamecommit
737
738
738 $ printf "a\nb\nc\n" > source.changed
739 $ printf "a\nb\nc\n" > source.changed
739 $ hg commit -Aqm "source revision"
740 $ hg commit -Aqm "source revision"
740 $ hg move source.changed dest.changed
741 $ hg move source.changed dest.changed
741 $ printf "a\nb\ncc\n" > dest.changed
742 $ printf "a\nb\ncc\n" > dest.changed
742 $ hg commit -m "dest revision"
743 $ hg commit -m "dest revision"
743
744
744 $ hg fix -r .
745 $ hg fix -r .
745 $ hg log -r tip --copies --template "{file_copies}\n"
746 $ hg log -r tip --copies --template "{file_copies}\n"
746 dest.changed (source.changed)
747 dest.changed (source.changed)
747 $ hg cat -r tip dest.changed
748 $ hg cat -r tip dest.changed
748 a
749 a
749 b
750 b
750 CC
751 CC
751
752
752 $ cd ..
753 $ cd ..
753
754
754 When fixing revisions that remove files we must ensure that the replacement
755 When fixing revisions that remove files we must ensure that the replacement
755 actually removes the file, whereas it could accidentally leave it unchanged or
756 actually removes the file, whereas it could accidentally leave it unchanged or
756 write an empty string to it.
757 write an empty string to it.
757
758
758 $ hg init fixremovedfile
759 $ hg init fixremovedfile
759 $ cd fixremovedfile
760 $ cd fixremovedfile
760
761
761 $ printf "foo\n" > foo.whole
762 $ printf "foo\n" > foo.whole
762 $ printf "bar\n" > bar.whole
763 $ printf "bar\n" > bar.whole
763 $ hg commit -Aqm "add files"
764 $ hg commit -Aqm "add files"
764 $ hg remove bar.whole
765 $ hg remove bar.whole
765 $ hg commit -m "remove file"
766 $ hg commit -m "remove file"
766 $ hg status --change .
767 $ hg status --change .
767 R bar.whole
768 R bar.whole
768 $ hg fix -r . foo.whole
769 $ hg fix -r . foo.whole
769 $ hg status --change tip
770 $ hg status --change tip
770 M foo.whole
771 M foo.whole
771 R bar.whole
772 R bar.whole
772
773
773 $ cd ..
774 $ cd ..
774
775
775 If fixing a revision finds no fixes to make, no replacement revision should be
776 If fixing a revision finds no fixes to make, no replacement revision should be
776 created.
777 created.
777
778
778 $ hg init nofixesneeded
779 $ hg init nofixesneeded
779 $ cd nofixesneeded
780 $ cd nofixesneeded
780
781
781 $ printf "FOO\n" > foo.whole
782 $ printf "FOO\n" > foo.whole
782 $ hg commit -Aqm "add file"
783 $ hg commit -Aqm "add file"
783 $ hg log --template '{rev}\n'
784 $ hg log --template '{rev}\n'
784 0
785 0
785 $ hg fix -r .
786 $ hg fix -r .
786 $ hg log --template '{rev}\n'
787 $ hg log --template '{rev}\n'
787 0
788 0
788
789
789 $ cd ..
790 $ cd ..
790
791
791 If fixing a commit reverts all the changes in the commit, we replace it with a
792 If fixing a commit reverts all the changes in the commit, we replace it with a
792 commit that changes no files.
793 commit that changes no files.
793
794
794 $ hg init nochangesleft
795 $ hg init nochangesleft
795 $ cd nochangesleft
796 $ cd nochangesleft
796
797
797 $ printf "FOO\n" > foo.whole
798 $ printf "FOO\n" > foo.whole
798 $ hg commit -Aqm "add file"
799 $ hg commit -Aqm "add file"
799 $ printf "foo\n" > foo.whole
800 $ printf "foo\n" > foo.whole
800 $ hg commit -m "edit file"
801 $ hg commit -m "edit file"
801 $ hg status --change .
802 $ hg status --change .
802 M foo.whole
803 M foo.whole
803 $ hg fix -r .
804 $ hg fix -r .
804 $ hg status --change tip
805 $ hg status --change tip
805
806
806 $ cd ..
807 $ cd ..
807
808
808 If we fix a parent and child revision together, the child revision must be
809 If we fix a parent and child revision together, the child revision must be
809 replaced if the parent is replaced, even if the diffs of the child needed no
810 replaced if the parent is replaced, even if the diffs of the child needed no
810 fixes. However, we're free to not replace revisions that need no fixes and have
811 fixes. However, we're free to not replace revisions that need no fixes and have
811 no ancestors that are replaced.
812 no ancestors that are replaced.
812
813
813 $ hg init mustreplacechild
814 $ hg init mustreplacechild
814 $ cd mustreplacechild
815 $ cd mustreplacechild
815
816
816 $ printf "FOO\n" > foo.whole
817 $ printf "FOO\n" > foo.whole
817 $ hg commit -Aqm "add foo"
818 $ hg commit -Aqm "add foo"
818 $ printf "foo\n" > foo.whole
819 $ printf "foo\n" > foo.whole
819 $ hg commit -m "edit foo"
820 $ hg commit -m "edit foo"
820 $ printf "BAR\n" > bar.whole
821 $ printf "BAR\n" > bar.whole
821 $ hg commit -Aqm "add bar"
822 $ hg commit -Aqm "add bar"
822
823
823 $ hg log --graph --template '{node|shortest} {files}'
824 $ hg log --graph --template '{node|shortest} {files}'
824 @ bc05 bar.whole
825 @ bc05 bar.whole
825 |
826 |
826 o 4fd2 foo.whole
827 o 4fd2 foo.whole
827 |
828 |
828 o f9ac foo.whole
829 o f9ac foo.whole
829
830
830 $ hg fix -r 0:2
831 $ hg fix -r 0:2
831 $ hg log --graph --template '{node|shortest} {files}'
832 $ hg log --graph --template '{node|shortest} {files}'
832 o 3801 bar.whole
833 o 3801 bar.whole
833 |
834 |
834 o 38cc
835 o 38cc
835 |
836 |
836 | @ bc05 bar.whole
837 | @ bc05 bar.whole
837 | |
838 | |
838 | x 4fd2 foo.whole
839 | x 4fd2 foo.whole
839 |/
840 |/
840 o f9ac foo.whole
841 o f9ac foo.whole
841
842
842
843
843 $ cd ..
844 $ cd ..
844
845
845 It's also possible that the child needs absolutely no changes, but we still
846 It's also possible that the child needs absolutely no changes, but we still
846 need to replace it to update its parent. If we skipped replacing the child
847 need to replace it to update its parent. If we skipped replacing the child
847 because it had no file content changes, it would become an orphan for no good
848 because it had no file content changes, it would become an orphan for no good
848 reason.
849 reason.
849
850
850 $ hg init mustreplacechildevenifnop
851 $ hg init mustreplacechildevenifnop
851 $ cd mustreplacechildevenifnop
852 $ cd mustreplacechildevenifnop
852
853
853 $ printf "Foo\n" > foo.whole
854 $ printf "Foo\n" > foo.whole
854 $ hg commit -Aqm "add a bad foo"
855 $ hg commit -Aqm "add a bad foo"
855 $ printf "FOO\n" > foo.whole
856 $ printf "FOO\n" > foo.whole
856 $ hg commit -m "add a good foo"
857 $ hg commit -m "add a good foo"
857 $ hg fix -r . -r '.^'
858 $ hg fix -r . -r '.^'
858 $ hg log --graph --template '{rev} {desc}'
859 $ hg log --graph --template '{rev} {desc}'
859 o 3 add a good foo
860 o 3 add a good foo
860 |
861 |
861 o 2 add a bad foo
862 o 2 add a bad foo
862
863
863 @ 1 add a good foo
864 @ 1 add a good foo
864 |
865 |
865 x 0 add a bad foo
866 x 0 add a bad foo
866
867
867
868
868 $ cd ..
869 $ cd ..
869
870
870 Similar to the case above, the child revision may become empty as a result of
871 Similar to the case above, the child revision may become empty as a result of
871 fixing its parent. We should still create an empty replacement child.
872 fixing its parent. We should still create an empty replacement child.
872 TODO: determine how this should interact with ui.allowemptycommit given that
873 TODO: determine how this should interact with ui.allowemptycommit given that
873 the empty replacement could have children.
874 the empty replacement could have children.
874
875
875 $ hg init mustreplacechildevenifempty
876 $ hg init mustreplacechildevenifempty
876 $ cd mustreplacechildevenifempty
877 $ cd mustreplacechildevenifempty
877
878
878 $ printf "foo\n" > foo.whole
879 $ printf "foo\n" > foo.whole
879 $ hg commit -Aqm "add foo"
880 $ hg commit -Aqm "add foo"
880 $ printf "Foo\n" > foo.whole
881 $ printf "Foo\n" > foo.whole
881 $ hg commit -m "edit foo"
882 $ hg commit -m "edit foo"
882 $ hg fix -r . -r '.^'
883 $ hg fix -r . -r '.^'
883 $ hg log --graph --template '{rev} {desc}\n' --stat
884 $ hg log --graph --template '{rev} {desc}\n' --stat
884 o 3 edit foo
885 o 3 edit foo
885 |
886 |
886 o 2 add foo
887 o 2 add foo
887 foo.whole | 1 +
888 foo.whole | 1 +
888 1 files changed, 1 insertions(+), 0 deletions(-)
889 1 files changed, 1 insertions(+), 0 deletions(-)
889
890
890 @ 1 edit foo
891 @ 1 edit foo
891 | foo.whole | 2 +-
892 | foo.whole | 2 +-
892 | 1 files changed, 1 insertions(+), 1 deletions(-)
893 | 1 files changed, 1 insertions(+), 1 deletions(-)
893 |
894 |
894 x 0 add foo
895 x 0 add foo
895 foo.whole | 1 +
896 foo.whole | 1 +
896 1 files changed, 1 insertions(+), 0 deletions(-)
897 1 files changed, 1 insertions(+), 0 deletions(-)
897
898
898
899
899 $ cd ..
900 $ cd ..
900
901
901 Fixing a secret commit should replace it with another secret commit.
902 Fixing a secret commit should replace it with another secret commit.
902
903
903 $ hg init fixsecretcommit
904 $ hg init fixsecretcommit
904 $ cd fixsecretcommit
905 $ cd fixsecretcommit
905
906
906 $ printf "foo\n" > foo.whole
907 $ printf "foo\n" > foo.whole
907 $ hg commit -Aqm "add foo" --secret
908 $ hg commit -Aqm "add foo" --secret
908 $ hg fix -r .
909 $ hg fix -r .
909 $ hg log --template '{rev} {phase}\n'
910 $ hg log --template '{rev} {phase}\n'
910 1 secret
911 1 secret
911 0 secret
912 0 secret
912
913
913 $ cd ..
914 $ cd ..
914
915
915 We should also preserve phase when fixing a draft commit while the user has
916 We should also preserve phase when fixing a draft commit while the user has
916 their default set to secret.
917 their default set to secret.
917
918
918 $ hg init respectphasesnewcommit
919 $ hg init respectphasesnewcommit
919 $ cd respectphasesnewcommit
920 $ cd respectphasesnewcommit
920
921
921 $ printf "foo\n" > foo.whole
922 $ printf "foo\n" > foo.whole
922 $ hg commit -Aqm "add foo"
923 $ hg commit -Aqm "add foo"
923 $ hg --config phases.newcommit=secret fix -r .
924 $ hg --config phases.newcommit=secret fix -r .
924 $ hg log --template '{rev} {phase}\n'
925 $ hg log --template '{rev} {phase}\n'
925 1 draft
926 1 draft
926 0 draft
927 0 draft
927
928
928 $ cd ..
929 $ cd ..
929
930
930 Debug output should show what fixer commands are being subprocessed, which is
931 Debug output should show what fixer commands are being subprocessed, which is
931 useful for anyone trying to set up a new config.
932 useful for anyone trying to set up a new config.
932
933
933 $ hg init debugoutput
934 $ hg init debugoutput
934 $ cd debugoutput
935 $ cd debugoutput
935
936
936 $ printf "foo\nbar\nbaz\n" > foo.changed
937 $ printf "foo\nbar\nbaz\n" > foo.changed
937 $ hg commit -Aqm "foo"
938 $ hg commit -Aqm "foo"
938 $ printf "Foo\nbar\nBaz\n" > foo.changed
939 $ printf "Foo\nbar\nBaz\n" > foo.changed
939 $ hg --debug fix --working-dir
940 $ hg --debug fix --working-dir
940 subprocess: * $TESTTMP/uppercase.py 1-1 3-3 (glob)
941 subprocess: * $TESTTMP/uppercase.py 1-1 3-3 (glob)
941
942
942 $ cd ..
943 $ cd ..
943
944
944 Fixing an obsolete revision can cause divergence, so we abort unless the user
945 Fixing an obsolete revision can cause divergence, so we abort unless the user
945 configures to allow it. This is not yet smart enough to know whether there is a
946 configures to allow it. This is not yet smart enough to know whether there is a
946 successor, but even then it is not likely intentional or idiomatic to fix an
947 successor, but even then it is not likely intentional or idiomatic to fix an
947 obsolete revision.
948 obsolete revision.
948
949
949 $ hg init abortobsoleterev
950 $ hg init abortobsoleterev
950 $ cd abortobsoleterev
951 $ cd abortobsoleterev
951
952
952 $ printf "foo\n" > foo.changed
953 $ printf "foo\n" > foo.changed
953 $ hg commit -Aqm "foo"
954 $ hg commit -Aqm "foo"
954 $ hg debugobsolete `hg parents --template '{node}'`
955 $ hg debugobsolete `hg parents --template '{node}'`
955 obsoleted 1 changesets
956 obsoleted 1 changesets
956 $ hg --hidden fix -r 0
957 $ hg --hidden fix -r 0
957 abort: fixing obsolete revision could cause divergence
958 abort: fixing obsolete revision could cause divergence
958 [255]
959 [255]
959
960
960 $ hg --hidden fix -r 0 --config experimental.evolution.allowdivergence=true
961 $ hg --hidden fix -r 0 --config experimental.evolution.allowdivergence=true
961 $ hg cat -r tip foo.changed
962 $ hg cat -r tip foo.changed
962 FOO
963 FOO
963
964
964 $ cd ..
965 $ cd ..
965
966
966 Test all of the available substitution values for fixer commands.
967 Test all of the available substitution values for fixer commands.
967
968
968 $ hg init substitution
969 $ hg init substitution
969 $ cd substitution
970 $ cd substitution
970
971
971 $ mkdir foo
972 $ mkdir foo
972 $ printf "hello\ngoodbye\n" > foo/bar
973 $ printf "hello\ngoodbye\n" > foo/bar
973 $ hg add
974 $ hg add
974 adding foo/bar
975 adding foo/bar
975 $ hg --config "fix.fail:command=printf '%s\n' '{rootpath}' '{basename}'" \
976 $ hg --config "fix.fail:command=printf '%s\n' '{rootpath}' '{basename}'" \
976 > --config "fix.fail:linerange='{first}' '{last}'" \
977 > --config "fix.fail:linerange='{first}' '{last}'" \
977 > --config "fix.fail:fileset=foo/bar" \
978 > --config "fix.fail:fileset=foo/bar" \
978 > fix --working-dir
979 > fix --working-dir
979 $ cat foo/bar
980 $ cat foo/bar
980 foo/bar
981 foo/bar
981 bar
982 bar
982 1
983 1
983 2
984 2
984
985
985 $ cd ..
986 $ cd ..
986
987
987 The --base flag should allow picking the revisions to diff against for changed
988 The --base flag should allow picking the revisions to diff against for changed
988 files and incremental line formatting.
989 files and incremental line formatting.
989
990
990 $ hg init baseflag
991 $ hg init baseflag
991 $ cd baseflag
992 $ cd baseflag
992
993
993 $ printf "one\ntwo\n" > foo.changed
994 $ printf "one\ntwo\n" > foo.changed
994 $ printf "bar\n" > bar.changed
995 $ printf "bar\n" > bar.changed
995 $ hg commit -Aqm "first"
996 $ hg commit -Aqm "first"
996 $ printf "one\nTwo\n" > foo.changed
997 $ printf "one\nTwo\n" > foo.changed
997 $ hg commit -m "second"
998 $ hg commit -m "second"
998 $ hg fix -w --base .
999 $ hg fix -w --base .
999 $ hg status
1000 $ hg status
1000 $ hg fix -w --base null
1001 $ hg fix -w --base null
1001 $ cat foo.changed
1002 $ cat foo.changed
1002 ONE
1003 ONE
1003 TWO
1004 TWO
1004 $ cat bar.changed
1005 $ cat bar.changed
1005 BAR
1006 BAR
1006
1007
1007 $ cd ..
1008 $ cd ..
1008
1009
1009 If the user asks to fix the parent of another commit, they are asking to create
1010 If the user asks to fix the parent of another commit, they are asking to create
1010 an orphan. We must respect experimental.evolution.allowunstable.
1011 an orphan. We must respect experimental.evolution.allowunstable.
1011
1012
1012 $ hg init allowunstable
1013 $ hg init allowunstable
1013 $ cd allowunstable
1014 $ cd allowunstable
1014
1015
1015 $ printf "one\n" > foo.whole
1016 $ printf "one\n" > foo.whole
1016 $ hg commit -Aqm "first"
1017 $ hg commit -Aqm "first"
1017 $ printf "two\n" > foo.whole
1018 $ printf "two\n" > foo.whole
1018 $ hg commit -m "second"
1019 $ hg commit -m "second"
1019 $ hg --config experimental.evolution.allowunstable=False fix -r '.^'
1020 $ hg --config experimental.evolution.allowunstable=False fix -r '.^'
1020 abort: can only fix a changeset together with all its descendants
1021 abort: can only fix a changeset together with all its descendants
1021 [255]
1022 [255]
1022 $ hg fix -r '.^'
1023 $ hg fix -r '.^'
1023 1 new orphan changesets
1024 1 new orphan changesets
1024 $ hg cat -r 2 foo.whole
1025 $ hg cat -r 2 foo.whole
1025 ONE
1026 ONE
1026
1027
1027 $ cd ..
1028 $ cd ..
1028
1029
General Comments 0
You need to be logged in to leave comments. Login now