[PATCH 1 of 1] imported patch revpair-extended

yozh at mx1.ru yozh at mx1.ru
Sun Feb 15 12:43:30 CST 2009


# HG changeset patch
# User Stepan Koltsov <stepancheg at yandex-team.ru>
# Date 1234722414 -10800
# Node ID 6a4537eaebb7397e8c68ec8fca12b583cba02160
# Parent  940e4d935d3c763d0980a160e7f4cdfc07612470
imported patch revpair-extended

diff -r 940e4d935d3c -r 6a4537eaebb7 mercurial/cmdutil.py
--- a/mercurial/cmdutil.py	Sun Feb 15 21:26:53 2009 +0300
+++ b/mercurial/cmdutil.py	Sun Feb 15 21:26:54 2009 +0300
@@ -7,11 +7,12 @@
 
 from node import hex, nullid, nullrev, short
 from i18n import _
-import os, sys, bisect, stat
+import os, sys, bisect, stat, re
 import mdiff, bdiff, util, templater, templatefilters, patch, errno, error
 import match as _match
 
-revrangesep = ':'
+def split_revrange(val):
+    return re.split("(?<!:):(?!:)", val, 1)
 
 def findpossible(cmd, table, strict=False):
     """
@@ -118,14 +119,17 @@
         return repo.dirstate.parents()[0], None
     end = None
     if len(revs) == 1:
-        if revrangesep in revs[0]:
-            start, end = revs[0].split(revrangesep, 1)
+        revrangelist = split_revrange(revs[0])
+        if len(revrangelist) == 2:
+            start, end = revrangelist
             start = revfix(repo, start, 0)
             end = revfix(repo, end, len(repo) - 1)
+        elif len(revrangelist) == 1:
+            start = revfix(repo, revrangelist[0], None)
         else:
-            start = revfix(repo, revs[0], None)
+            raise util.Abort(_('internal error'))
     elif len(revs) == 2:
-        if revrangesep in revs[0] or revrangesep in revs[1]:
+        if len(split_revrange(revs[0])) > 1 or len(split_revrange(revs[1])) > 1:
             raise util.Abort(_('too many revisions specified'))
         start = revfix(repo, revs[0], None)
         end = revfix(repo, revs[1], None)
@@ -143,8 +147,9 @@
 
     seen, l = {}, []
     for spec in revs:
-        if revrangesep in spec:
-            start, end = spec.split(revrangesep, 1)
+        revrangelist = split_revrange(spec)
+        if len(revrangelist) > 1:
+            start, end = revrangelist
             start = revfix(repo, start, 0)
             end = revfix(repo, end, len(repo) - 1)
             step = start > end and -1 or 1
@@ -153,12 +158,14 @@
                     continue
                 seen[rev] = 1
                 l.append(rev)
-        else:
+        elif len(revrangelist) == 1:
             rev = revfix(repo, spec, None)
             if rev in seen:
                 continue
             seen[rev] = 1
             l.append(rev)
+        else:
+            raise util.Abort(_('internal error'))
 
     return l
 
diff -r 940e4d935d3c -r 6a4537eaebb7 mercurial/localrepo.py
--- a/mercurial/localrepo.py	Sun Feb 15 21:26:53 2009 +0300
+++ b/mercurial/localrepo.py	Sun Feb 15 21:26:54 2009 +0300
@@ -463,6 +463,42 @@
                 if pn in bheads:
                     bheads.remove(pn)
 
+    def _branchbase(self, key):
+        node = self[key]
+        if node.rev() == 0:
+            return node.node()
+        node = node.parents()[0]
+        while len(node.children()) == 1 and node.rev() != 0:
+            node = node.parents()[0]
+        return node.node()
+    
+    def _namedbranchbase(self, key):
+        node = self[key]
+        if node.rev() == 0:
+            return node.node()
+        branch = node.branch()
+        bases = {}
+        seen = {}
+        nodes = [node]
+        while len(nodes) > 0:
+            #print [n.rev() for n in nodes]
+            n = nodes.pop()
+            #print n.rev()
+            if n.rev() == 0:
+                bases[n.rev()] = n
+            else:
+                for p in n.parents():
+                    if p.rev() in seen:
+                        continue
+                    seen[p.rev()] = 1
+                    if p.branch() != branch:
+                        bases[p.rev()] = p
+                    else:
+                        nodes.append(p)
+        if len(bases) > 1:
+            raise util.Abort(_("branch %s has more then one base") % branch)
+        return bases.iteritems().next()[1].node()
+    
     def lookup(self, key):
         if isinstance(key, int):
             return self.changelog.node(key)
@@ -482,6 +518,12 @@
         n = self.changelog._partialmatch(key)
         if n:
             return n
+        
+        if key.startswith("branch-base::"):
+            return self._branchbase(key[len("branch-base::"):])
+        if key.startswith("named-branch-base::"):
+            return self._namedbranchbase(key[len("named-branch-base::"):])
+           
         try:
             if len(key) == 20:
                 key = hex(key)
diff -r 940e4d935d3c -r 6a4537eaebb7 tests/test-branchbase
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-branchbase	Sun Feb 15 21:26:54 2009 +0300
@@ -0,0 +1,42 @@
+#!/bin/sh -e
+
+ec() {
+    echo "#" "$@"
+    "$@"
+}
+
+ec hg init x
+
+ec cd x
+
+echo "some commit" > f.txt
+hg add f.txt
+hg ci -m 'some message' # 0
+
+echo "branch base" > f.txt
+hg ci -m 'branch base' # 1
+
+hg up 1
+echo 2 > f.txt
+hg ci -m '2' # 2
+
+hg up 1
+echo 3 > f.txt
+hg ci -m '3' # 3
+
+echo 4 > f.txt
+hg ci -m '4' # 4
+
+# these should produce same result
+ec hg log -r branch-base::.
+ec hg log -r branch-base::3
+
+# Branch base of root is a first changeset
+ec hg log -r branch-base::1
+ec hg log -r branch-base::0
+
+# testing diff works
+
+ec hg diff -r branch-base::3:3 # 1 to 3
+
+# vim: set ts=4 sw=4 et:
diff -r 940e4d935d3c -r 6a4537eaebb7 tests/test-branchbase.out
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-branchbase.out	Sun Feb 15 21:26:54 2009 +0300
@@ -0,0 +1,36 @@
+# hg init x
+# cd x
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+created new head
+# hg log -r branch-base::.
+changeset:   1:3a26a10b008c
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     branch base
+
+# hg log -r branch-base::3
+changeset:   1:3a26a10b008c
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     branch base
+
+# hg log -r branch-base::1
+changeset:   0:ab9c02aca3ed
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     some message
+
+# hg log -r branch-base::0
+changeset:   0:ab9c02aca3ed
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     some message
+
+# hg diff -r branch-base::3:3
+diff -r 3a26a10b008c -r 1c819642afae f.txt
+--- a/f.txt	Thu Jan 01 00:00:00 1970 +0000
++++ b/f.txt	Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +1,1 @@
+-branch base
++3
diff -r 940e4d935d3c -r 6a4537eaebb7 tests/test-namedbranchbase
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-namedbranchbase	Sun Feb 15 21:26:54 2009 +0300
@@ -0,0 +1,55 @@
+#!/bin/sh -e
+
+ec() {
+    echo "#" "$@"
+    "$@"
+}
+
+echo "### Simple case"
+echo
+
+ec hg init r
+ec cd r
+
+echo "the quick brown fox" > file.txt
+hg add file.txt
+hg commit -m "first commit" # 0
+
+echo "jumps over the lazy dog" >> file.txt
+hg commit -m "second commit" # 1
+
+hg up 0 # just before second commit
+hg branch "rabbit"
+echo "and the rabbit rabbit" >> file.txt
+hg commit -m "into the rabbit branch" # 2
+
+# must have same result
+ec hg log -r named-branch-base::rabbit
+ec hg log -r named-branch-base::2
+
+ec hg diff -r named-branch-base::rabbit:rabbit
+
+echo
+echo "### Complicating: single parent of two tails, head is merge"
+echo
+
+hg branch "complex"
+echo "to be or not to be" > shakespeare.txt
+hg add shakespeare.txt
+hg commit -m 'shakespeare' # 3
+echo "that is the question" >> shakespeare.txt
+hg commit -m 'shakespeare^2' # 4
+
+hg up 2
+hg branch --force "complex"
+echo "in god we trust" > file.txt
+hg commit -m "another head" # 5
+
+ec hg merge 4
+ec hg commit -m "merge two heads of the same branch"
+
+ec hg log -r named-branch-base::complex
+
+ec hg diff -r named-branch-base::complex:complex
+
+# vim: set ts=4 sw=4 et:
diff -r 940e4d935d3c -r 6a4537eaebb7 tests/test-namedbranchbase.out
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-namedbranchbase.out	Sun Feb 15 21:26:54 2009 +0300
@@ -0,0 +1,59 @@
+### Simple case
+
+# hg init r
+# cd r
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+marked working directory as branch rabbit
+created new head
+# hg log -r named-branch-base::rabbit
+changeset:   0:019d07f21017
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     first commit
+
+# hg log -r named-branch-base::2
+changeset:   0:019d07f21017
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     first commit
+
+# hg diff -r named-branch-base::rabbit:rabbit
+diff -r 019d07f21017 -r 4c6087bd3384 file.txt
+--- a/file.txt	Thu Jan 01 00:00:00 1970 +0000
++++ b/file.txt	Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +1,2 @@
+ the quick brown fox
++and the rabbit rabbit
+
+### Complicating: single parent of two tails, head is merge
+
+marked working directory as branch complex
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+marked working directory as branch complex
+created new head
+# hg merge 4
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+# hg commit -m merge two heads of the same branch
+# hg log -r named-branch-base::complex
+changeset:   2:4c6087bd3384
+branch:      rabbit
+parent:      0:019d07f21017
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     into the rabbit branch
+
+# hg diff -r named-branch-base::complex:complex
+diff -r 4c6087bd3384 -r 386f2ff150ae file.txt
+--- a/file.txt	Thu Jan 01 00:00:00 1970 +0000
++++ b/file.txt	Thu Jan 01 00:00:00 1970 +0000
+@@ -1,2 +1,1 @@
+-the quick brown fox
+-and the rabbit rabbit
++in god we trust
+diff -r 4c6087bd3384 -r 386f2ff150ae shakespeare.txt
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/shakespeare.txt	Thu Jan 01 00:00:00 1970 +0000
+@@ -0,0 +1,2 @@
++to be or not to be
++that is the question


More information about the Mercurial-devel mailing list