hgext/censor.py
changeset 43077 687b865b95ad
parent 43076 2372284d9457
child 43434 bec734015b70
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
    40 command = registrar.command(cmdtable)
    40 command = registrar.command(cmdtable)
    41 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
    41 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
    42 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
    42 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
    43 # be specifying the version(s) of Mercurial they are tested with, or
    43 # be specifying the version(s) of Mercurial they are tested with, or
    44 # leave the attribute unspecified.
    44 # leave the attribute unspecified.
    45 testedwith = 'ships-with-hg-core'
    45 testedwith = b'ships-with-hg-core'
    46 
    46 
    47 
    47 
    48 @command(
    48 @command(
    49     'censor',
    49     b'censor',
    50     [
    50     [
    51         ('r', 'rev', '', _('censor file from specified revision'), _('REV')),
    51         (
    52         ('t', 'tombstone', '', _('replacement tombstone data'), _('TEXT')),
    52             b'r',
       
    53             b'rev',
       
    54             b'',
       
    55             _(b'censor file from specified revision'),
       
    56             _(b'REV'),
       
    57         ),
       
    58         (b't', b'tombstone', b'', _(b'replacement tombstone data'), _(b'TEXT')),
    53     ],
    59     ],
    54     _('-r REV [-t TEXT] [FILE]'),
    60     _(b'-r REV [-t TEXT] [FILE]'),
    55     helpcategory=command.CATEGORY_MAINTENANCE,
    61     helpcategory=command.CATEGORY_MAINTENANCE,
    56 )
    62 )
    57 def censor(ui, repo, path, rev='', tombstone='', **opts):
    63 def censor(ui, repo, path, rev=b'', tombstone=b'', **opts):
    58     with repo.wlock(), repo.lock():
    64     with repo.wlock(), repo.lock():
    59         return _docensor(ui, repo, path, rev, tombstone, **opts)
    65         return _docensor(ui, repo, path, rev, tombstone, **opts)
    60 
    66 
    61 
    67 
    62 def _docensor(ui, repo, path, rev='', tombstone='', **opts):
    68 def _docensor(ui, repo, path, rev=b'', tombstone=b'', **opts):
    63     if not path:
    69     if not path:
    64         raise error.Abort(_('must specify file path to censor'))
    70         raise error.Abort(_(b'must specify file path to censor'))
    65     if not rev:
    71     if not rev:
    66         raise error.Abort(_('must specify revision to censor'))
    72         raise error.Abort(_(b'must specify revision to censor'))
    67 
    73 
    68     wctx = repo[None]
    74     wctx = repo[None]
    69 
    75 
    70     m = scmutil.match(wctx, (path,))
    76     m = scmutil.match(wctx, (path,))
    71     if m.anypats() or len(m.files()) != 1:
    77     if m.anypats() or len(m.files()) != 1:
    72         raise error.Abort(_('can only specify an explicit filename'))
    78         raise error.Abort(_(b'can only specify an explicit filename'))
    73     path = m.files()[0]
    79     path = m.files()[0]
    74     flog = repo.file(path)
    80     flog = repo.file(path)
    75     if not len(flog):
    81     if not len(flog):
    76         raise error.Abort(_('cannot censor file with no history'))
    82         raise error.Abort(_(b'cannot censor file with no history'))
    77 
    83 
    78     rev = scmutil.revsingle(repo, rev, rev).rev()
    84     rev = scmutil.revsingle(repo, rev, rev).rev()
    79     try:
    85     try:
    80         ctx = repo[rev]
    86         ctx = repo[rev]
    81     except KeyError:
    87     except KeyError:
    82         raise error.Abort(_('invalid revision identifier %s') % rev)
    88         raise error.Abort(_(b'invalid revision identifier %s') % rev)
    83 
    89 
    84     try:
    90     try:
    85         fctx = ctx.filectx(path)
    91         fctx = ctx.filectx(path)
    86     except error.LookupError:
    92     except error.LookupError:
    87         raise error.Abort(_('file does not exist at revision %s') % rev)
    93         raise error.Abort(_(b'file does not exist at revision %s') % rev)
    88 
    94 
    89     fnode = fctx.filenode()
    95     fnode = fctx.filenode()
    90     heads = []
    96     heads = []
    91     for headnode in repo.heads():
    97     for headnode in repo.heads():
    92         hc = repo[headnode]
    98         hc = repo[headnode]
    93         if path in hc and hc.filenode(path) == fnode:
    99         if path in hc and hc.filenode(path) == fnode:
    94             heads.append(hc)
   100             heads.append(hc)
    95     if heads:
   101     if heads:
    96         headlist = ', '.join([short(c.node()) for c in heads])
   102         headlist = b', '.join([short(c.node()) for c in heads])
    97         raise error.Abort(
   103         raise error.Abort(
    98             _('cannot censor file in heads (%s)') % headlist,
   104             _(b'cannot censor file in heads (%s)') % headlist,
    99             hint=_('clean/delete and commit first'),
   105             hint=_(b'clean/delete and commit first'),
   100         )
   106         )
   101 
   107 
   102     wp = wctx.parents()
   108     wp = wctx.parents()
   103     if ctx.node() in [p.node() for p in wp]:
   109     if ctx.node() in [p.node() for p in wp]:
   104         raise error.Abort(
   110         raise error.Abort(
   105             _('cannot censor working directory'),
   111             _(b'cannot censor working directory'),
   106             hint=_('clean/delete/update first'),
   112             hint=_(b'clean/delete/update first'),
   107         )
   113         )
   108 
   114 
   109     with repo.transaction(b'censor') as tr:
   115     with repo.transaction(b'censor') as tr:
   110         flog.censorrevision(tr, fnode, tombstone=tombstone)
   116         flog.censorrevision(tr, fnode, tombstone=tombstone)