##// 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 b''
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 b' 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
@@ -38,6 +39,7 b' from .pycompat import ('
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,
@@ -3402,6 +3404,143 b' def debugssl(ui, repo, source=None, **op'
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]'),
@@ -75,6 +75,7 b' Show debug commands if there are no othe'
75 $ hg debugcomplete debug
75 $ hg debugcomplete debug
76 debugancestor
76 debugancestor
77 debugapplystreamclonebundle
77 debugapplystreamclonebundle
78 debugbackupbundle
78 debugbuilddag
79 debugbuilddag
79 debugbundle
80 debugbundle
80 debugcapabilities
81 debugcapabilities
@@ -260,6 +261,7 b' Show all commands + options'
260 copy: forget, after, at-rev, force, include, exclude, dry-run
261 copy: forget, after, at-rev, force, include, exclude, dry-run
261 debugancestor:
262 debugancestor:
262 debugapplystreamclonebundle:
263 debugapplystreamclonebundle:
264 debugbackupbundle: recover, patch, git, limit, no-merges, stat, graph, style, template
263 debugbuilddag: mergeable-file, overwritten-file, new-file
265 debugbuilddag: mergeable-file, overwritten-file, new-file
264 debugbundle: all, part-type, spec
266 debugbundle: all, part-type, spec
265 debugcapabilities:
267 debugcapabilities:
@@ -973,6 +973,8 b' Test list of internal help commands'
973 find the ancestor revision of two revisions in a given index
973 find the ancestor revision of two revisions in a given index
974 debugapplystreamclonebundle
974 debugapplystreamclonebundle
975 apply a stream clone bundle file
975 apply a stream clone bundle file
976 debugbackupbundle
977 lists the changesets available in backup bundles
976 debugbuilddag
978 debugbuilddag
977 builds a repo with a given DAG from scratch in the current
979 builds a repo with a given DAG from scratch in the current
978 empty repo
980 empty repo
General Comments 0
You need to be logged in to leave comments. Login now