[PATCH 01 of 12 V2] bookmarks: add function to centralize the logic to compare bookmarks
FUJIWARA Katsunori
foozy at lares.dti.ne.jp
Sun Sep 22 09:05:27 CDT 2013
# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1379858556 -32400
# Sun Sep 22 23:02:36 2013 +0900
# Node ID 2bb09ac15facc79ae3e926317d250d4f2bf50bfc
# Parent ea35caf324bb04cbc9ab5e2328367bc50f558cfb
bookmarks: add function to centralize the logic to compare bookmarks
This patch adds "compare()" function to centralize the logic to
compare bookmarks between two repositories.
This patch also adds utility function "_execactions()" to execute
action corresponded to comparison result for each bookmarks.
diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py
--- a/mercurial/bookmarks.py
+++ b/mercurial/bookmarks.py
@@ -239,6 +239,84 @@
finally:
w.release()
+def compare(localrepo, srcmarks, dstmarks,
+ srchex=None, dsthex=None, targets=None):
+ '''Compare bookmarks between srcmarks and dstmarks, and create result list
+
+ Each elements in result list are tuple "(kind, bookmark name,
+ changeset ID on source side, changeset ID on destination
+ side)". "kind" is one of "addsrc", "adddst", "advsrc", "advdst",
+ "diverge", "differ" or "invalid". Each changeset IDs are 40
+ hexadecimal digit string or None.
+
+ Changeset IDs in result tuples may be unknown for localrepo, if
+ "kind" is one of "addsrc", "adddst", "differ" or "invalid".
+
+ This function expects that "srcmarks" and "dstmarks" return
+ changeset ID in 40 hexadecimal digit string for specified
+ bookmark. If not so (e.g. bmstore "repo._bookmarks" returning
+ binary value), "srchex" or "dsthex" should be specified to convert
+ into such form.
+
+ If "targets" is specified, only bookmarks listed in it are
+ examined.
+ '''
+ if not srchex:
+ srchex = lambda x: x
+ if not dsthex:
+ dsthex = lambda x: x
+
+ if targets:
+ bset = set(targets)
+ else:
+ srcmarkset = set(srcmarks)
+ dstmarkset = set(dstmarks)
+ bset = (srcmarkset - dstmarkset) | (dstmarkset - srcmarkset)
+ for b in srcmarkset & dstmarkset:
+ if srchex(srcmarks[b]) != dsthex(dstmarks[b]):
+ bset.add(b)
+
+ results = []
+ for b in sorted(bset):
+ if b not in srcmarks:
+ if b in dstmarks:
+ results.append(('adddst', b, None, dsthex(dstmarks[b])))
+ else:
+ results.append(('invalid', b, None, None))
+ elif b not in dstmarks:
+ results.append(('addsrc', b, srchex(srcmarks[b]), None))
+ else:
+ scid = srchex(srcmarks[b])
+ dcid = dsthex(dstmarks[b])
+ if scid in localrepo and dcid in localrepo:
+ sctx = localrepo[scid]
+ dctx = localrepo[dcid]
+ if sctx.rev() < dctx.rev():
+ if validdest(localrepo, sctx, dctx):
+ kind = 'advdst'
+ else:
+ kind = 'diverge'
+ else:
+ if validdest(localrepo, dctx, sctx):
+ kind = 'advsrc'
+ else:
+ kind = 'diverge'
+ else:
+ # it is too expensive to examine in detail, in this case
+ kind = 'differ'
+ results.append((kind, b, scid, dcid))
+ return results
+
+def _execactions(results, actionmap, ignore=None):
+ count = 0
+ for kind, b, scid, dcid in results:
+ if ignore and kind in ignore:
+ continue
+ assert kind in actionmap
+ if actionmap[kind](b, scid, dcid):
+ count += 1
+ return count
+
def updatefromremote(ui, repo, remotemarks, path):
ui.debug("checking for updated bookmarks\n")
changed = False
More information about the Mercurial-devel
mailing list