##// END OF EJS Templates
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
Vadim Gelfer -
r2673:109a22f5 default
parent child Browse files
Show More
@@ -194,7 +194,8 b' hooks::'
194 194
195 195 changegroup;;
196 196 Run after a changegroup has been added via push, pull or
197 unbundle. ID of the first new changeset is in $HG_NODE.
197 unbundle. ID of the first new changeset is in $HG_NODE. URL from
198 which changes came is in $HG_URL.
198 199 commit;;
199 200 Run after a changeset has been created in the local repository.
200 201 ID of the newly created changeset is in $HG_NODE. Parent
@@ -202,7 +203,7 b' hooks::'
202 203 incoming;;
203 204 Run after a changeset has been pulled, pushed, or unbundled into
204 205 the local repository. The ID of the newly arrived changeset is in
205 $HG_NODE.
206 $HG_NODE. URL that was source of changes came is in $HG_URL.
206 207 outgoing;;
207 208 Run after sending changes from local repository to another. ID of
208 209 first changeset sent is in $HG_NODE. Source of operation is in
@@ -210,7 +211,8 b' hooks::'
210 211 prechangegroup;;
211 212 Run before a changegroup is added via push, pull or unbundle.
212 213 Exit status 0 allows the changegroup to proceed. Non-zero status
213 will cause the push, pull or unbundle to fail.
214 will cause the push, pull or unbundle to fail. URL from which
215 changes will come is in $HG_URL.
214 216 precommit;;
215 217 Run before starting a local commit. Exit status 0 allows the
216 218 commit to proceed. Non-zero status will cause the commit to fail.
@@ -236,7 +238,8 b' hooks::'
236 238 before accepting them. Passed the ID of the first new changeset
237 239 in $HG_NODE. Exit status 0 allows the transaction to commit.
238 240 Non-zero status will cause the transaction to be rolled back and
239 the push, pull or unbundle will fail.
241 the push, pull or unbundle will fail. URL that was source of
242 changes is in $HG_URL.
240 243 pretxncommit;;
241 244 Run after a changeset has been created but the transaction not yet
242 245 committed. Changeset is visible to hook program. This lets you
@@ -159,6 +159,10 b' class bundlefilelog(bundlerevlog, filelo'
159 159 class bundlerepository(localrepo.localrepository):
160 160 def __init__(self, ui, path, bundlename):
161 161 localrepo.localrepository.__init__(self, ui, path)
162
163 self._url = 'bundle:' + bundlename
164 if path: self._url += '+' + path
165
162 166 self.tempfile = None
163 167 self.bundlefile = open(bundlename, "rb")
164 168 header = self.bundlefile.read(6)
@@ -208,6 +212,9 b' class bundlerepository(localrepo.localre'
208 212 for c in changegroup.chunkiter(self.bundlefile):
209 213 pass
210 214
215 def url(self):
216 return self._url
217
211 218 def dev(self):
212 219 return -1
213 220
@@ -2763,7 +2763,8 b' def unbundle(ui, repo, fname, **opts):'
2763 2763 raise util.Abort(_("%s: unknown bundle compression type")
2764 2764 % fname)
2765 2765 gen = generator(util.filechunkiter(f, 4096))
2766 modheads = repo.addchangegroup(util.chunkbuffer(gen), 'unbundle')
2766 modheads = repo.addchangegroup(util.chunkbuffer(gen), 'unbundle',
2767 'bundle:' + fname)
2767 2768 return postincoming(ui, repo, modheads, opts['update'])
2768 2769
2769 2770 def undo(ui, repo):
@@ -904,9 +904,13 b' class hgweb(object):'
904 904 # require ssl by default, auth info cannot be sniffed and
905 905 # replayed
906 906 ssl_req = self.repo.ui.configbool('web', 'push_ssl', True)
907 if ssl_req and not req.env.get('HTTPS'):
907 if ssl_req:
908 if not req.env.get('HTTPS'):
908 909 bail(_('ssl required\n'))
909 910 return
911 proto = 'https'
912 else:
913 proto = 'http'
910 914
911 915 # do not allow push unless explicitly allowed
912 916 if not self.check_perm(req, 'push', False):
@@ -952,7 +956,9 b' class hgweb(object):'
952 956 sys.stdout = cStringIO.StringIO()
953 957
954 958 try:
955 ret = self.repo.addchangegroup(fp, 'serve')
959 url = 'remote:%s:%s' % (proto,
960 req.env.get('REMOTE_HOST', ''))
961 ret = self.repo.addchangegroup(fp, 'serve', url)
956 962 finally:
957 963 val = sys.stdout.getvalue()
958 964 sys.stdout = old_stdout
@@ -115,6 +115,7 b' else:'
115 115
116 116 class httprepository(remoterepository):
117 117 def __init__(self, ui, path):
118 self.path = path
118 119 self.caps = None
119 120 scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
120 121 if query or frag:
@@ -124,7 +125,7 b' class httprepository(remoterepository):'
124 125 host, port, user, passwd = netlocsplit(netloc)
125 126
126 127 # urllib cannot handle URLs with embedded user or passwd
127 self.url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
128 self._url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
128 129 urlpath, '', ''))
129 130 self.ui = ui
130 131
@@ -189,6 +190,9 b' class httprepository(remoterepository):'
189 190 opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
190 191 urllib2.install_opener(opener)
191 192
193 def url(self):
194 return self.path
195
192 196 # look up capabilities only when needed
193 197
194 198 def get_caps(self):
@@ -213,7 +217,7 b' class httprepository(remoterepository):'
213 217 q = {"cmd": cmd}
214 218 q.update(args)
215 219 qs = urllib.urlencode(q)
216 cu = "%s?%s" % (self.url, qs)
220 cu = "%s?%s" % (self._url, qs)
217 221 try:
218 222 resp = urllib2.urlopen(urllib2.Request(cu, data, headers))
219 223 except urllib2.HTTPError, inst:
@@ -234,13 +238,13 b' class httprepository(remoterepository):'
234 238 not proto.startswith('text/plain') and \
235 239 not proto.startswith('application/hg-changegroup'):
236 240 raise hg.RepoError(_("'%s' does not appear to be an hg repository") %
237 self.url)
241 self._url)
238 242
239 243 if proto.startswith('application/mercurial'):
240 244 version = proto[22:]
241 245 if float(version) > 0.1:
242 246 raise hg.RepoError(_("'%s' uses newer protocol %s") %
243 (self.url, version))
247 (self._url, version))
244 248
245 249 return resp
246 250
@@ -83,6 +83,9 b' class localrepository(repo.repository):'
83 83
84 84 self.dirstate = dirstate.dirstate(self.opener, self.ui, self.root)
85 85
86 def url(self):
87 return 'file:' + self.root
88
86 89 def hook(self, name, throw=False, **args):
87 90 def callhook(hname, funcname):
88 91 '''call python hook. hook is callable object, looked up as
@@ -1185,7 +1188,7 b' class localrepository(repo.repository):'
1185 1188 cg = remote.changegroup(fetch, 'pull')
1186 1189 else:
1187 1190 cg = remote.changegroupsubset(fetch, heads, 'pull')
1188 return self.addchangegroup(cg, 'pull')
1191 return self.addchangegroup(cg, 'pull', remote.url())
1189 1192
1190 1193 def push(self, remote, force=False, revs=None):
1191 1194 # there are two ways to push to remote repo:
@@ -1241,7 +1244,7 b' class localrepository(repo.repository):'
1241 1244 ret = self.prepush(remote, force, revs)
1242 1245 if ret[0] is not None:
1243 1246 cg, remote_heads = ret
1244 return remote.addchangegroup(cg, 'push')
1247 return remote.addchangegroup(cg, 'push', self.url())
1245 1248 return ret[1]
1246 1249
1247 1250 def push_unbundle(self, remote, force, revs):
@@ -1594,7 +1597,7 b' class localrepository(repo.repository):'
1594 1597
1595 1598 return util.chunkbuffer(gengroup())
1596 1599
1597 def addchangegroup(self, source, srctype):
1600 def addchangegroup(self, source, srctype, url):
1598 1601 """add changegroup to repo.
1599 1602 returns number of heads modified or added + 1."""
1600 1603
@@ -1608,7 +1611,7 b' class localrepository(repo.repository):'
1608 1611 if not source:
1609 1612 return 0
1610 1613
1611 self.hook('prechangegroup', throw=True, source=srctype)
1614 self.hook('prechangegroup', throw=True, source=srctype, url=url)
1612 1615
1613 1616 changesets = files = revisions = 0
1614 1617
@@ -1675,17 +1678,18 b' class localrepository(repo.repository):'
1675 1678
1676 1679 if changesets > 0:
1677 1680 self.hook('pretxnchangegroup', throw=True,
1678 node=hex(self.changelog.node(cor+1)), source=srctype)
1681 node=hex(self.changelog.node(cor+1)), source=srctype,
1682 url=url)
1679 1683
1680 1684 tr.close()
1681 1685
1682 1686 if changesets > 0:
1683 1687 self.hook("changegroup", node=hex(self.changelog.node(cor+1)),
1684 source=srctype)
1688 source=srctype, url=url)
1685 1689
1686 1690 for i in range(cor + 1, cnr + 1):
1687 1691 self.hook("incoming", node=hex(self.changelog.node(i)),
1688 source=srctype)
1692 source=srctype, url=url)
1689 1693
1690 1694 return newheads - oldheads + 1
1691 1695
@@ -13,7 +13,7 b' demandload(globals(), "hg os re stat uti'
13 13
14 14 class sshrepository(remoterepository):
15 15 def __init__(self, ui, path, create=0):
16 self.url = path
16 self._url = path
17 17 self.ui = ui
18 18
19 19 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', path)
@@ -48,6 +48,9 b' class sshrepository(remoterepository):'
48 48
49 49 self.validate_repo(ui, sshcmd, args, remotecmd)
50 50
51 def url(self):
52 return self._url
53
51 54 def validate_repo(self, ui, sshcmd, args, remotecmd):
52 55 cmd = '%s %s "%s -R %s serve --stdio"'
53 56 cmd = cmd % (sshcmd, args, remotecmd, self.path)
@@ -180,7 +183,7 b' class sshrepository(remoterepository):'
180 183 return 1
181 184 return int(r)
182 185
183 def addchangegroup(self, cg, source):
186 def addchangegroup(self, cg, source, url):
184 187 d = self.call("addchangegroup")
185 188 if d:
186 189 raise hg.RepoError(_("push refused: %s") % d)
@@ -117,9 +117,13 b' class sshserver(object):'
117 117 return
118 118
119 119 self.respond("")
120 r = self.repo.addchangegroup(self.fin, 'serve')
120 r = self.repo.addchangegroup(self.fin, 'serve', self.client_url())
121 121 self.respond(str(r))
122 122
123 def client_url(self):
124 client = os.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
125 return 'remote:ssh:' + client
126
123 127 def do_unbundle(self):
124 128 their_heads = self.getarg()[1].split()
125 129
@@ -159,7 +163,7 b' class sshserver(object):'
159 163 # push can proceed
160 164
161 165 fp.seek(0)
162 r = self.repo.addchangegroup(fp, 'serve')
166 r = self.repo.addchangegroup(fp, 'serve', self.client_url())
163 167 self.respond(str(r))
164 168 finally:
165 169 if not was_locked:
@@ -30,6 +30,7 b' def opener(base):'
30 30
31 31 class statichttprepository(localrepo.localrepository):
32 32 def __init__(self, ui, path):
33 self._url = path
33 34 self.path = (path + "/.hg")
34 35 self.ui = ui
35 36 self.revlogversion = 0
@@ -41,6 +42,9 b' class statichttprepository(localrepo.loc'
41 42 self.encodepats = None
42 43 self.decodepats = None
43 44
45 def url(self):
46 return 'static-' + self._url
47
44 48 def dev(self):
45 49 return -1
46 50
@@ -38,6 +38,8 b' rm -rf empty'
38 38 hg init empty
39 39 cd empty
40 40 hg -R bundle://../full.hg log
41 echo '[hooks]' >> .hg/hgrc
42 echo 'changegroup = echo changegroup: u=$HG_URL' >> .hg/hgrc
41 43 #doesn't work (yet ?)
42 44 #hg -R bundle://../full.hg verify
43 45 hg pull bundle://../full.hg
@@ -81,6 +81,7 b' user: test'
81 81 date: Mon Jan 12 13:46:40 1970 +0000
82 82 summary: 0.0
83 83
84 changegroup: u=bundle:../full.hg
84 85 pulling from bundle://../full.hg
85 86 requesting all changes
86 87 adding changesets
@@ -17,9 +17,9 b' cd ../b'
17 17
18 18 # changegroup hooks can see env vars
19 19 echo '[hooks]' > .hg/hgrc
20 echo 'prechangegroup = echo prechangegroup hook' >> .hg/hgrc
21 echo 'changegroup = echo changegroup hook: n=$HG_NODE' >> .hg/hgrc
22 echo 'incoming = echo incoming hook: n=$HG_NODE' >> .hg/hgrc
20 echo 'prechangegroup = echo prechangegroup hook: u=`echo $HG_URL | sed s,file:.*,file:,`' >> .hg/hgrc
21 echo 'changegroup = echo changegroup hook: n=$HG_NODE u=`echo $HG_URL | sed s,file:.*,file:,`' >> .hg/hgrc
22 echo 'incoming = echo incoming hook: n=$HG_NODE u=`echo $HG_URL | sed s,file:.*,file:,`' >> .hg/hgrc
23 23
24 24 # pretxncommit and commit hooks can see both parents of merge
25 25 cd ../a
@@ -22,11 +22,11 b' pretxncommit hook: n=4c52fb2e402287dd5dc'
22 22 3:4c52fb2e4022
23 23 commit hook: n=4c52fb2e402287dd5dc052090682536c8406c321 p1=1324a5531bac09b329c3845d35ae6a7526874edb p2=b702efe9688826e3a91283852b328b84dbf37bc2
24 24 commit hook b
25 prechangegroup hook
26 changegroup hook: n=b702efe9688826e3a91283852b328b84dbf37bc2
27 incoming hook: n=b702efe9688826e3a91283852b328b84dbf37bc2
28 incoming hook: n=1324a5531bac09b329c3845d35ae6a7526874edb
29 incoming hook: n=4c52fb2e402287dd5dc052090682536c8406c321
25 prechangegroup hook: u=file:
26 changegroup hook: n=b702efe9688826e3a91283852b328b84dbf37bc2 u=file:
27 incoming hook: n=b702efe9688826e3a91283852b328b84dbf37bc2 u=file:
28 incoming hook: n=1324a5531bac09b329c3845d35ae6a7526874edb u=file:
29 incoming hook: n=4c52fb2e402287dd5dc052090682536c8406c321 u=file:
30 30 pulling from ../a
31 31 searching for changes
32 32 adding changesets
@@ -23,3 +23,13 b' echo % clone via pull'
23 23 http_proxy= hg clone http://localhost:20059/ copy-pull
24 24 cd copy-pull
25 25 hg verify
26
27 cd test
28 echo bar > bar
29 hg commit -A -d '1 0' -m 2
30
31 echo % pull
32 cd ../copy-pull
33 echo '[hooks]' >> .hg/hgrc
34 echo 'changegroup = echo changegroup: u=$HG_URL' >> .hg/hgrc
35 hg pull
@@ -28,3 +28,9 b' checking manifests'
28 28 crosschecking files in changesets and manifests
29 29 checking files
30 30 1 files, 1 changesets, 1 total revisions
31 /home/bos/hg/hg/hg-url/tests/test-http: line 27: cd: test: No such file or directory
32 adding bar
33 % pull
34 pulling from http://localhost:20059/
35 searching for changes
36 no changes found
@@ -36,13 +36,19 b' kill `cat hg.pid`'
36 36
37 37 echo % expect success
38 38 echo 'allow_push = *' >> .hg/hgrc
39 echo '[hooks]' >> .hg/hgrc
40 echo 'changegroup = echo changegroup: u=$HG_URL >> $HGTMP/urls' >> .hg/hgrc
39 41 hg serve -p 20059 -d --pid-file=hg.pid
40 42 cat hg.pid >> $DAEMON_PIDS
41 43 hg --cwd ../test2 push http://localhost:20059/
42 44 kill `cat hg.pid`
43 45 hg rollback
44 46
47 sed 's/\(remote:http.*\):.*/\1/' $HGTMP/urls
48
45 49 echo % expect authorization error: all users denied
50 echo '[web]' > .hg/hgrc
51 echo 'push_ssl = false' >> .hg/hgrc
46 52 echo 'deny_push = *' >> .hg/hgrc
47 53 hg serve -p 20059 -d --pid-file=hg.pid
48 54 cat hg.pid >> $DAEMON_PIDS
@@ -20,6 +20,7 b' adding manifests'
20 20 adding file changes
21 21 added 1 changesets with 1 changes to 1 files
22 22 rolling back last transaction
23 changegroup: u=remote:http
23 24 % expect authorization error: all users denied
24 25 pushing to http://localhost:20059/
25 26 searching for changes
@@ -17,6 +17,8 b' if [ ! -x dummyssh ] ; then'
17 17 exit -1
18 18 fi
19 19
20 SSH_CLIENT='127.0.0.1 1 2'
21 export SSH_CLIENT
20 22 echo Got arguments 1:$1 2:$2 3:$3 4:$4 5:$5 >> dummylog
21 23 $2
22 24 EOF
@@ -29,6 +31,8 b' echo this > foo'
29 31 hg ci -A -m "init" -d "1000000 0" foo
30 32 echo '[server]' > .hg/hgrc
31 33 echo 'uncompressed = True' >> .hg/hgrc
34 echo '[hooks]' >> .hg/hgrc
35 echo 'changegroup = echo changegroup in remote: u=$HG_URL >> ../dummylog' >> .hg/hgrc
32 36
33 37 cd ..
34 38
@@ -46,6 +50,9 b' echo "# verify"'
46 50 cd local
47 51 hg verify
48 52
53 echo '[hooks]' >> .hg/hgrc
54 echo 'changegroup = echo changegroup in local: u=$HG_URL >> ../dummylog' >> .hg/hgrc
55
49 56 echo "# empty default pull"
50 57 hg paths
51 58 hg pull -e ../dummyssh
@@ -83,5 +83,7 b' Got arguments 1:user@dummy 2:hg -R remot'
83 83 Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
84 84 Got arguments 1:user@dummy 2:hg -R local serve --stdio 3: 4: 5:
85 85 Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
86 changegroup in remote: u=remote:ssh:127.0.0.1
86 87 Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
87 88 Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
89 changegroup in remote: u=remote:ssh:127.0.0.1
@@ -37,6 +37,14 b' http_proxy= hg clone static-http://local'
37 37 cd local
38 38 hg verify
39 39 cat bar
40
41 cd ../remote
42 echo baz > quux
43 hg commit -A -mtest2 -d '100000000 0'
44
45 cd ../local
46 echo '[hooks]' >> .hg/hgrc
47 echo 'changegroup = echo changegroup: u=$HG_URL' >> .hg/hgrc
40 48 http_proxy= hg pull
41 49
42 50 kill $!
@@ -19,6 +19,12 b' crosschecking files in changesets and ma'
19 19 checking files
20 20 1 files, 1 changesets, 1 total revisions
21 21 foo
22 adding quux
23 changegroup: u=static-http://localhost:20059/remote
22 24 pulling from static-http://localhost:20059/remote
23 25 searching for changes
24 no changes found
26 adding changesets
27 adding manifests
28 adding file changes
29 added 1 changesets with 1 changes to 1 files
30 (run 'hg update' to get a working copy)
General Comments 0
You need to be logged in to leave comments. Login now