Mercurial > hg
comparison mercurial/bookmarks.py @ 35257:3340d46a5c3f
bookmark: add methods to binary encode and decode bookmark values
Coming new bundle2 parts related to bookmark will use a binary encoding. It
encodes a series of '(bookmark, node)' pairs. Bookmark name has a high enough
size limit to not be affected by issue5165. (64K length, we are well covered)
author | Boris Feld <boris.feld@octobus.net> |
---|---|
date | Sun, 15 Oct 2017 14:59:55 +0200 |
parents | ee5f0d047b41 |
children | b9a0de08110e |
comparison
equal
deleted
inserted
replaced
35256:8fbb2678d8e8 | 35257:3340d46a5c3f |
---|---|
6 # GNU General Public License version 2 or any later version. | 6 # GNU General Public License version 2 or any later version. |
7 | 7 |
8 from __future__ import absolute_import | 8 from __future__ import absolute_import |
9 | 9 |
10 import errno | 10 import errno |
11 import struct | |
11 | 12 |
12 from .i18n import _ | 13 from .i18n import _ |
13 from .node import ( | 14 from .node import ( |
14 bin, | 15 bin, |
15 hex, | 16 hex, |
16 short, | 17 short, |
18 wdirid, | |
17 ) | 19 ) |
18 from . import ( | 20 from . import ( |
19 encoding, | 21 encoding, |
20 error, | 22 error, |
21 lock as lockmod, | 23 lock as lockmod, |
548 binremotemarks = {} | 550 binremotemarks = {} |
549 for name, node in marks.items(): | 551 for name, node in marks.items(): |
550 binremotemarks[name] = bin(node) | 552 binremotemarks[name] = bin(node) |
551 return binremotemarks | 553 return binremotemarks |
552 | 554 |
555 _binaryentry = struct.Struct('>20sH') | |
556 | |
557 def binaryencode(bookmarks): | |
558 """encode a '(bookmark, node)' iterable into a binary stream | |
559 | |
560 the binary format is: | |
561 | |
562 <node><bookmark-length><bookmark-name> | |
563 | |
564 :node: is a 20 bytes binary node, | |
565 :bookmark-length: an unsigned short, | |
566 :bookmark-name: the name of the bookmark (of length <bookmark-length>) | |
567 | |
568 wdirid (all bits set) will be used as a special value for "missing" | |
569 """ | |
570 binarydata = [] | |
571 for book, node in bookmarks: | |
572 if not node: # None or '' | |
573 node = wdirid | |
574 binarydata.append(_binaryentry.pack(node, len(book))) | |
575 binarydata.append(book) | |
576 return ''.join(binarydata) | |
577 | |
578 def binarydecode(stream): | |
579 """decode a binary stream into an '(bookmark, node)' iterable | |
580 | |
581 the binary format is: | |
582 | |
583 <node><bookmark-length><bookmark-name> | |
584 | |
585 :node: is a 20 bytes binary node, | |
586 :bookmark-length: an unsigned short, | |
587 :bookmark-name: the name of the bookmark (of length <bookmark-length>)) | |
588 | |
589 wdirid (all bits set) will be used as a special value for "missing" | |
590 """ | |
591 entrysize = _binaryentry.size | |
592 books = [] | |
593 while True: | |
594 entry = stream.read(entrysize) | |
595 if len(entry) < entrysize: | |
596 if entry: | |
597 raise error.Abort(_('bad bookmark stream')) | |
598 break | |
599 node, length = _binaryentry.unpack(entry) | |
600 bookmark = stream.read(length) | |
601 if len(bookmark) < length: | |
602 if entry: | |
603 raise error.Abort(_('bad bookmark stream')) | |
604 if node == wdirid: | |
605 node = None | |
606 books.append((bookmark, node)) | |
607 return books | |
608 | |
553 def updatefromremote(ui, repo, remotemarks, path, trfunc, explicit=()): | 609 def updatefromremote(ui, repo, remotemarks, path, trfunc, explicit=()): |
554 ui.debug("checking for updated bookmarks\n") | 610 ui.debug("checking for updated bookmarks\n") |
555 localmarks = repo._bookmarks | 611 localmarks = repo._bookmarks |
556 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same | 612 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same |
557 ) = comparebookmarks(repo, remotemarks, localmarks) | 613 ) = comparebookmarks(repo, remotemarks, localmarks) |