Patchwork [06,of,10,V10] bundle2: add `bookmarks` part handler

login
register
mail settings
Submitter Stanislau Hlebik
Date Nov. 20, 2016, 12:13 p.m.
Message ID <866281dae2407308c19c.1479644039@dev1918.lla1.facebook.com>
Download mbox | patch
Permalink /patch/17646/
State Accepted
Headers show

Comments

Stanislau Hlebik - Nov. 20, 2016, 12:13 p.m.
# HG changeset patch
# User Stanislau Hlebik <stash@fb.com>
# Date 1479643450 28800
#      Sun Nov 20 04:04:10 2016 -0800
# Node ID 866281dae2407308c19c7c3109bb5501b940ee67
# Parent  57d7f92db34461da87850e26d831d2d235282356
bundle2: add `bookmarks` part handler

Applies bookmarks part to the local repo. `processbookmarksmode` determines
how remote bookmarks are handled. They are either ignored ('ignore' mode),
diverged ('diverge' mode) or applied ('apply' mode).
Gregory Szorc - Nov. 22, 2016, 3:22 a.m.
On Sun, Nov 20, 2016 at 4:13 AM, Stanislau Hlebik <stash@fb.com> wrote:

> # HG changeset patch
> # User Stanislau Hlebik <stash@fb.com>
> # Date 1479643450 28800
> #      Sun Nov 20 04:04:10 2016 -0800
> # Node ID 866281dae2407308c19c7c3109bb5501b940ee67
> # Parent  57d7f92db34461da87850e26d831d2d235282356
> bundle2: add `bookmarks` part handler
>
> Applies bookmarks part to the local repo. `processbookmarksmode` determines
> how remote bookmarks are handled. They are either ignored ('ignore' mode),
> diverged ('diverge' mode) or applied ('apply' mode).
>
> diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
> --- a/mercurial/bundle2.py
> +++ b/mercurial/bundle2.py
> @@ -155,6 +155,7 @@
>
>  from .i18n import _
>  from . import (
> +    bookmarks as bookmod,
>      changegroup,
>      error,
>      obsolete,
> @@ -287,13 +288,19 @@
>      * a way to construct a bundle response when applicable.
>      """
>
> -    def __init__(self, repo, transactiongetter, captureoutput=True):
> +    def __init__(self, repo, transactiongetter, captureoutput=True,
> +                 behavior=None):
> +        """
> +        `behavior` is a dictionary that is passed to part handlers to
> tweak
> +        their behaviour
> +        """
>          self.repo = repo
>          self.ui = repo.ui
>          self.records = unbundlerecords()
>          self.gettransaction = transactiongetter
>          self.reply = None
>          self.captureoutput = captureoutput
> +        self.behavior = behavior or {}
>
>  class TransactionUnavailable(RuntimeError):
>      pass
> @@ -1616,3 +1623,36 @@
>
>      cache.write()
>      op.ui.debug('applied %i hgtags fnodes cache entries\n' % count)
> +
> +@parthandler('bookmarks')
> +def handlebookmarks(op, inpart):
> +    """Processes bookmarks part.
> +
> +    `processbookmarksmode` determines how remote bookmarks are handled.
> They are
> +    either ignored ('ignore' mode), diverged ('diverge' mode) or applied
> +    ('apply' mode). 'ignore' mode is used to get bookmarks and process
> them
> +    later, 'diverge' mode is used to process bookmarks during pull,
> 'apply'
> +    mode is used during push.
> +    """
> +
> +    bookmarks = {}
> +    bookmarks = bookmod.decodebookmarks(inpart.read())
>

The empty dict assignment line can be deleted.


> +    processbookmarksmode = op.behavior.get('processbookmarksmode',
> 'ignore')
> +    if processbookmarksmode == 'apply':
> +        for bookmark, node in bookmarks.items():
> +            if node:
> +                op.repo._bookmarks[bookmark] = node
> +            else:
> +                try:
> +                    del op.repo._bookmarks[bookmark]
> +                except KeyError:
> +                    # ignore if bookmark does not exist
> +                    pass
> +        op.repo._bookmarks.recordchange(op.gettransaction())
> +    elif processbookmarksmode == 'diverge':
> +        remotepath = op.behavior.get('remotepath', '')
> +        explicitbookmarks = op.behavior.get('explicitbookmarks', ())
> +        bookmod.updatefromremote(op.ui, op.repo, bookmarks,
> +                                 remotepath, op.gettransaction,
> +                                 explicit=explicitbookmarks)
> +    op.records.add('bookmarks', bookmarks)
>

Patch

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -155,6 +155,7 @@ 
 
 from .i18n import _
 from . import (
+    bookmarks as bookmod,
     changegroup,
     error,
     obsolete,
@@ -287,13 +288,19 @@ 
     * a way to construct a bundle response when applicable.
     """
 
-    def __init__(self, repo, transactiongetter, captureoutput=True):
+    def __init__(self, repo, transactiongetter, captureoutput=True,
+                 behavior=None):
+        """
+        `behavior` is a dictionary that is passed to part handlers to tweak
+        their behaviour
+        """
         self.repo = repo
         self.ui = repo.ui
         self.records = unbundlerecords()
         self.gettransaction = transactiongetter
         self.reply = None
         self.captureoutput = captureoutput
+        self.behavior = behavior or {}
 
 class TransactionUnavailable(RuntimeError):
     pass
@@ -1616,3 +1623,36 @@ 
 
     cache.write()
     op.ui.debug('applied %i hgtags fnodes cache entries\n' % count)
+
+@parthandler('bookmarks')
+def handlebookmarks(op, inpart):
+    """Processes bookmarks part.
+
+    `processbookmarksmode` determines how remote bookmarks are handled. They are
+    either ignored ('ignore' mode), diverged ('diverge' mode) or applied
+    ('apply' mode). 'ignore' mode is used to get bookmarks and process them
+    later, 'diverge' mode is used to process bookmarks during pull, 'apply'
+    mode is used during push.
+    """
+
+    bookmarks = {}
+    bookmarks = bookmod.decodebookmarks(inpart.read())
+    processbookmarksmode = op.behavior.get('processbookmarksmode', 'ignore')
+    if processbookmarksmode == 'apply':
+        for bookmark, node in bookmarks.items():
+            if node:
+                op.repo._bookmarks[bookmark] = node
+            else:
+                try:
+                    del op.repo._bookmarks[bookmark]
+                except KeyError:
+                    # ignore if bookmark does not exist
+                    pass
+        op.repo._bookmarks.recordchange(op.gettransaction())
+    elif processbookmarksmode == 'diverge':
+        remotepath = op.behavior.get('remotepath', '')
+        explicitbookmarks = op.behavior.get('explicitbookmarks', ())
+        bookmod.updatefromremote(op.ui, op.repo, bookmarks,
+                                 remotepath, op.gettransaction,
+                                 explicit=explicitbookmarks)
+    op.records.add('bookmarks', bookmarks)