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).
This commit is contained in:
Sune Foldager 2010-02-07 14:29:07 +01:00
parent 91c6eab10f
commit 5020620fca
8 changed files with 147 additions and 38 deletions

View File

@ -276,12 +276,12 @@ def goutgoing(ui, repo, dest=None, **opts):
"""
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 @@ def gincoming(ui, repo, source="default", **opts):
"""
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]

View File

@ -233,7 +233,8 @@ def patchbomb(ui, repo, *revs, **opts):
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)

View File

@ -538,9 +538,10 @@ def bundle(ui, repo, fname, dest=None, **opts):
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 @@ def clone(ui, source, dest=None, **opts):
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 @@ def identify(ui, repo, source=None,
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 @@ def incoming(ui, repo, source="default", **opts):
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 @@ def outgoing(ui, repo, dest=None, **opts):
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 @@ def pull(ui, repo, source="default", **opts):
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 @@ def push(ui, repo, dest=None, **opts):
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:

View File

@ -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 @@ def _local(path):
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 @@ def share(ui, source, dest=None, update=True):
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 @@ def clone(ui, source, dest=None, pull=False, rev=None, update=True,
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)

41
tests/test-branch-option Normal file
View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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']