hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks

all repository classes now have url() method that returns url of repo.
This commit is contained in:
Vadim Gelfer 2006-07-25 13:50:32 -07:00
parent e8d38e08fe
commit 0778999161
21 changed files with 119 additions and 34 deletions

View File

@ -194,7 +194,8 @@ hooks::
changegroup;;
Run after a changegroup has been added via push, pull or
unbundle. ID of the first new changeset is in $HG_NODE.
unbundle. ID of the first new changeset is in $HG_NODE. URL from
which changes came is in $HG_URL.
commit;;
Run after a changeset has been created in the local repository.
ID of the newly created changeset is in $HG_NODE. Parent
@ -202,7 +203,7 @@ hooks::
incoming;;
Run after a changeset has been pulled, pushed, or unbundled into
the local repository. The ID of the newly arrived changeset is in
$HG_NODE.
$HG_NODE. URL that was source of changes came is in $HG_URL.
outgoing;;
Run after sending changes from local repository to another. ID of
first changeset sent is in $HG_NODE. Source of operation is in
@ -210,7 +211,8 @@ hooks::
prechangegroup;;
Run before a changegroup is added via push, pull or unbundle.
Exit status 0 allows the changegroup to proceed. Non-zero status
will cause the push, pull or unbundle to fail.
will cause the push, pull or unbundle to fail. URL from which
changes will come is in $HG_URL.
precommit;;
Run before starting a local commit. Exit status 0 allows the
commit to proceed. Non-zero status will cause the commit to fail.
@ -236,7 +238,8 @@ hooks::
before accepting them. Passed the ID of the first new changeset
in $HG_NODE. Exit status 0 allows the transaction to commit.
Non-zero status will cause the transaction to be rolled back and
the push, pull or unbundle will fail.
the push, pull or unbundle will fail. URL that was source of
changes is in $HG_URL.
pretxncommit;;
Run after a changeset has been created but the transaction not yet
committed. Changeset is visible to hook program. This lets you

View File

@ -159,6 +159,10 @@ class bundlefilelog(bundlerevlog, filelog.filelog):
class bundlerepository(localrepo.localrepository):
def __init__(self, ui, path, bundlename):
localrepo.localrepository.__init__(self, ui, path)
self._url = 'bundle:' + bundlename
if path: self._url += '+' + path
self.tempfile = None
self.bundlefile = open(bundlename, "rb")
header = self.bundlefile.read(6)
@ -208,6 +212,9 @@ class bundlerepository(localrepo.localrepository):
for c in changegroup.chunkiter(self.bundlefile):
pass
def url(self):
return self._url
def dev(self):
return -1

View File

@ -2763,7 +2763,8 @@ def unbundle(ui, repo, fname, **opts):
raise util.Abort(_("%s: unknown bundle compression type")
% fname)
gen = generator(util.filechunkiter(f, 4096))
modheads = repo.addchangegroup(util.chunkbuffer(gen), 'unbundle')
modheads = repo.addchangegroup(util.chunkbuffer(gen), 'unbundle',
'bundle:' + fname)
return postincoming(ui, repo, modheads, opts['update'])
def undo(ui, repo):

View File

@ -904,9 +904,13 @@ class hgweb(object):
# require ssl by default, auth info cannot be sniffed and
# replayed
ssl_req = self.repo.ui.configbool('web', 'push_ssl', True)
if ssl_req and not req.env.get('HTTPS'):
bail(_('ssl required\n'))
return
if ssl_req:
if not req.env.get('HTTPS'):
bail(_('ssl required\n'))
return
proto = 'https'
else:
proto = 'http'
# do not allow push unless explicitly allowed
if not self.check_perm(req, 'push', False):
@ -952,7 +956,9 @@ class hgweb(object):
sys.stdout = cStringIO.StringIO()
try:
ret = self.repo.addchangegroup(fp, 'serve')
url = 'remote:%s:%s' % (proto,
req.env.get('REMOTE_HOST', ''))
ret = self.repo.addchangegroup(fp, 'serve', url)
finally:
val = sys.stdout.getvalue()
sys.stdout = old_stdout

View File

