interpret repo#name url syntax as branch instead of revision
authorSune Foldager <cryo@cyanite.org>
Sun, 07 Feb 2010 14:29:07 +0100
changeset 10365 d757bc0c7865
parent 10364 de1e7099d100
child 10368 f05e0d54f424
interpret repo#name url syntax as branch instead of revision Previously, the name part of an repo#name url was interpreted as a revision, similar to using the --rev option. Now it is instead looked up as a branch first, and if that succeeds all the heads of the branch will be processed instead of just its tip-most head. If the branch lookup fails, it will be assumed to be an revision as before (e.g. for tags).
hgext/graphlog.py
hgext/patchbomb.py
mercurial/commands.py
mercurial/hg.py
tests/test-branch-option
tests/test-branch-option.out
tests/test-hg-parseurl.py
tests/test-hg-parseurl.py.out
--- a/hgext/graphlog.py	Sun Feb 07 14:01:43 2010 +0100
+++ b/hgext/graphlog.py	Sun Feb 07 14:29:07 2010 +0100
@@ -276,12 +276,12 @@
     """
 
     check_unsupported_flags(opts)
-    dest, revs, checkout = hg.parseurl(
-        ui.expandpath(dest or 'default-push', dest or 'default'),
-        opts.get('rev'))
+    dest = ui.expandpath(dest or 'default-push', dest or 'default')
+    dest, branches = hg.parseurl(dest)
+    revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
+    other = hg.repository(cmdutil.remoteui(ui, opts), dest)
     if revs:
         revs = [repo.lookup(rev) for rev in revs]
-    other = hg.repository(cmdutil.remoteui(ui, opts), dest)
     ui.status(_('comparing with %s\n') % url.hidepassword(dest))
     o = repo.findoutgoing(other, force=opts.get('force'))
     if not o:
@@ -305,8 +305,9 @@
     """
 
     check_unsupported_flags(opts)
-    source, revs, checkout = hg.parseurl(ui.expandpath(source), opts.get('rev'))
+    source, branches = hg.parseurl(ui.expandpath(source))
     other = hg.repository(cmdutil.remoteui(repo, opts), source)
+    revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
     ui.status(_('comparing with %s\n') % url.hidepassword(source))
     if revs:
         revs = [other.lookup(rev) for rev in revs]
--- a/hgext/patchbomb.py	Sun Feb 07 14:01:43 2010 +0100
+++ b/hgext/patchbomb.py	Sun Feb 07 14:29:07 2010 +0100
@@ -233,7 +233,8 @@
     def outgoing(dest, revs):
         '''Return the revisions present locally but not in dest'''
         dest = ui.expandpath(dest or 'default-push', dest or 'default')
-        dest, revs, checkout = hg.parseurl(dest, revs)
+        dest, branches = hg.parseurl(dest)
+        revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
         if revs:
             revs = [repo.lookup(rev) for rev in revs]
         other = hg.repository(cmdutil.remoteui(repo, opts), dest)
--- a/mercurial/commands.py	Sun Feb 07 14:01:43 2010 +0100
+++ b/mercurial/commands.py	Sun Feb 07 14:29:07 2010 +0100
@@ -538,9 +538,10 @@
                         seen[p] = 1
                         visit.append(p)
     else:
-        dest, revs, checkout = hg.parseurl(
-            ui.expandpath(dest or 'default-push', dest or 'default'), revs)
+        dest = ui.expandpath(dest or 'default-push', dest or 'default')
+        dest, branches = hg.parseurl(dest)
         other = hg.repository(cmdutil.remoteui(repo, opts), dest)
+        revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
         o = repo.findoutgoing(other, force=opts.get('force'))
 
     if revs:
@@ -607,7 +608,8 @@
 
     a) the changeset, tag or branch specified with -u/--updaterev
     b) the changeset, tag or branch given with the first -r/--rev
-    c) the head of the default branch
+    c) the branch given with the url#branch source syntax
+    d) the head of the default branch
 
     Use 'hg clone -u . src dst' to checkout the source repository's
     parent changeset (applicable for local source repositories only).
@@ -1727,8 +1729,9 @@
 
     revs = []
     if source:
-        source, revs, checkout = hg.parseurl(ui.expandpath(source), [])
+        source, branches = hg.parseurl(ui.expandpath(source))
         repo = hg.repository(ui, source)
+        revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
 
     if not repo.local():
         if not rev and revs:
