Patchwork D8949: rewriteutil: also consider pending obsoletes when updating hashes in messages

login
register
mail settings
Submitter phabricator
Date Aug. 24, 2020, 11:08 p.m.
Message ID <differential-rev-PHID-DREV-efawirwwelchzh4ikngr-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47049/
State Superseded
Headers show

Comments

phabricator - Aug. 24, 2020, 11:08 p.m.
mharbison72 created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  Phabricator builds up the replacement commits and mapping in a single
  transaction, and then finalizes everything once the commits have been rewritten.
  That's too late when trying to update the messages for those commits.
  
  I'm a little concerned that this isn't a generic enough interface, since it
  doesn't mimic the list of list return of `obsutil.successorssets()`.  But this
  is the type of mapping that phabricator maintains, and I don't think the methods
  that would be interested in calling this need to worry about split and
  divergence.  We can fix that later if the need arises.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  mercurial/utils/rewriteutil.py

CHANGE DETAILS




To: mharbison72, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/mercurial/utils/rewriteutil.py b/mercurial/utils/rewriteutil.py
--- a/mercurial/utils/rewriteutil.py
+++ b/mercurial/utils/rewriteutil.py
@@ -12,20 +12,34 @@ 
 
 from ..i18n import _
 from .. import (
+    localrepo,
     node as nodemod,
     obsutil,
+    pycompat,
     scmutil,
 )
 
+if pycompat.TYPE_CHECKING:
+    from typing import (
+        Dict,
+        List,
+        Optional,
+    )
+
+    assert any((Dict, List, Optional,))
+
 sha1re = re.compile(br'\b[0-9a-f]{6,40}\b')
 
 
-def update_hash_refs(repo, commitmsg):
+def update_hash_refs(repo, commitmsg, pending=None):
+    # type: (localrepo.localrepository, bytes, Optional[Dict[bytes, List[bytes]]]) -> bytes
     """Replace all obsolete commit hashes in the message with the current hash.
 
     If the obsolete commit was split or is divergent, the hash is not replaced
     as there's no way to know which successor to choose.
     """
+    if not pending:
+        pending = {}
     cache = {}
     sha1s = re.findall(sha1re, commitmsg)
     unfi = repo.unfiltered()
@@ -35,9 +49,13 @@ 
             continue
         ctx = unfi[fullnode]
         if not ctx.obsolete():
-            continue
-
-        successors = obsutil.successorssets(repo, ctx.node(), cache=cache)
+            successors = pending.get(fullnode, None)
+            if successors is None:
+                continue
+            # obsutil.successorssets() returns a list of list of nodes
+            successors = [successors]
+        else:
+            successors = obsutil.successorssets(repo, ctx.node(), cache=cache)
 
         # We can't make any assumptions about how to update the hash if the
         # cset in question was split or diverged.