##// END OF EJS Templates
debugbackupbundle: introduce command to interact with strip backups...
Pulkit Goyal -
r44915:f82d2d4e default
parent child Browse files
Show More
@@ -0,0 +1,39
1 $ cat >> $HGRCPATH << EOF
2 > [extensions]
3 > strip=
4 > EOF
5
6 Setup repo
7
8 $ hg init repo
9 $ cd repo
10
11 Test backups list and recover
12
13 $ hg debugbackupbundle
14 no backup changesets found
15
16 $ mkcommit() {
17 > echo "$1" > "$1"
18 > hg add "$1"
19 > hg ci -l $1
20 > }
21 $ mkcommit a
22 $ mkcommit b
23 $ hg strip .
24 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
25 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/d2ae7f538514-2953539b-backup.hg (glob)
26 $ hg debugbackupbundle
27 Recover changesets using: hg debugbackupbundle --recover <changeset hash>
28
29 Available backup changesets:
30 * (glob)
31 d2ae7f538514 b
32
33 $ hg debugbackupbundle --recover d2ae7f538514
34 Unbundling d2ae7f538514
35 adding changesets
36 adding manifests
37 adding file changes
38 added 1 changesets with 1 changes to 1 files
39 new changesets d2ae7f538514 (1 drafts)
@@ -11,6 +11,7 import codecs
11 11 import collections
12 12 import difflib
13 13 import errno
14 import glob
14 15 import operator
15 16 import os
16 17 import platform
@@ -38,6 +39,7 from .pycompat import (
38 39 )
39 40 from . import (
40 41 bundle2,
42 bundlerepo,
41 43 changegroup,
42 44 cmdutil,
43 45 color,
@@ -3402,6 +3404,143 def debugssl(ui, repo, source=None, **op
3402 3404
3403 3405
3404 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 3544 b'debugsub',
3406 3545 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
3407 3546 _(b'[-r REV] [REV]'),
@@ -75,6 +75,7 Show debug commands if there are no othe
75 75 $ hg debugcomplete debug
76 76 debugancestor
77 77 debugapplystreamclonebundle
78 debugbackupbundle
78 79 debugbuilddag
79 80 debugbundle
80 81 debugcapabilities
@@ -260,6 +261,7 Show all commands + options
260 261 copy: forget, after, at-rev, force, include, exclude, dry-run
261 262 debugancestor:
262 263 debugapplystreamclonebundle:
264 debugbackupbundle: recover, patch, git, limit, no-merges, stat, graph, style, template
263 265 debugbuilddag: mergeable-file, overwritten-file, new-file
264 266 debugbundle: all, part-type, spec
265 267 debugcapabilities:
@@ -973,6 +973,8 Test list of internal help commands
973 973 find the ancestor revision of two revisions in a given index
974 974 debugapplystreamclonebundle
975 975 apply a stream clone bundle file
976 debugbackupbundle
977 lists the changesets available in backup bundles
976 978 debugbuilddag
977 979 builds a repo with a given DAG from scratch in the current
978 980 empty repo
General Comments 0
You need to be logged in to leave comments. Login now