@@ -1919,9 +1922,10 @@
     See pull for valid source format details.
     """
     limit = cmdutil.loglimit(opts)
-    source, revs, checkout = hg.parseurl(ui.expandpath(source), opts.get('rev'))
+    source, branches = hg.parseurl(ui.expandpath(source))
     other = hg.repository(cmdutil.remoteui(repo, opts), source)
     ui.status(_('comparing with %s\n') % url.hidepassword(source))
+    revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
     if revs:
         revs = [other.lookup(rev) for rev in revs]
     common, incoming, rheads = repo.findcommonincoming(other, heads=revs,
@@ -2206,9 +2210,9 @@
     See pull for valid destination format details.
     """
     limit = cmdutil.loglimit(opts)
-    dest, revs, checkout = hg.parseurl(
-        ui.expandpath(dest or 'default-push', dest or 'default'),
-        opts.get('rev'))
+    dest = ui.expandpath(dest or 'default-push', dest or 'default')
+    dest, branches = hg.parseurl(dest)
+    revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
     if revs:
         revs = [repo.lookup(rev) for rev in revs]
 
@@ -2327,9 +2331,10 @@
     If SOURCE is omitted, the 'default' path will be used.
     See 'hg help urls' for more information.
     """
-    source, revs, checkout = hg.parseurl(ui.expandpath(source), opts.get('rev'))
+    source, branches = hg.parseurl(ui.expandpath(source))
     other = hg.repository(cmdutil.remoteui(repo, opts), source)
     ui.status(_('pulling from %s\n') % url.hidepassword(source))
+    revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
     if revs:
         try:
             revs = [other.lookup(rev) for rev in revs]
@@ -2363,9 +2368,9 @@
     Please see 'hg help urls' for important details about ``ssh://``
     URLs. If DESTINATION is omitted, a default path will be used.
     """
-    dest, revs, checkout = hg.parseurl(
-        ui.expandpath(dest or 'default-push', dest or 'default'),
-        opts.get('rev'))
+    dest = ui.expandpath(dest or 'default-push', dest or 'default')
+    dest, branches = hg.parseurl(dest)
+    revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
     other = hg.repository(cmdutil.remoteui(repo, opts), dest)
     ui.status(_('pushing to %s\n') % url.hidepassword(dest))
     if revs:
--- a/mercurial/hg.py	Sun Feb 07 14:01:43 2010 +0100
+++ b/mercurial/hg.py	Sun Feb 07 14:29:07 2010 +0100
@@ -9,7 +9,7 @@
 from i18n import _
 from lock import release
 import localrepo, bundlerepo, httprepo, sshrepo, statichttprepo
-import lock, util, extensions, error, encoding
+import lock, util, extensions, error, encoding, node
 import merge as _merge
 import verify as _verify
 import errno, os, shutil
@@ -18,15 +18,31 @@
     return (os.path.isfile(util.drop_scheme('file', path)) and
             bundlerepo or localrepo)
 
-def parseurl(url, revs=[]):
-    '''parse url#branch, returning url, branch + revs'''
+def addbranchrevs(lrepo, repo, branches, revs):
+    if not branches:
+        return revs or None, revs and revs[0] or None
+    branchmap = repo.branchmap()
+    revs = revs and list(revs) or []
+    for branch in branches:
+        if branch == '.':
+            if not lrepo or not lrepo.local():
+                raise util.Abort(_("dirstate branch not accessible"))
+            revs.append(lrepo.dirstate.branch())
+        else:
+            butf8 = encoding.fromlocal(branch)
+            if butf8 in branchmap:
+                revs.extend(node.hex(r) for r in reversed(branchmap[butf8]))
+            else:
+                revs.append(branch)
+    return revs, revs[0]
+
+def parseurl(url, branches=None):
+    '''parse url#branch, returning url, branches+[branch]'''
 
     if '#' not in url:
-        return url, (revs or None), revs and revs[0] or None
-
+        return url, branches or []
     url, branch = url.split('#', 1)
