Patchwork [5,of,5] changegroup: produce correct deltas when revisions are tombstoned

login
register
mail settings
Submitter adgar@google.com
Date Nov. 6, 2014, 7:03 p.m.
Message ID <ad9f4d59dc04476bf321.1415300591@adgar.nyc.corp.google.com>
Download mbox | patch
Permalink /patch/6612/
State Changes Requested
Headers show

Comments

adgar@google.com - Nov. 6, 2014, 7:03 p.m.
# HG changeset patch
# User Mike Edgar <adgar@google.com>
# Date 1409797442 14400
#      Wed Sep 03 22:24:02 2014 -0400
# Node ID ad9f4d59dc04476bf321e421304150f79b5f07d0
# Parent  f268f988ccb395bc2b693d624d2e6a41d9998aba
changegroup: produce correct deltas when revisions are tombstoned

When creating a delta between old and new revisions of a file using
revlog.revdiff, either the old or new (or both) could be tombstoned. Since the
bundle10 format expects each changegroup to be based on the previous, we must
produce a delta between each successive revision.

Patch

diff -r f268f988ccb3 -r ad9f4d59dc04 mercurial/changegroup.py
--- a/mercurial/changegroup.py	Mon Sep 01 14:38:29 2014 +0200
+++ b/mercurial/changegroup.py	Wed Sep 03 22:24:02 2014 -0400
@@ -435,7 +435,10 @@ 
                 delta = e.metadata
             prefix = mdiff.trivialdiffheader(len(delta))
         else:
-            delta = revlog.revdiff(base, rev)
+            try:
+                delta = revlog.revdiff(base, rev)
+            except error.CensoredNodeError:
+                delta = _tombstonedelta(revlog, base, rev)
         p1n, p2n = revlog.parents(node)
         basenode = revlog.node(base)
         meta = self.builddeltaheader(node, p1n, p2n, basenode, linknode)
@@ -448,6 +451,17 @@ 
         # do nothing with basenode, it is implicitly the previous one in HG10
         return struct.pack(self.deltaheader, node, p1n, p2n, linknode)
 
+def _tombstonedelta(revlog, base, rev):
+    try:
+        basedata = revlog.revision(base)
+    except error.CensoredNodeError, e:
+        basedata = e.metadata
+    try:
+        revdata = revlog.revision(rev)
+    except error.CensoredNodeError, e:
+        revdata = e.metadata
+    return struct.pack(">lll", 0, len(basedata), len(revdata)) + revdata
+
 class cg2packer(cg1packer):
 
     deltaheader = _CHANGEGROUPV2_DELTA_HEADER