diff mercurial/dispatch.py @ 23871:b2d8f3685b06

dispatch: only check compatibility against major and minor versions (BC) Extensions can declare compatibility with Mercurial versions. If an error occurs, Mercurial will attempt to pin blame on an extension that isn't marked as compatible. While all bets are off when it comes to the internal API, my experience has shown that a monthly/patch release of Mercurial has never broken any of the extensions I've written. I think that expecting extensions to declare compatibility with every patch release of Mercurial is asking a bit much and adds little to no value. This patch changes the blame logic from exact version matching to only match on the major and minor Mercurial versions. This means that extensions only need to mark themselves as compatible with the major, quarterly releases and not the monthly ones in order to stay current and avoid what is almost certainly unfair blame. This will mean less work for extension authors and almost certainly fewer false positives in the blame attribution.
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 15 Jan 2015 20:36:03 -0800
parents 41c03b7592ed
children 2ee35b6ee4fb 97a548aeb749
line wrap: on
line diff
--- a/mercurial/dispatch.py	Thu Jan 15 20:03:48 2015 -0800
+++ b/mercurial/dispatch.py	Thu Jan 15 20:36:03 2015 -0800
@@ -283,12 +283,19 @@
                 # We found an untested extension. It's likely the culprit.
                 worst = name, 'unknown', report
                 break
-            if compare not in testedwith.split() and testedwith != 'internal':
-                tested = [tuplever(v) for v in testedwith.split()]
-                lower = [t for t in tested if t < ct]
-                nearest = max(lower or tested)
-                if worst[0] is None or nearest < worst[1]:
-                    worst = name, nearest, report
+
+            # Never blame on extensions bundled with Mercurial.
+            if testedwith == 'internal':
+                continue
+
+            tested = [tuplever(t) for t in testedwith.split()]
+            if ct in tested:
+                continue
+
+            lower = [t for t in tested if t < ct]
+            nearest = max(lower or tested)
+            if worst[0] is None or nearest < worst[1]:
+                worst = name, nearest, report
         if worst[0] is not None:
             name, testedwith, report = worst
             if not isinstance(testedwith, str):
@@ -315,7 +322,10 @@
 
 def tuplever(v):
     try:
-        return tuple([int(i) for i in v.split('.')])
+        # Assertion: tuplever is only used for extension compatibility
+        # checking. Otherwise, the discarding of extra version fields is
+        # incorrect.
+        return tuple([int(i) for i in v.split('.')[0:2]])
     except ValueError:
         return tuple()