Patchwork [15,of,19] snapshot: try to refine new snapshot base down the chain

mail settings
Submitter Boris Feld
Date Sept. 8, 2018, 10:57 a.m.
Message ID <45a29cbc741ec23c1c3c.1536404229@localhost.localdomain>
Download mbox | patch
Permalink /patch/34438/
State Accepted
Headers show


Boris Feld - Sept. 8, 2018, 10:57 a.m.
# HG changeset patch
# User Boris Feld <>
# Date 1536333455 14400
#      Fri Sep 07 11:17:35 2018 -0400
# Node ID 45a29cbc741ec23c1c3c98227c5ca2fcf6f0a3ff
# Parent  cc72a5b2135b94e1176eaf7a71b5b577bb7b7a33
# EXP-Topic sparse-snapshot
# Available At
#              hg pull -r 45a29cbc741e
snapshot: try to refine new snapshot base down the chain

There are cases where doing a diff against a snapshot's parent will be shorter
than against the snapshot itself. Reusing snapshot not directly related to the
revision we are trying to store increase this odd.

So once we found a possible candidate, we check the snapshots lower in the

This will involve extra processing, but this extra processing will only happen
when we are doing building a snapshot, a rare situation.


diff --git a/mercurial/revlogutils/ b/mercurial/revlogutils/
--- a/mercurial/revlogutils/
+++ b/mercurial/revlogutils/
@@ -647,6 +647,17 @@  def _refinedgroups(revlog, p1, p2, cache
         good = yield candidates
         if good is not None:
+    # if we have a refinable value, try to refine it
+    if good is not None and good not in (p1, p2) and revlog.issnapshot(good):
+        # refine snapshot down
+        previous = None
+        while previous != good:
+            previous = good
+            base = revlog.deltaparent(good)
+            if base == nullrev:
+                break
+            good = yield (base,)
     # we have found nothing
     yield None