D1143: revset: update repo.pinnedrevs with hidden commits from the tree

pulkit (Pulkit Goyal) phabricator at mercurial-scm.org
Tue Oct 17 12:19:36 UTC 2017


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

REVISION SUMMARY
  This patch adds functionality to update the pinnedrevs set with the hidden
  commits whose hashes are passed if the command allow accessing them and showing
  warning depending on repo.filtername which is set by the type of command.
  
  The logic to check whether a symbol is hash and logic related to showing
  warning to user is imported from directacess extension from fb-hgext.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/revset.py

CHANGE DETAILS

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2202,6 +2202,10 @@
     tree = revsetlang.analyze(tree)
     tree = revsetlang.optimize(tree)
     posttreebuilthook(tree, repo)
+    # add commits to pinned revs if hashes of hidden revs is passed and
+    # accessing hidden commmits is allowed
+    if repo and repo.filtername in ['visible-hidden', 'visible-warnhidden']:
+        _updatepinnedrevs(tree, repo)
     return makematcher(tree)
 
 def makematcher(tree):
@@ -2230,3 +2234,66 @@
 
 # tell hggettext to extract docstrings from these functions:
 i18nfunctions = symbols.values()
+
+hashre = util.re.compile('[0-9a-fA-F]{1,40}')
+_listtuple = ('symbol', '_list')
+
+def _ishashsymbol(symbol, maxrev):
+    """ returns true if symbol looks like a hash """
+
+    try:
+        n = int(symbol)
+        if n <= maxrev:
+            # It's a rev number
+            return False
+    except ValueError:
+        pass
+    return hashre.match(symbol)
+
+def gethashsymbols(tree, maxrev):
+    """ returns the list of symbols of the tree that look like hashes
+    for example for the revset 3::abe3ff it will return ('abe3ff') """
+
+    if not tree:
+        return []
+
+    results = []
+    if len(tree) in (2, 3) and tree[0] == "symbol":
+        results.append(tree[1])
+    elif tree[0] == "func" and tree[1] == _listtuple:
+        # the optimiser will group sequence of hash request
+        results += tree[2][1].split('\0')
+    elif len(tree) >= 2:
+        for subtree in tree[1:]:
+            results += gethashsymbols(subtree, maxrev)
+        # return directly, we don't need to filter symbols again
+        return results
+    return [s for s in results if _ishashsymbol(s, maxrev)]
+
+def _updatepinnedrevs(tree, repo):
+    """ extracts the symbols that looks like hashes and add them to
+    repo._pinnedrevs for accessing hidden hashes
+    """
+
+    hiddenset = set()
+    cl = repo.unfiltered().changelog
+    symbols = gethashsymbols(tree, len(cl))
+    for revnode in symbols:
+        try:
+            revnode = cl._partialmatch(revnode)
+        except error.LookupError:
+            revnode = None
+        if revnode is not None:
+            rev = cl.rev(revnode)
+            if rev not in repo.changelog:
+                hiddenset.add(rev)
+
+    if hiddenset:
+        if repo.filtername == 'visible-warnhidden':
+            repo.ui.warn(_("warning: accessing hidden changesets %s "
+                           "for write operation\n") %
+                         (",".join([str(repo.unfiltered()[l])
+                          for l in hiddenset])))
+
+        repo.pinnedrevs.update(hiddenset)
+        repo.invalidatevolatilesets()



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


More information about the Mercurial-devel mailing list