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: