D2880: bundle: add the possibility to bundle bookmarks (issue5792)

lothiraldan (Boris Feld) phabricator at mercurial-scm.org
Fri Mar 16 13:22:35 UTC 2018


lothiraldan created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Also take the wlock when unbundling. It shouldn't have a big impact on
  performance.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2880

AFFECTED FILES
  mercurial/bundle2.py
  mercurial/commands.py
  mercurial/configitems.py
  mercurial/debugcommands.py
  tests/test-bundle-bookmarks.t

CHANGE DETAILS

diff --git a/tests/test-bundle-bookmarks.t b/tests/test-bundle-bookmarks.t
new file mode 100644
--- /dev/null
+++ b/tests/test-bundle-bookmarks.t
@@ -0,0 +1,80 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [experimental]
+  > bundle-bookmarks=yes
+  > [extensions]
+  > strip=
+  > drawdag=$TESTDIR/drawdag.py
+  > EOF
+
+Set up repo with linear history
+  $ hg init linear
+  $ cd linear
+  $ hg debugdrawdag <<'EOF'
+  > E
+  > |
+  > D
+  > |
+  > C
+  > |
+  > B
+  > |
+  > A
+  > EOF
+  $ hg bookmarks -r A "A1"
+  $ hg bookmarks -r D "D1"
+  $ hg bookmarks -r D "D2"
+  $ hg log -G -T '{desc} {bookmarks}\n'
+  o  E
+  |
+  o  D D1 D2
+  |
+  o  C
+  |
+  o  B
+  |
+  o  A A1
+  
+Bookmarks are restored when unbundling
+  $ hg bundle --all bundle
+  5 changesets found
+  $ hg debugbundle bundle
+  Stream params: {Compression: BZ}
+  changegroup -- {nbchanges: 5, version: 02}
+      426bada5c67598ca65036d57d9e4b64b0c1ce7a0
+      112478962961147124edd43549aedd1a335e44bf
+      26805aba1e600a82e93661149f2313866a221a7b
+      f585351a92f85104bff7c284233c338b10eb1df7
+      9bc730a19041f9ec7cb33c626e811aa233efb18c
+  bookmarks -- {}
+      A1: Bk\xad\xa5\xc6u\x98\xcae\x03mW\xd9\xe4\xb6K\x0c\x1c\xe7\xa0 (esc)
+      D1: \xf5\x855\x1a\x92\xf8Q\x04\xbf\xf7\xc2\x84#<3\x8b\x10\xeb\x1d\xf7 (esc)
+      D2: \xf5\x855\x1a\x92\xf8Q\x04\xbf\xf7\xc2\x84#<3\x8b\x10\xeb\x1d\xf7 (esc)
+  $ hg strip --no-backup C
+  $ hg unbundle -q bundle
+  $ hg log -G -T '{desc} {bookmarks}\n'
+  o  E
+  |
+  o  D D1 D2
+  |
+  o  C
+  |
+  o  B
+  |
+  o  A A1
+  
+Bookmarks doesn't conflict with local bookmarks
+
+  $ hg bookmarks -d A1
+  $ hg bookmarks -r A "A2"
+  $ hg unbundle -q bundle
+  $ hg log -G -T '{desc} {bookmarks}\n'
+  o  E
+  |
+  o  D D1 D2
+  |
+  o  C
+  |
+  o  B
+  |
+  o  A A1 A2
+  
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -33,6 +33,7 @@
     short,
 )
 from . import (
+    bookmarks,
     bundle2,
     changegroup,
     cmdutil,
@@ -326,6 +327,14 @@
             ui.write(indent_string)
             ui.write('%s %s\n' % (hex(head), phases.phasenames[phase]))
 
+def _debugbookmarks(ui, data, indent=0):
+    """display version and markers contained in 'data'"""
+    indent_string = ' ' * indent
+    bm = bookmarks.binarydecode(data)
+    for bookmark in sorted(bm):
+        ui.write(indent_string)
+        ui.write('%s: %s\n' % (bookmark[0], bookmark[1]))
+
 def _quasirepr(thing):
     if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
         return '{%s}' % (
@@ -353,6 +362,9 @@
         if part.type == 'phase-heads':
             if not ui.quiet:
                 _debugphaseheads(ui, part, indent=4)
+        if part.type == 'bookmarks':
+            if not ui.quiet:
+                _debugbookmarks(ui, part, indent=4)
 
 @command('debugbundle',
         [('a', 'all', None, _('show all details')),
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -419,6 +419,9 @@
 coreconfigitem('experimental', 'archivemetatemplate',
     default=dynamicdefault,
 )
+coreconfigitem('experimental', 'bundle-bookmarks',
+    default=False,
+)
 coreconfigitem('experimental', 'bundle-phases',
     default=False,
 )
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1267,6 +1267,8 @@
         contentopts['obsolescence'] = True
     if repo.ui.configbool('experimental', 'bundle-phases'):
         contentopts['phases'] = True
+    if repo.ui.configbool('experimental', 'bundle-bookmarks'):
+        contentopts['bookmarks'] = True
     bundle2.writenewbundle(ui, repo, 'bundle', fname, bversion, outgoing,
                            contentopts, compression=bcompression,
                            compopts=compopts)
@@ -5406,7 +5408,7 @@
     """
     fnames = (fname1,) + fnames
 
-    with repo.lock():
+    with repo.wlock(), repo.lock():
         for fname in fnames:
             f = hg.openpath(ui, fname)
             gen = exchange.readbundle(ui, f, fname)
diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -1599,6 +1599,14 @@
         phasedata = phases.binaryencode(headsbyphase)
         bundler.newpart('phase-heads', data=phasedata)
 
+    if opts.get('bookmarks', False):
+        # From exchange._pushb2bookmarkspart
+        data = []
+        for book, new in repo._bookmarks.items():
+            data.append((book, new))
+        checkdata = bookmarks.binaryencode(data)
+        bundler.newpart('bookmarks', data=checkdata)
+
 def addparttagsfnodescache(repo, bundler, outgoing):
     # we include the tags fnode cache for the bundle changeset
     # (as an optional parts)



To: lothiraldan, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list