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).
--- 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']