[PATCH 1 of 2] Add tolerant option to log command

Jason Harris jason.f.harris at gmail.com
Sat Dec 11 21:20:00 CST 2010


# HG changeset patch
# User jfh <jason at jasonfharris.com>
# Date 1292119613 -3600
# Node ID 5eec305ce06f7f096871f70aacedcd838eb802c2
# Parent  4a13ca2c21cefc6409072d9f3bd55a1e8d75b6e1
Add tolerant option to log command

Allow revision ranges outside the repository to be handled tolerantly. For
instance assume that the repository has 15 changesets and the user asks for log
--tolerant --rev "0:23" then Mercurial should interpret this request as --rev
"0:15" and not fail with an abort: unknown revision '23'! error.

This is important for GUI clients which are working in a multithreaded way when
strip or collapse or histedit operations are taking place the size of the
repository can become smaller while a status update of the size of the
repository is underway.

Conceivably this should just happen automatically for --noninteractive?

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -134,14 +134,27 @@
 
     return repo.lookup(l[0]), repo.lookup(l[-1])
 
-def revrange(repo, revs):
+def revrange(repo, revs, opts = {}):
     """Yield revision as strings from a list of revision specifications."""
 
-    def revfix(repo, val, defval):
+    def revfix(repo, val, defval, tolerant):
         if not val and val != 0 and defval is not None:
             return defval
+        if tolerant:
+            #constrain a numerical revision to be inside 0:tip
+            max = len(repo) - 1
+            try:
+                rev = int(val)
+                if str(rev) == val:
+                    if rev > max:
+                        val = str(max)
+                    elif rev < -max-1:
+                        val = str(-max-1)
+            except:
+                pass
         return repo.changelog.rev(repo.lookup(val))
 
+    tolerant = opts.get('tolerant')
     seen, l = set(), []
     for spec in revs:
         # attempt to parse old-style ranges first to deal with
@@ -154,8 +167,8 @@
 
             if revrangesep in spec:
                 start, end = spec.split(revrangesep, 1)
-                start = revfix(repo, start, 0)
-                end = revfix(repo, end, len(repo) - 1)
+                start = revfix(repo, start, 0, tolerant)
+                end = revfix(repo, end, len(repo) - 1, tolerant)
                 step = start > end and -1 or 1
                 for rev in xrange(start, end + step, step):
                     if rev in seen:
@@ -164,7 +177,7 @@
                     l.append(rev)
                 continue
             elif spec and spec in repo: # single unquoted rev
-                rev = revfix(repo, spec, None)
+                rev = revfix(repo, spec, None, tolerant)
                 if rev in seen:
                     continue
                 seen.add(rev)
@@ -1106,7 +1119,7 @@
         defrange = '%s:0' % repo['.'].rev()
     else:
         defrange = '-1:0'
-    revs = revrange(repo, opts['rev'] or [defrange])
+    revs = revrange(repo, opts['rev'] or [defrange], opts)
     if not revs:
         return []
     wanted = set()
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3974,6 +3974,8 @@
      _('limit number of changes displayed'), _('NUM')),
     ('M', 'no-merges', None, _('do not show merges')),
     ('', 'stat', None, _('output diffstat-style summary of changes')),
+    ('', 'tolerant', None,
+     _('tolerate revision ranges outside the repository')),
 ] + templateopts
 
 diffopts = [


More information about the Mercurial-devel mailing list