mercurial/debugcommands.py
changeset 44433 f82d2d4e71db
parent 44396 acbfa31cfaf2
child 44452 9d2b2df2c2ba
equal deleted inserted replaced
44427:4ce2330f2d0b 44433:f82d2d4e71db
     9 
     9 
    10 import codecs
    10 import codecs
    11 import collections
    11 import collections
    12 import difflib
    12 import difflib
    13 import errno
    13 import errno
       
    14 import glob
    14 import operator
    15 import operator
    15 import os
    16 import os
    16 import platform
    17 import platform
    17 import random
    18 import random
    18 import re
    19 import re
    36     getattr,
    37     getattr,
    37     open,
    38     open,
    38 )
    39 )
    39 from . import (
    40 from . import (
    40     bundle2,
    41     bundle2,
       
    42     bundlerepo,
    41     changegroup,
    43     changegroup,
    42     cmdutil,
    44     cmdutil,
    43     color,
    45     color,
    44     context,
    46     context,
    45     copies,
    47     copies,
  3400     finally:
  3402     finally:
  3401         s.close()
  3403         s.close()
  3402 
  3404 
  3403 
  3405 
  3404 @command(
  3406 @command(
       
  3407     b"debugbackupbundle",
       
  3408     [
       
  3409         (
       
  3410             b"",
       
  3411             b"recover",
       
  3412             b"",
       
  3413             b"brings the specified changeset back into the repository",
       
  3414         )
       
  3415     ]
       
  3416     + cmdutil.logopts,
       
  3417     _(b"hg debugbackupbundle [--recover HASH]"),
       
  3418 )
       
  3419 def debugbackupbundle(ui, repo, *pats, **opts):
       
  3420     """lists the changesets available in backup bundles
       
  3421 
       
  3422     Without any arguments, this command prints a list of the changesets in each
       
  3423     backup bundle.
       
  3424 
       
  3425     --recover takes a changeset hash and unbundles the first bundle that
       
  3426     contains that hash, which puts that changeset back in your repository.
       
  3427 
       
  3428     --verbose will print the entire commit message and the bundle path for that
       
  3429     backup.
       
  3430     """
       
  3431     backups = list(
       
  3432         filter(
       
  3433             os.path.isfile, glob.glob(repo.vfs.join(b"strip-backup") + b"/*.hg")
       
  3434         )
       
  3435     )
       
  3436     backups.sort(key=lambda x: os.path.getmtime(x), reverse=True)
       
  3437 
       
  3438     opts = pycompat.byteskwargs(opts)
       
  3439     opts[b"bundle"] = b""
       
  3440     opts[b"force"] = None
       
  3441     limit = logcmdutil.getlimit(opts)
       
  3442 
       
  3443     def display(other, chlist, displayer):
       
  3444         if opts.get(b"newest_first"):
       
  3445             chlist.reverse()
       
  3446         count = 0
       
  3447         for n in chlist:
       
  3448             if limit is not None and count >= limit:
       
  3449                 break
       
  3450             parents = [True for p in other.changelog.parents(n) if p != nullid]
       
  3451             if opts.get(b"no_merges") and len(parents) == 2:
       
  3452                 continue
       
  3453             count += 1
       
  3454             displayer.show(other[n])
       
  3455 
       
  3456     recovernode = opts.get(b"recover")
       
  3457     if recovernode:
       
  3458         if scmutil.isrevsymbol(repo, recovernode):
       
  3459             ui.warn(_(b"%s already exists in the repo\n") % recovernode)
       
  3460             return
       
  3461     elif backups:
       
  3462         msg = _(
       
  3463             b"Recover changesets using: hg debugbackupbundle --recover "
       
  3464             b"<changeset hash>\n\nAvailable backup changesets:"
       
  3465         )
       
  3466         ui.status(msg, label=b"status.removed")
       
  3467     else:
       
  3468         ui.status(_(b"no backup changesets found\n"))
       
  3469         return
       
  3470 
       
  3471     for backup in backups:
       
  3472         # Much of this is copied from the hg incoming logic
       
  3473         source = ui.expandpath(os.path.relpath(backup, encoding.getcwd()))
       
  3474         source, branches = hg.parseurl(source, opts.get(b"branch"))
       
  3475         try:
       
  3476             other = hg.peer(repo, opts, source)
       
  3477         except error.LookupError as ex:
       
  3478             msg = _(b"\nwarning: unable to open bundle %s") % source
       
  3479             hint = _(b"\n(missing parent rev %s)\n") % short(ex.name)
       
  3480             ui.warn(msg, hint=hint)
       
  3481             continue
       
  3482         revs, checkout = hg.addbranchrevs(
       
  3483             repo, other, branches, opts.get(b"rev")
       
  3484         )
       
  3485 
       
  3486         if revs:
       
  3487             revs = [other.lookup(rev) for rev in revs]
       
  3488 
       
  3489         quiet = ui.quiet
       
  3490         try:
       
  3491             ui.quiet = True
       
  3492             other, chlist, cleanupfn = bundlerepo.getremotechanges(
       
  3493                 ui, repo, other, revs, opts[b"bundle"], opts[b"force"]
       
  3494             )
       
  3495         except error.LookupError:
       
  3496             continue
       
  3497         finally:
       
  3498             ui.quiet = quiet
       
  3499 
       
  3500         try:
       
  3501             if not chlist:
       
  3502                 continue
       
  3503             if recovernode:
       
  3504                 with repo.lock(), repo.transaction(b"unbundle") as tr:
       
  3505                     if scmutil.isrevsymbol(other, recovernode):
       
  3506                         ui.status(_(b"Unbundling %s\n") % (recovernode))
       
  3507                         f = hg.openpath(ui, source)
       
  3508                         gen = exchange.readbundle(ui, f, source)
       
  3509                         if isinstance(gen, bundle2.unbundle20):
       
  3510                             bundle2.applybundle(
       
  3511                                 repo,
       
  3512                                 gen,
       
  3513                                 tr,
       
  3514                                 source=b"unbundle",
       
  3515                                 url=b"bundle:" + source,
       
  3516                             )
       
  3517                         else:
       
  3518                             gen.apply(repo, b"unbundle", b"bundle:" + source)
       
  3519                         break
       
  3520             else:
       
  3521                 backupdate = encoding.strtolocal(
       
  3522                     time.strftime(
       
  3523                         "%a %H:%M, %Y-%m-%d",
       
  3524                         time.localtime(os.path.getmtime(source)),
       
  3525                     )
       
  3526                 )
       
  3527                 ui.status(b"\n%s\n" % (backupdate.ljust(50)))
       
  3528                 if ui.verbose:
       
  3529                     ui.status(b"%s%s\n" % (b"bundle:".ljust(13), source))
       
  3530                 else:
       
  3531                     opts[
       
  3532                         b"template"
       
  3533                     ] = b"{label('status.modified', node|short)} {desc|firstline}\n"
       
  3534                 displayer = logcmdutil.changesetdisplayer(
       
  3535                     ui, other, opts, False
       
  3536                 )
       
  3537                 display(other, chlist, displayer)
       
  3538                 displayer.close()
       
  3539         finally:
       
  3540             cleanupfn()
       
  3541 
       
  3542 
       
  3543 @command(
  3405     b'debugsub',
  3544     b'debugsub',
  3406     [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
  3545     [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
  3407     _(b'[-r REV] [REV]'),
  3546     _(b'[-r REV] [REV]'),
  3408 )
  3547 )
  3409 def debugsub(ui, repo, rev=None):
  3548 def debugsub(ui, repo, rev=None):