-    checkout = revs and revs[0] or branch
-    return url, (revs or []) + [branch], checkout
+    return url, (branches or []) + [branch]
 
 schemes = {
     'bundle': bundlerepo,
@@ -94,8 +110,9 @@
 
     if isinstance(source, str):
         origsource = ui.expandpath(source)
-        source, rev, checkout = parseurl(origsource, '')
+        source, branches = parseurl(origsource)
         srcrepo = repository(ui, source)
+        rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
     else:
         srcrepo = source
         origsource = source = srcrepo.url()
@@ -183,12 +200,12 @@
 
     if isinstance(source, str):
         origsource = ui.expandpath(source)
-        source, rev, checkout = parseurl(origsource, rev)
+        source, branch = parseurl(origsource)
         src_repo = repository(ui, source)
     else:
         src_repo = source
         origsource = source = src_repo.url()
-        checkout = rev and rev[0] or None
+    rev, checkout = addbranchrevs(src_repo, src_repo, branch, rev)
 
     if dest is None:
         dest = defaultdest(source)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-branch-option	Sun Feb 07 14:29:07 2010 +0100
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+# test branch selection options
+hg init branch
+cd branch
+hg branch a
+echo a > foo
+hg ci -d '0 0' -Ama
+echo a2 > foo
+hg ci -d '0 0' -ma2
+hg up 0
+hg branch c
+echo c > foo
+hg ci -d '0 0' -mc
+cd ..
+hg clone -r 0 branch branch2
+cd branch2
+hg up 0
+hg branch b
+echo b > foo
+hg ci -d '0 0' -mb
+hg up 0
+hg branch -f b
+echo b2 > foo
+hg ci -d '0 0' -mb2
+
+echo in rev c branch a
+hg in -qr c ../branch#a
+echo out branch .
+hg out -q ../branch#.
+echo clone branch b
+cd ..
+hg clone branch2#b branch3
+hg -q -R branch3 heads b
+hg -q -R branch3 parents
+rm -rf branch3
+echo clone rev a branch b
+hg clone -r a branch2#b branch3
+hg -q -R branch3 heads b
+hg -q -R branch3 parents
+rm -rf branch3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-branch-option.out	Sun Feb 07 14:29:07 2010 +0100
@@ -0,0 +1,44 @@
+marked working directory as branch a
+adding foo
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+marked working directory as branch c
+created new head
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+updating to branch a
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+marked working directory as branch b
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+marked working directory as branch b
+created new head
+in rev c branch a
+1:dd6e60a716c6
+2:f25d57ab0566
+out branch .
+2:65511d0e2b55
+clone branch b
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 3 changesets with 3 changes to 1 files (+1 heads)
+updating to branch b
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+2:65511d0e2b55
+1:b84708d77ab7
+2:65511d0e2b55
+clone rev a branch b
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 3 changesets with 3 changes to 1 files (+1 heads)
+updating to branch a
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+2:65511d0e2b55
+1:b84708d77ab7
+0:5b65ba7c951d
--- a/tests/test-hg-parseurl.py	Sun Feb 07 14:01:43 2010 +0100
+++ b/tests/test-hg-parseurl.py	Sun Feb 07 14:29:07 2010 +0100
@@ -2,11 +2,11 @@
 
 from mercurial.hg import parseurl
 
-def testparse(url, rev=[]):
-    print '%s, revs: %r, checkout: %r' % parseurl(url, rev)
+def testparse(url, branch=[]):
+    print '%s, branches: %r' % parseurl(url, branch)
 
 testparse('http://example.com/no/anchor')
 testparse('http://example.com/an/anchor#foo')
-testparse('http://example.com/no/anchor/revs', rev=['foo'])
-testparse('http://example.com/an/anchor/revs#bar', rev=['foo'])
-testparse('http://example.com/an/anchor/rev-None#foo', rev=None)
+testparse('http://example.com/no/anchor/branches', branch=['foo'])
+testparse('http://example.com/an/anchor/branches#bar', branch=['foo'])
+testparse('http://example.com/an/anchor/branches-None#foo', branch=None)
--- a/tests/test-hg-parseurl.py.out	Sun Feb 07 14:01:43 2010 +0100
+++ b/tests/test-hg-parseurl.py.out	Sun Feb 07 14:29:07 2010 +0100
@@ -1,5 +1,5 @@
-http://example.com/no/anchor, revs: None, checkout: None
-http://example.com/an/anchor, revs: ['foo'], checkout: 'foo'
-http://example.com/no/anchor/revs, revs: ['foo'], checkout: 'foo'
-http://example.com/an/anchor/revs, revs: ['foo', 'bar'], checkout: 'foo'
-http://example.com/an/anchor/rev-None, revs: ['foo'], checkout: 'foo'
+http://example.com/no/anchor, branches: []
+http://example.com/an/anchor, branches: ['foo']
+http://example.com/no/anchor/branches, branches: ['foo']
+http://example.com/an/anchor/branches, branches: ['foo', 'bar']
+http://example.com/an/anchor/branches-None, branches: ['foo']