##// END OF EJS Templates
debugbackupbundle: introduce command to interact with strip backups...
Pulkit Goyal -
r44898:89323f85 default draft
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,138 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 = filter(
3432 os.path.isfile, glob.glob(repo.vfs.join("strip-backup") + "/*.hg")
3433 )
3434 backups.sort(key=lambda x: os.path.getmtime(x), reverse=True)
3435
3436 opts["bundle"] = ""
3437 opts["force"] = None
3438 limit = logcmdutil.getlimit(opts)
3439
3440 def display(other, chlist, displayer):
3441 if opts.get("newest_first"):
3442 chlist.reverse()
3443 count = 0
3444 for n in chlist:
3445 if limit is not None and count >= limit:
3446 break
3447 parents = [True for p in other.changelog.parents(n) if p != nullid]
3448 if opts.get("no_merges") and len(parents) == 2:
3449 continue
3450 count += 1
3451 displayer.show(other[n])
3452
3453 recovernode = opts.get("recover")
3454 if recovernode:
3455 if scmutil.isrevsymbol(repo, recovernode):
3456 ui.warn(_("%s already exists in the repo\n") % recovernode)
3457 return
3458 elif backups:
3459 msg = _(
3460 "Recover changesets using: hg debugbackupbundle --recover "
3461 "<changeset hash>\n\nAvailable backup changesets:"
3462 )
3463 ui.status(msg, label="status.removed")
3464 else:
3465 ui.status(_("no backup changesets found\n"))
3466 return
3467
3468 for backup in backups:
3469 # Much of this is copied from the hg incoming logic
3470 source = ui.expandpath(os.path.relpath(backup, encoding.getcwd()))
3471 source, branches = hg.parseurl(source, opts.get("branch"))
3472 try:
3473 other = hg.peer(repo, opts, source)
3474 except error.LookupError as ex:
3475 msg = _("\nwarning: unable to open bundle %s") % source
3476 hint = _("\n(missing parent rev %s)\n") % short(ex.name)
3477 ui.warn(msg, hint=hint)
3478 continue
3479 revs, checkout = hg.addbranchrevs(
3480 repo, other, branches, opts.get("rev")
3481 )
3482
3483 if revs:
3484 revs = [other.lookup(rev) for rev in revs]
3485
3486 quiet = ui.quiet
3487 try:
3488 ui.quiet = True
3489 other, chlist, cleanupfn = bundlerepo.getremotechanges(
3490 ui, repo, other, revs, opts["bundle"], opts["force"]
3491 )
3492 except error.LookupError:
3493 continue
3494 finally:
3495 ui.quiet = quiet
3496
3497 try:
3498 if not chlist:
3499 continue
3500 if recovernode:
3501 with repo.lock(), repo.transaction("unbundle") as tr:
3502 if scmutil.isrevsymbol(other, recovernode):
3503 ui.status(_("Unbundling %s\n") % (recovernode))
3504 f = hg.openpath(ui, source)
3505 gen = exchange.readbundle(ui, f, source)
3506 if isinstance(gen, bundle2.unbundle20):
3507 bundle2.applybundle(
3508 repo,
3509 gen,
3510 tr,
3511 source="unbundle",
3512 url="bundle:" + source,
3513 )
3514 else:
3515 gen.apply(repo, "unbundle", "bundle:" + source)
3516 break
3517 else:
3518 backupdate = time.strftime(
3519 "%a %H:%M, %Y-%m-%d",
3520 time.localtime(os.path.getmtime(source)),
3521 )
3522 ui.status("\n%s\n" % (backupdate.ljust(50)))
3523 if ui.verbose:
3524 ui.status("%s%s\n" % ("bundle:".ljust(13), source))
3525 else:
3526 opts[
3527 "template"
3528 ] = "{label('status.modified', node|short)} {desc|firstline}\n"
3529 displayer = logcmdutil.changesetdisplayer(
3530 ui, other, opts, False
3531 )
3532 display(other, chlist, displayer)
3533 displayer.close()
3534 finally:
3535 cleanupfn()
3536
3537
3538 @command(
3405 b'debugsub',
3539 b'debugsub',
3406 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
3540 [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
3407 _(b'[-r REV] [REV]'),
3541 _(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