Mercurial > hg
comparison hgext/fix.py @ 44574:5205b46bd887
fix: add a -s option to format a revision and its descendants
`hg fix -r abc123` will format that commit but not its
descendants. That seems expected given the option name (`-r`), but
it's very rarely what the user wants to do. The problem is that any
descendants of that commit will not be formatted, leaving them as
orphans that are hard to evolve. They are hard to evolve because the
new parent will have formatting changes that the orphan doesn't have.
I talked to Danny Hooper (who wrote most of the fix extension) about
the problem and we agreed that deprecating `-r` in favor of a new `-s`
argument (mimicing rebase's `-s`) would be a good way of reducing the
risk that users end up with these hard-to-evolve orphans. So that's
what this patch implements.
Differential Revision: https://phab.mercurial-scm.org/D8287
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Fri, 13 Mar 2020 12:16:00 -0700 |
parents | 9f5e94bbc606 |
children | a6ef1e8e2f6d |
comparison
equal
deleted
inserted
replaced
44573:9f5e94bbc606 | 44574:5205b46bd887 |
---|---|
212 b'fixed)' | 212 b'fixed)' |
213 ), | 213 ), |
214 _(b'REV'), | 214 _(b'REV'), |
215 ) | 215 ) |
216 revopt = (b'r', b'rev', [], _(b'revisions to fix'), _(b'REV')) | 216 revopt = (b'r', b'rev', [], _(b'revisions to fix'), _(b'REV')) |
217 sourceopt = ( | |
218 b's', | |
219 b'source', | |
220 [], | |
221 _(b'fix the specified revisions and their descendants'), | |
222 _(b'REV'), | |
223 ) | |
217 wdiropt = (b'w', b'working-dir', False, _(b'fix the working directory')) | 224 wdiropt = (b'w', b'working-dir', False, _(b'fix the working directory')) |
218 wholeopt = (b'', b'whole', False, _(b'always fix every line of a file')) | 225 wholeopt = (b'', b'whole', False, _(b'always fix every line of a file')) |
219 usage = _(b'[OPTION]... [FILE]...') | 226 usage = _(b'[OPTION]... [FILE]...') |
220 | 227 |
221 | 228 |
222 @command( | 229 @command( |
223 b'fix', | 230 b'fix', |
224 [allopt, baseopt, revopt, wdiropt, wholeopt], | 231 [allopt, baseopt, revopt, sourceopt, wdiropt, wholeopt], |
225 usage, | 232 usage, |
226 helpcategory=command.CATEGORY_FILE_CONTENTS, | 233 helpcategory=command.CATEGORY_FILE_CONTENTS, |
227 ) | 234 ) |
228 def fix(ui, repo, *pats, **opts): | 235 def fix(ui, repo, *pats, **opts): |
229 """rewrite file content in changesets or working directory | 236 """rewrite file content in changesets or working directory |
247 set of revisions being fixed is considered, so that fixes to earlier | 254 set of revisions being fixed is considered, so that fixes to earlier |
248 revisions are not forgotten in later ones. The --base flag can be used to | 255 revisions are not forgotten in later ones. The --base flag can be used to |
249 override this default behavior, though it is not usually desirable to do so. | 256 override this default behavior, though it is not usually desirable to do so. |
250 """ | 257 """ |
251 opts = pycompat.byteskwargs(opts) | 258 opts = pycompat.byteskwargs(opts) |
252 cmdutil.check_at_most_one_arg(opts, b'all', b'rev') | 259 cmdutil.check_at_most_one_arg(opts, b'all', b'source', b'rev') |
253 cmdutil.check_incompatible_arguments(opts, b'working_dir', [b'all']) | 260 cmdutil.check_incompatible_arguments( |
261 opts, b'working_dir', [b'all', b'source'] | |
262 ) | |
254 | 263 |
255 with repo.wlock(), repo.lock(), repo.transaction(b'fix'): | 264 with repo.wlock(), repo.lock(), repo.transaction(b'fix'): |
256 revstofix = getrevstofix(ui, repo, opts) | 265 revstofix = getrevstofix(ui, repo, opts) |
257 basectxs = getbasectxs(repo, opts, revstofix) | 266 basectxs = getbasectxs(repo, opts, revstofix) |
258 workqueue, numitems = getworkqueue( | 267 workqueue, numitems = getworkqueue( |
397 | 406 |
398 def getrevstofix(ui, repo, opts): | 407 def getrevstofix(ui, repo, opts): |
399 """Returns the set of revision numbers that should be fixed""" | 408 """Returns the set of revision numbers that should be fixed""" |
400 if opts[b'all']: | 409 if opts[b'all']: |
401 revs = repo.revs(b'(not public() and not obsolete()) or wdir()') | 410 revs = repo.revs(b'(not public() and not obsolete()) or wdir()') |
411 elif opts[b'source']: | |
412 source_revs = scmutil.revrange(repo, opts[b'source']) | |
413 revs = set(repo.revs(b'%ld::', source_revs)) | |
414 if wdirrev in source_revs: | |
415 # `wdir()::` is currently empty, so manually add wdir | |
416 revs.add(wdirrev) | |
417 if repo[b'.'].rev() in revs: | |
418 revs.add(wdirrev) | |
402 else: | 419 else: |
403 revs = set(scmutil.revrange(repo, opts[b'rev'])) | 420 revs = set(scmutil.revrange(repo, opts[b'rev'])) |
404 if opts.get(b'working_dir'): | 421 if opts.get(b'working_dir'): |
405 revs.add(wdirrev) | 422 revs.add(wdirrev) |
406 for rev in revs: | 423 for rev in revs: |