<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Nov 20, 2016 at 4:13 AM, Stanislau Hlebik <span dir="ltr"><<a href="mailto:stash@fb.com" target="_blank">stash@fb.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Stanislau Hlebik <<a href="mailto:stash@fb.com">stash@fb.com</a>><br>
# Date 1479643450 28800<br>
#      Sun Nov 20 04:04:10 2016 -0800<br>
# Node ID 866281dae2407308c19c7c3109bb55<wbr>01b940ee67<br>
# Parent  57d7f92db34461da87850e26d831d2<wbr>d235282356<br>
bundle2: add `bookmarks` part handler<br>
<br>
Applies bookmarks part to the local repo. `processbookmarksmode` determines<br>
how remote bookmarks are handled. They are either ignored ('ignore' mode),<br>
diverged ('diverge' mode) or applied ('apply' mode).<br>
<br>
diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py<br>
--- a/mercurial/bundle2.py<br>
+++ b/mercurial/bundle2.py<br>
@@ -155,6 +155,7 @@<br>
<br>
 from .i18n import _<br>
 from . import (<br>
+    bookmarks as bookmod,<br>
     changegroup,<br>
     error,<br>
     obsolete,<br>
@@ -287,13 +288,19 @@<br>
     * a way to construct a bundle response when applicable.<br>
     """<br>
<br>
-    def __init__(self, repo, transactiongetter, captureoutput=True):<br>
+    def __init__(self, repo, transactiongetter, captureoutput=True,<br>
+                 behavior=None):<br>
+        """<br>
+        `behavior` is a dictionary that is passed to part handlers to tweak<br>
+        their behaviour<br>
+        """<br>
         self.repo = repo<br>
         self.ui = repo.ui<br>
         self.records = unbundlerecords()<br>
         self.gettransaction = transactiongetter<br>
         self.reply = None<br>
         self.captureoutput = captureoutput<br>
+        self.behavior = behavior or {}<br>
<br>
 class TransactionUnavailable(<wbr>RuntimeError):<br>
     pass<br>
@@ -1616,3 +1623,36 @@<br>
<br>
     cache.write()<br>
     op.ui.debug('applied %i hgtags fnodes cache entries\n' % count)<br>
+<br>
+@parthandler('bookmarks')<br>
+def handlebookmarks(op, inpart):<br>
+    """Processes bookmarks part.<br>
+<br>
+    `processbookmarksmode` determines how remote bookmarks are handled. They are<br>
+    either ignored ('ignore' mode), diverged ('diverge' mode) or applied<br>
+    ('apply' mode). 'ignore' mode is used to get bookmarks and process them<br>
+    later, 'diverge' mode is used to process bookmarks during pull, 'apply'<br>
+    mode is used during push.<br>
+    """<br>
+<br>
+    bookmarks = {}<br>
+    bookmarks = bookmod.decodebookmarks(<wbr>inpart.read())<br></blockquote><div><br></div><div>The empty dict assignment line can be deleted.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    processbookmarksmode = op.behavior.get('<wbr>processbookmarksmode', 'ignore')<br>
+    if processbookmarksmode == 'apply':<br>
+        for bookmark, node in bookmarks.items():<br>
+            if node:<br>
+                op.repo._bookmarks[bookmark] = node<br>
+            else:<br>
+                try:<br>
+                    del op.repo._bookmarks[bookmark]<br>
+                except KeyError:<br>
+                    # ignore if bookmark does not exist<br>
+                    pass<br>
+        op.repo._bookmarks.<wbr>recordchange(op.<wbr>gettransaction())<br>
+    elif processbookmarksmode == 'diverge':<br>
+        remotepath = op.behavior.get('remotepath', '')<br>
+        explicitbookmarks = op.behavior.get('<wbr>explicitbookmarks', ())<br>
+        bookmod.updatefromremote(op.<wbr>ui, op.repo, bookmarks,<br>
+                                 remotepath, op.gettransaction,<br>
+                                 explicit=explicitbookmarks)<br>
+    op.records.add('bookmarks', bookmarks)<br>
</blockquote></div><br></div></div>