@ -115,6 +115,7 @@ else:
class httprepository(remoterepository):
def __init__(self, ui, path):
self.path = path
self.caps = None
scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
if query or frag:
@ -124,8 +125,8 @@ class httprepository(remoterepository):
host, port, user, passwd = netlocsplit(netloc)
# urllib cannot handle URLs with embedded user or passwd
self.url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
urlpath, '', ''))
self._url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
urlpath, '', ''))
self.ui = ui
proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
@ -189,6 +190,9 @@ class httprepository(remoterepository):
opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
urllib2.install_opener(opener)
def url(self):
return self.path
# look up capabilities only when needed
def get_caps(self):
@ -213,7 +217,7 @@ class httprepository(remoterepository):
q = {"cmd": cmd}
q.update(args)
qs = urllib.urlencode(q)
cu = "%s?%s" % (self.url, qs)
cu = "%s?%s" % (self._url, qs)
try:
resp = urllib2.urlopen(urllib2.Request(cu, data, headers))
except urllib2.HTTPError, inst:
@ -234,13 +238,13 @@ class httprepository(remoterepository):
not proto.startswith('text/plain') and \
not proto.startswith('application/hg-changegroup'):
raise hg.RepoError(_("'%s' does not appear to be an hg repository") %
self.url)
self._url)
if proto.startswith('application/mercurial'):
version = proto[22:]
if float(version) > 0.1:
raise hg.RepoError(_("'%s' uses newer protocol %s") %
(self.url, version))
(self._url, version))
return resp

View File

@ -83,6 +83,9 @@ class localrepository(repo.repository):
self.dirstate = dirstate.dirstate(self.opener, self.ui, self.root)
def url(self):
return 'file:' + self.root
def hook(self, name, throw=False, **args):
def callhook(hname, funcname):
'''call python hook. hook is callable object, looked up as
@ -1185,7 +1188,7 @@ class localrepository(repo.repository):
cg = remote.changegroup(fetch, 'pull')
else:
cg = remote.changegroupsubset(fetch, heads, 'pull')
return self.addchangegroup(cg, 'pull')
return self.addchangegroup(cg, 'pull', remote.url())
def push(self, remote, force=False, revs=None):
# there are two ways to push to remote repo:
@ -1241,7 +1244,7 @@ class localrepository(repo.repository):
ret = self.prepush(remote, force, revs)
if ret[0] is not None:
cg, remote_heads = ret
return remote.addchangegroup(cg, 'push')
return remote.addchangegroup(cg, 'push', self.url())
return ret[1]
def push_unbundle(self, remote, force, revs):
@ -1594,7 +1597,7 @@ class localrepository(repo.repository):
return util.chunkbuffer(gengroup())
def addchangegroup(self, source, srctype):
def addchangegroup(self, source, srctype, url):
"""add changegroup to repo.
returns number of heads modified or added + 1."""
@ -1608,7 +1611,7 @@ class localrepository(repo.repository):
if not source:
return 0
self.hook('prechangegroup', throw=True, source=srctype)
self.hook('prechangegroup', throw=True, source=srctype, url=url)
changesets = files = revisions = 0
@ -1675,17 +1678,18 @@ class localrepository(repo.repository):
if changesets > 0:
self.hook('pretxnchangegroup', throw=True,
node=hex(self.changelog.node(cor+1)), source=srctype)
node=hex(self.changelog.node(cor+1)), source=srctype,
url=url)
tr.close()
if changesets > 0:
self.hook("changegroup", node=hex(self.changelog.node(cor+1)),
source=srctype)
source=srctype, url=url)
for i in range(cor + 1, cnr + 1):
self.hook("incoming", node=hex(self.changelog.node(i)),
source=srctype)
source=srctype, url=url)
return newheads - oldheads + 1

View File

@ -13,7 +13,7 @@ demandload(globals(), "hg os re stat util")
class sshrepository(remoterepository):
def __init__(self, ui, path, create=0):
self.url = path
self._url = path
self.ui = ui
m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', path)
@ -48,6 +48,9 @@ class sshrepository(remoterepository):
self.validate_repo(ui, sshcmd, args, remotecmd)
def url(self):
return self._url
def validate_repo(self, ui, sshcmd, args, remotecmd):
cmd = '%s %s "%s -R %s serve --stdio"'
cmd = cmd % (sshcmd, args, remotecmd, self.path)
@ -180,7 +183,7 @@ class sshrepository(remoterepository):
return 1
return int(r)
def addchangegroup(self, cg, source):
def addchangegroup(self, cg, source, url):
d = self.call("addchangegroup")
if d:
raise hg.RepoError(_("push refused: %s") % d)

View File

@ -117,9 +117,13 @@ class sshserver(object):
return
self.respond("")
r = self.repo.addchangegroup(self.fin, 'serve')
r = self.repo.addchangegroup(self.fin, 'serve', self.client_url())
self.respond(str(r))
def client_url(self):
client = os.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
return 'remote:ssh:' + client
def do_unbundle(self):
their_heads = self.getarg()[1].split()
@ -159,7 +163,7 @@ class sshserver(object):
# push can proceed
fp.seek(0)
r = self.repo.addchangegroup(fp, 'serve')
r = self.repo.addchangegroup(fp, 'serve', self.client_url())
self.respond(str(r))
finally:
if not was_locked:

View File

@ -30,6 +30,7 @@ def opener(base):
class statichttprepository(localrepo.localrepository):
def __init__(self, ui, path):
self._url = path
self.path = (path + "/.hg")
self.ui = ui
self.revlogversion = 0
@ -41,6 +42,9 @@ class statichttprepository(localrepo.localrepository):
self.encodepats = None
self.decodepats = None
def url(self):
return 'static-' + self._url
def dev(self):
return -1

View File

@ -38,6 +38,8 @@ rm -rf empty
hg init empty
cd empty
hg -R bundle://../full.hg log
echo '[hooks]' >> .hg/hgrc
echo 'changegroup = echo changegroup: u=$HG_URL' >> .hg/hgrc
#doesn't work (yet ?)
#hg -R bundle://../full.hg verify
hg pull bundle://../full.hg

View File

@ -81,6 +81,7 @@ user: test
date: Mon Jan 12 13:46:40 1970 +0000
summary: 0.0
changegroup: u=bundle:../full.hg
pulling from bundle://../full.hg
requesting all changes
adding changesets

View File

@ -17,9 +17,9 @@ cd ../b
# changegroup hooks can see env vars
echo '[hooks]' > .hg/hgrc
echo 'prechangegroup = echo prechangegroup hook' >> .hg/hgrc
echo 'changegroup = echo changegroup hook: n=$HG_NODE' >> .hg/hgrc
echo 'incoming = echo incoming hook: n=$HG_NODE' >> .hg/hgrc
echo 'prechangegroup = echo prechangegroup hook: u=`echo $HG_URL | sed s,file:.*,file:,`' >> .hg/hgrc
echo 'changegroup = echo changegroup hook: n=$HG_NODE u=`echo $HG_URL | sed s,file:.*,file:,`' >> .hg/hgrc
echo 'incoming = echo incoming hook: n=$HG_NODE u=`echo $HG_URL | sed s,file:.*,file:,`' >> .hg/hgrc
# pretxncommit and commit hooks can see both parents of merge
cd ../a

View File

@ -22,11 +22,11 @@ pretxncommit hook: n=4c52fb2e402287dd5dc052090682536c8406c321 p1=1324a5531bac09b
3:4c52fb2e4022
commit hook: n=4c52fb2e402287dd5dc052090682536c8406c321 p1=1324a5531bac09b329c3845d35ae6a7526874edb p2=b702efe9688826e3a91283852b328b84dbf37bc2
commit hook b
prechangegroup hook
changegroup hook: n=b702efe9688826e3a91283852b328b84dbf37bc2
incoming hook: n=b702efe9688826e3a91283852b328b84dbf37bc2
incoming hook: n=1324a5531bac09b329c3845d35ae6a7526874edb
incoming hook: n=4c52fb2e402287dd5dc052090682536c8406c321
prechangegroup hook: u=file:
changegroup hook: n=b702efe9688826e3a91283852b328b84dbf37bc2 u=file:
incoming hook: n=b702efe9688826e3a91283852b328b84dbf37bc2 u=file:
incoming hook: n=1324a5531bac09b329c3845d35ae6a7526874edb u=file:
incoming hook: n=4c52fb2e402287dd5dc052090682536c8406c321 u=file:
pulling from ../a
searching for changes
adding changesets

View File

@ -23,3 +23,13 @@ echo % clone via pull
http_proxy= hg clone http://localhost:20059/ copy-pull
cd copy-pull
hg verify
cd test
echo bar > bar
hg commit -A -d '1 0' -m 2
echo % pull
cd ../copy-pull
echo '[hooks]' >> .hg/hgrc
echo 'changegroup = echo changegroup: u=$HG_URL' >> .hg/hgrc
hg pull

View File

@ -28,3 +28,9 @@ checking manifests
crosschecking files in changesets and manifests
checking files
1 files, 1 changesets, 1 total revisions
/home/bos/hg/hg/hg-url/tests/test-http: line 27: cd: test: No such file or directory
adding bar
% pull
pulling from http://localhost:20059/
searching for changes
no changes found

View File

@ -36,13 +36,19 @@ kill `cat hg.pid`
echo % expect success
echo 'allow_push = *' >> .hg/hgrc
echo '[hooks]' >> .hg/hgrc
echo 'changegroup = echo changegroup: u=$HG_URL >> $HGTMP/urls' >> .hg/hgrc
hg serve -p 20059 -d --pid-file=hg.pid
cat hg.pid >> $DAEMON_PIDS
hg --cwd ../test2 push http://localhost:20059/
kill `cat hg.pid`
hg rollback
sed 's/\(remote:http.*\):.*/\1/' $HGTMP/urls
echo % expect authorization error: all users denied
echo '[web]' > .hg/hgrc
echo 'push_ssl = false' >> .hg/hgrc
echo 'deny_push = *' >> .hg/hgrc
hg serve -p 20059 -d --pid-file=hg.pid
cat hg.pid >> $DAEMON_PIDS

View File

@ -20,6 +20,7 @@ adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
rolling back last transaction
changegroup: u=remote:http
% expect authorization error: all users denied
pushing to http://localhost:20059/
searching for changes

View File

@ -17,6 +17,8 @@ if [ ! -x dummyssh ] ; then
exit -1
fi
SSH_CLIENT='127.0.0.1 1 2'
export SSH_CLIENT
echo Got arguments 1:$1 2:$2 3:$3 4:$4 5:$5 >> dummylog
$2
EOF
@ -29,6 +31,8 @@ echo this > foo
hg ci -A -m "init" -d "1000000 0" foo
echo '[server]' > .hg/hgrc
echo 'uncompressed = True' >> .hg/hgrc
echo '[hooks]' >> .hg/hgrc
echo 'changegroup = echo changegroup in remote: u=$HG_URL >> ../dummylog' >> .hg/hgrc
cd ..
@ -46,6 +50,9 @@ echo "# verify"
cd local
hg verify
echo '[hooks]' >> .hg/hgrc
echo 'changegroup = echo changegroup in local: u=$HG_URL >> ../dummylog' >> .hg/hgrc
echo "# empty default pull"
hg paths
hg pull -e ../dummyssh

View File

@ -83,5 +83,7 @@ Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
Got arguments 1:user@dummy 2:hg -R local serve --stdio 3: 4: 5:
Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
changegroup in remote: u=remote:ssh:127.0.0.1
Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
changegroup in remote: u=remote:ssh:127.0.0.1

View File

@ -37,6 +37,14 @@ http_proxy= hg clone static-http://localhost:20059/remote local
cd local
hg verify
cat bar
cd ../remote
echo baz > quux
hg commit -A -mtest2 -d '100000000 0'
cd ../local
echo '[hooks]' >> .hg/hgrc
echo 'changegroup = echo changegroup: u=$HG_URL' >> .hg/hgrc
http_proxy= hg pull
kill $!

View File

@ -19,6 +19,12 @@ crosschecking files in changesets and manifests
checking files
1 files, 1 changesets, 1 total revisions
foo
adding quux
changegroup: u=static-http://localhost:20059/remote
pulling from static-http://localhost:20059/remote
searching for changes
no changes found
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
(run 'hg update' to get a working copy)