Show More
@@ -0,0 +1,77 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | # This tests if hgweb and hgwebdir still work if the REQUEST_URI variable is | |||
|
3 | # no longer passed with the request. Instead, SCRIPT_NAME and PATH_INFO | |||
|
4 | # should be used from d74fc8dec2b4 onward to route the request. | |||
|
5 | ||||
|
6 | mkdir repo | |||
|
7 | cd repo | |||
|
8 | hg init | |||
|
9 | echo foo > bar | |||
|
10 | hg add bar | |||
|
11 | hg commit -m "test" -d "0 0" -u "Testing" | |||
|
12 | hg tip | |||
|
13 | ||||
|
14 | cat > request.py <<EOF | |||
|
15 | from mercurial.hgweb import hgweb, hgwebdir | |||
|
16 | from StringIO import StringIO | |||
|
17 | import os, sys | |||
|
18 | ||||
|
19 | errors = StringIO() | |||
|
20 | input = StringIO() | |||
|
21 | ||||
|
22 | def startrsp(headers, data): | |||
|
23 | print '---- HEADERS' | |||
|
24 | print headers | |||
|
25 | print '---- DATA' | |||
|
26 | print data | |||
|
27 | return output.write | |||
|
28 | ||||
|
29 | env = { | |||
|
30 | 'wsgi.version': (1, 0), | |||
|
31 | 'wsgi.url_scheme': 'http', | |||
|
32 | 'wsgi.errors': errors, | |||
|
33 | 'wsgi.input': input, | |||
|
34 | 'wsgi.multithread': False, | |||
|
35 | 'wsgi.multiprocess': False, | |||
|
36 | 'wsgi.run_once': False, | |||
|
37 | 'REQUEST_METHOD': 'GET', | |||
|
38 | 'SCRIPT_NAME': '', | |||
|
39 | 'SERVER_NAME': '127.0.0.1', | |||
|
40 | 'SERVER_PORT': os.environ['HGPORT'], | |||
|
41 | 'SERVER_PROTOCOL': 'HTTP/1.0' | |||
|
42 | } | |||
|
43 | ||||
|
44 | output = StringIO() | |||
|
45 | env['PATH_INFO'] = '/' | |||
|
46 | env['QUERY_STRING'] = 'style=atom' | |||
|
47 | hgweb('.', name = 'repo')(env, startrsp) | |||
|
48 | print output.getvalue() | |||
|
49 | print '---- ERRORS' | |||
|
50 | print errors.getvalue() | |||
|
51 | ||||
|
52 | output = StringIO() | |||
|
53 | env['PATH_INFO'] = '/file/tip/' | |||
|
54 | env['QUERY_STRING'] = 'style=raw' | |||
|
55 | hgweb('.', name = 'repo')(env, startrsp) | |||
|
56 | print output.getvalue() | |||
|
57 | print '---- ERRORS' | |||
|
58 | print errors.getvalue() | |||
|
59 | ||||
|
60 | output = StringIO() | |||
|
61 | env['PATH_INFO'] = '/' | |||
|
62 | env['QUERY_STRING'] = 'style=raw' | |||
|
63 | hgwebdir({'repo': '.'})(env, startrsp) | |||
|
64 | print output.getvalue() | |||
|
65 | print '---- ERRORS' | |||
|
66 | print errors.getvalue() | |||
|
67 | ||||
|
68 | output = StringIO() | |||
|
69 | env['PATH_INFO'] = '/repo/file/tip/' | |||
|
70 | env['QUERY_STRING'] = 'style=raw' | |||
|
71 | hgwebdir({'repo': '.'})(env, startrsp) | |||
|
72 | print output.getvalue() | |||
|
73 | print '---- ERRORS' | |||
|
74 | print errors.getvalue() | |||
|
75 | EOF | |||
|
76 | ||||
|
77 | python request.py | sed "s/http:\/\/127\.0\.0\.1:[0-9]*\//http:\/\/127.0.0.1\//" |
@@ -0,0 +1,72 b'' | |||||
|
1 | changeset: 0:4cbec7e6f8c4 | |||
|
2 | tag: tip | |||
|
3 | user: Testing | |||
|
4 | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
5 | summary: test | |||
|
6 | ||||
|
7 | ---- HEADERS | |||
|
8 | 200 Script output follows | |||
|
9 | ---- DATA | |||
|
10 | [('content-type', 'application/atom+xml; charset=ascii')] | |||
|
11 | <?xml version="1.0" encoding="ascii"?> | |||
|
12 | <feed xmlns="http://www.w3.org/2005/Atom"> | |||
|
13 | <!-- Changelog --> | |||
|
14 | <id>http://127.0.0.1/</id> | |||
|
15 | <link rel="self" href="http://127.0.0.1/atom-log"/> | |||
|
16 | <link rel="alternate" href="http://127.0.0.1/"/> | |||
|
17 | <title>repo Changelog</title> | |||
|
18 | <updated>1970-01-01T00:00:00+00:00</updated> | |||
|
19 | ||||
|
20 | <entry> | |||
|
21 | <title>test</title> | |||
|
22 | <id>http://www.selenic.com/mercurial/#changeset-4cbec7e6f8c42eb52b6b52670e1f7560ae9a101e</id> | |||
|
23 | <link href="http://127.0.0.1/rev/4cbec7e6f8c42eb52b6b52670e1f7560ae9a101e"/> | |||
|
24 | <author> | |||
|
25 | <name>Testing</name> | |||
|
26 | <email>Testing</email> | |||
|
27 | </author> | |||
|
28 | <updated>1970-01-01T00:00:00+00:00</updated> | |||
|
29 | <published>1970-01-01T00:00:00+00:00</published> | |||
|
30 | <content type="xhtml"> | |||
|
31 | <div xmlns="http://www.w3.org/1999/xhtml"> | |||
|
32 | <pre xml:space="preserve">test</pre> | |||
|
33 | </div> | |||
|
34 | </content> | |||
|
35 | </entry> | |||
|
36 | ||||
|
37 | </feed> | |||
|
38 | ||||
|
39 | ---- ERRORS | |||
|
40 | ||||
|
41 | ---- HEADERS | |||
|
42 | 200 Script output follows | |||
|
43 | ---- DATA | |||
|
44 | [('content-type', 'text/plain; charset=ascii')] | |||
|
45 | ||||
|
46 | -rw-r--r-- 4 bar | |||
|
47 | ||||
|
48 | ||||
|
49 | ||||
|
50 | ---- ERRORS | |||
|
51 | ||||
|
52 | ---- HEADERS | |||
|
53 | 200 Script output follows | |||
|
54 | ---- DATA | |||
|
55 | [('content-type', 'text/plain; charset=ascii')] | |||
|
56 | ||||
|
57 | /repo/ | |||
|
58 | ||||
|
59 | ||||
|
60 | ---- ERRORS | |||
|
61 | ||||
|
62 | ---- HEADERS | |||
|
63 | 200 Script output follows | |||
|
64 | ---- DATA | |||
|
65 | [('content-type', 'text/plain; charset=ascii')] | |||
|
66 | ||||
|
67 | -rw-r--r-- 4 bar | |||
|
68 | ||||
|
69 | ||||
|
70 | ||||
|
71 | ---- ERRORS | |||
|
72 |
@@ -0,0 +1,69 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | # Test issue835: | |||
|
4 | # qpush fails immediately when patching a missing file, but | |||
|
5 | # remaining added files are still created empty which will | |||
|
6 | # trick a future qrefresh. | |||
|
7 | ||||
|
8 | cat > writelines.py <<EOF | |||
|
9 | import sys | |||
|
10 | path = sys.argv[1] | |||
|
11 | args = sys.argv[2:] | |||
|
12 | assert (len(args) % 2) == 0 | |||
|
13 | ||||
|
14 | f = file(path, 'wb') | |||
|
15 | for i in xrange(len(args)/2): | |||
|
16 | count, s = args[2*i:2*i+2] | |||
|
17 | count = int(count) | |||
|
18 | s = s.decode('string_escape') | |||
|
19 | f.write(s*count) | |||
|
20 | f.close() | |||
|
21 | ||||
|
22 | EOF | |||
|
23 | ||||
|
24 | echo "[extensions]" >> $HGRCPATH | |||
|
25 | echo "mq=" >> $HGRCPATH | |||
|
26 | ||||
|
27 | hg init normal | |||
|
28 | cd normal | |||
|
29 | python ../writelines.py b 10 'a\n' | |||
|
30 | hg ci -Am addb | |||
|
31 | echo a > a | |||
|
32 | python ../writelines.py b 2 'b\n' 10 'a\n' 2 'c\n' | |||
|
33 | echo c > c | |||
|
34 | hg add a c | |||
|
35 | hg qnew -f changeb | |||
|
36 | hg qpop | |||
|
37 | hg rm b | |||
|
38 | hg ci -Am rmb | |||
|
39 | echo % push patch with missing target | |||
|
40 | hg qpush | |||
|
41 | echo % display added files | |||
|
42 | cat a | |||
|
43 | cat c | |||
|
44 | cd .. | |||
|
45 | ||||
|
46 | ||||
|
47 | echo "[diff]" >> $HGRCPATH | |||
|
48 | echo "git=1" >> $HGRCPATH | |||
|
49 | ||||
|
50 | hg init git | |||
|
51 | cd git | |||
|
52 | python ../writelines.py b 1 '\x00' | |||
|
53 | hg ci -Am addb | |||
|
54 | echo a > a | |||
|
55 | python ../writelines.py b 1 '\x01' 1 '\x00' | |||
|
56 | echo c > c | |||
|
57 | hg add a c | |||
|
58 | hg qnew -f changeb | |||
|
59 | hg qpop | |||
|
60 | hg rm b | |||
|
61 | hg ci -Am rmb | |||
|
62 | echo % push git patch with missing target | |||
|
63 | hg qpush 2>&1 | sed -e 's/b:.*/b: No such file or directory/' | |||
|
64 | hg st | |||
|
65 | echo % display added files | |||
|
66 | cat a | |||
|
67 | cat c | |||
|
68 | cd .. | |||
|
69 |
@@ -0,0 +1,25 b'' | |||||
|
1 | adding b | |||
|
2 | Patch queue now empty | |||
|
3 | % push patch with missing target | |||
|
4 | applying changeb | |||
|
5 | unable to find b or b for patching | |||
|
6 | unable to find b or b for patching | |||
|
7 | patch failed, unable to continue (try -v) | |||
|
8 | patch failed, rejects left in working dir | |||
|
9 | Errors during apply, please fix and refresh changeb | |||
|
10 | % display added files | |||
|
11 | a | |||
|
12 | c | |||
|
13 | adding b | |||
|
14 | Patch queue now empty | |||
|
15 | % push git patch with missing target | |||
|
16 | applying changeb | |||
|
17 | unable to find b or b for patching | |||
|
18 | patch failed, unable to continue (try -v) | |||
|
19 | b: No such file or directory | |||
|
20 | b not tracked! | |||
|
21 | patch failed, rejects left in working dir | |||
|
22 | Errors during apply, please fix and refresh changeb | |||
|
23 | % display added files | |||
|
24 | a | |||
|
25 | c |
@@ -0,0 +1,91 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | # This tests if CGI files from after d0db3462d568 but | |||
|
3 | # before d74fc8dec2b4 still work. | |||
|
4 | ||||
|
5 | hg init test | |||
|
6 | ||||
|
7 | cat >hgweb.cgi <<HGWEB | |||
|
8 | #!/usr/bin/env python | |||
|
9 | # | |||
|
10 | # An example CGI script to use hgweb, edit as necessary | |||
|
11 | ||||
|
12 | import cgitb | |||
|
13 | cgitb.enable() | |||
|
14 | ||||
|
15 | from mercurial import demandimport; demandimport.enable() | |||
|
16 | from mercurial.hgweb import hgweb | |||
|
17 | from mercurial.hgweb import wsgicgi | |||
|
18 | from mercurial.hgweb.request import wsgiapplication | |||
|
19 | ||||
|
20 | def make_web_app(): | |||
|
21 | return hgweb("test", "Empty test repository") | |||
|
22 | ||||
|
23 | wsgicgi.launch(wsgiapplication(make_web_app)) | |||
|
24 | HGWEB | |||
|
25 | chmod 755 hgweb.cgi | |||
|
26 | ||||
|
27 | cat >hgweb.config <<HGWEBDIRCONF | |||
|
28 | [paths] | |||
|
29 | test = test | |||
|
30 | HGWEBDIRCONF | |||
|
31 | ||||
|
32 | cat >hgwebdir.cgi <<HGWEBDIR | |||
|
33 | #!/usr/bin/env python | |||
|
34 | # | |||
|
35 | # An example CGI script to export multiple hgweb repos, edit as necessary | |||
|
36 | ||||
|
37 | import cgitb | |||
|
38 | cgitb.enable() | |||
|
39 | ||||
|
40 | from mercurial import demandimport; demandimport.enable() | |||
|
41 | from mercurial.hgweb import hgwebdir | |||
|
42 | from mercurial.hgweb import wsgicgi | |||
|
43 | from mercurial.hgweb.request import wsgiapplication | |||
|
44 | ||||
|
45 | def make_web_app(): | |||
|
46 | return hgwebdir("hgweb.config") | |||
|
47 | ||||
|
48 | wsgicgi.launch(wsgiapplication(make_web_app)) | |||
|
49 | HGWEBDIR | |||
|
50 | chmod 755 hgwebdir.cgi | |||
|
51 | ||||
|
52 | DOCUMENT_ROOT="/var/www/hg"; export DOCUMENT_ROOT | |||
|
53 | GATEWAY_INTERFACE="CGI/1.1"; export GATEWAY_INTERFACE | |||
|
54 | HTTP_ACCEPT="text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"; export HTTP_ACCEPT | |||
|
55 | HTTP_ACCEPT_CHARSET="ISO-8859-1,utf-8;q=0.7,*;q=0.7"; export HTTP_ACCEPT_CHARSET | |||
|
56 | HTTP_ACCEPT_ENCODING="gzip,deflate"; export HTTP_ACCEPT_ENCODING | |||
|
57 | HTTP_ACCEPT_LANGUAGE="en-us,en;q=0.5"; export HTTP_ACCEPT_LANGUAGE | |||
|
58 | HTTP_CACHE_CONTROL="max-age=0"; export HTTP_CACHE_CONTROL | |||
|
59 | HTTP_CONNECTION="keep-alive"; export HTTP_CONNECTION | |||
|
60 | HTTP_HOST="hg.omnifarious.org"; export HTTP_HOST | |||
|
61 | HTTP_KEEP_ALIVE="300"; export HTTP_KEEP_ALIVE | |||
|
62 | HTTP_USER_AGENT="Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.0.4) Gecko/20060608 Ubuntu/dapper-security Firefox/1.5.0.4"; export HTTP_USER_AGENT | |||
|
63 | PATH_INFO="/"; export PATH_INFO | |||
|
64 | PATH_TRANSLATED="/var/www/hg/index.html"; export PATH_TRANSLATED | |||
|
65 | QUERY_STRING=""; export QUERY_STRING | |||
|
66 | REMOTE_ADDR="127.0.0.2"; export REMOTE_ADDR | |||
|
67 | REMOTE_PORT="44703"; export REMOTE_PORT | |||
|
68 | REQUEST_METHOD="GET"; export REQUEST_METHOD | |||
|
69 | REQUEST_URI="/test/"; export REQUEST_URI | |||
|
70 | SCRIPT_FILENAME="/home/hopper/hg_public/test.cgi"; export SCRIPT_FILENAME | |||
|
71 | SCRIPT_NAME="/test"; export SCRIPT_NAME | |||
|
72 | SCRIPT_URI="http://hg.omnifarious.org/test/"; export SCRIPT_URI | |||
|
73 | SCRIPT_URL="/test/"; export SCRIPT_URL | |||
|
74 | SERVER_ADDR="127.0.0.1"; export SERVER_ADDR | |||
|
75 | SERVER_ADMIN="eric@localhost"; export SERVER_ADMIN | |||
|
76 | SERVER_NAME="hg.omnifarious.org"; export SERVER_NAME | |||
|
77 | SERVER_PORT="80"; export SERVER_PORT | |||
|
78 | SERVER_PROTOCOL="HTTP/1.1"; export SERVER_PROTOCOL | |||
|
79 | SERVER_SIGNATURE="<address>Apache/2.0.53 (Fedora) Server at hg.omnifarious.org Port 80</address>\; export SERVER_SIGNATURE | |||
|
80 | " | |||
|
81 | SERVER_SOFTWARE="Apache/2.0.53 (Fedora)"; export SERVER_SOFTWARE | |||
|
82 | python hgweb.cgi >page1 2>&1 ; echo $? | |||
|
83 | python hgwebdir.cgi >page2 2>&1 ; echo $? | |||
|
84 | PATH_INFO="/test/" | |||
|
85 | PATH_TRANSLATED="/var/something/test.cgi" | |||
|
86 | REQUEST_URI="/test/test/" | |||
|
87 | SCRIPT_URI="http://hg.omnifarious.org/test/test/" | |||
|
88 | SCRIPT_URL="/test/test/" | |||
|
89 | python hgwebdir.cgi >page3 2>&1 ; echo $? | |||
|
90 | fgrep -i error page1 page2 page3 && exit 1 | |||
|
91 | exit 0 |
@@ -0,0 +1,84 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | # This is a rudimentary test of the CGI files as of d74fc8dec2b4. | |||
|
3 | ||||
|
4 | hg init test | |||
|
5 | ||||
|
6 | cat >hgweb.cgi <<HGWEB | |||
|
7 | #!/usr/bin/env python | |||
|
8 | # | |||
|
9 | # An example CGI script to use hgweb, edit as necessary | |||
|
10 | ||||
|
11 | import cgitb | |||
|
12 | cgitb.enable() | |||
|
13 | ||||
|
14 | from mercurial import demandimport; demandimport.enable() | |||
|
15 | from mercurial.hgweb import hgweb | |||
|
16 | from mercurial.hgweb import wsgicgi | |||
|
17 | ||||
|
18 | application = hgweb("test", "Empty test repository") | |||
|
19 | wsgicgi.launch(application) | |||
|
20 | HGWEB | |||
|
21 | chmod 755 hgweb.cgi | |||
|
22 | ||||
|
23 | cat >hgweb.config <<HGWEBDIRCONF | |||
|
24 | [paths] | |||
|
25 | test = test | |||
|
26 | HGWEBDIRCONF | |||
|
27 | ||||
|
28 | cat >hgwebdir.cgi <<HGWEBDIR | |||
|
29 | #!/usr/bin/env python | |||
|
30 | # | |||
|
31 | # An example CGI script to export multiple hgweb repos, edit as necessary | |||
|
32 | ||||
|
33 | import cgitb | |||
|
34 | cgitb.enable() | |||
|
35 | ||||
|
36 | from mercurial import demandimport; demandimport.enable() | |||
|
37 | from mercurial.hgweb import hgwebdir | |||
|
38 | from mercurial.hgweb import wsgicgi | |||
|
39 | ||||
|
40 | application = hgwebdir("hgweb.config") | |||
|
41 | wsgicgi.launch(application) | |||
|
42 | HGWEBDIR | |||
|
43 | chmod 755 hgwebdir.cgi | |||
|
44 | ||||
|
45 | DOCUMENT_ROOT="/var/www/hg"; export DOCUMENT_ROOT | |||
|
46 | GATEWAY_INTERFACE="CGI/1.1"; export GATEWAY_INTERFACE | |||
|
47 | HTTP_ACCEPT="text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"; export HTTP_ACCEPT | |||
|
48 | HTTP_ACCEPT_CHARSET="ISO-8859-1,utf-8;q=0.7,*;q=0.7"; export HTTP_ACCEPT_CHARSET | |||
|
49 | HTTP_ACCEPT_ENCODING="gzip,deflate"; export HTTP_ACCEPT_ENCODING | |||
|
50 | HTTP_ACCEPT_LANGUAGE="en-us,en;q=0.5"; export HTTP_ACCEPT_LANGUAGE | |||
|
51 | HTTP_CACHE_CONTROL="max-age=0"; export HTTP_CACHE_CONTROL | |||
|
52 | HTTP_CONNECTION="keep-alive"; export HTTP_CONNECTION | |||
|
53 | HTTP_HOST="hg.omnifarious.org"; export HTTP_HOST | |||
|
54 | HTTP_KEEP_ALIVE="300"; export HTTP_KEEP_ALIVE | |||
|
55 | HTTP_USER_AGENT="Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.0.4) Gecko/20060608 Ubuntu/dapper-security Firefox/1.5.0.4"; export HTTP_USER_AGENT | |||
|
56 | PATH_INFO="/"; export PATH_INFO | |||
|
57 | PATH_TRANSLATED="/var/www/hg/index.html"; export PATH_TRANSLATED | |||
|
58 | QUERY_STRING=""; export QUERY_STRING | |||
|
59 | REMOTE_ADDR="127.0.0.2"; export REMOTE_ADDR | |||
|
60 | REMOTE_PORT="44703"; export REMOTE_PORT | |||
|
61 | REQUEST_METHOD="GET"; export REQUEST_METHOD | |||
|
62 | REQUEST_URI="/test/"; export REQUEST_URI | |||
|
63 | SCRIPT_FILENAME="/home/hopper/hg_public/test.cgi"; export SCRIPT_FILENAME | |||
|
64 | SCRIPT_NAME="/test"; export SCRIPT_NAME | |||
|
65 | SCRIPT_URI="http://hg.omnifarious.org/test/"; export SCRIPT_URI | |||
|
66 | SCRIPT_URL="/test/"; export SCRIPT_URL | |||
|
67 | SERVER_ADDR="127.0.0.1"; export SERVER_ADDR | |||
|
68 | SERVER_ADMIN="eric@localhost"; export SERVER_ADMIN | |||
|
69 | SERVER_NAME="hg.omnifarious.org"; export SERVER_NAME | |||
|
70 | SERVER_PORT="80"; export SERVER_PORT | |||
|
71 | SERVER_PROTOCOL="HTTP/1.1"; export SERVER_PROTOCOL | |||
|
72 | SERVER_SIGNATURE="<address>Apache/2.0.53 (Fedora) Server at hg.omnifarious.org Port 80</address>\; export SERVER_SIGNATURE | |||
|
73 | " | |||
|
74 | SERVER_SOFTWARE="Apache/2.0.53 (Fedora)"; export SERVER_SOFTWARE | |||
|
75 | python hgweb.cgi >page1 2>&1 ; echo $? | |||
|
76 | python hgwebdir.cgi >page2 2>&1 ; echo $? | |||
|
77 | PATH_INFO="/test/" | |||
|
78 | PATH_TRANSLATED="/var/something/test.cgi" | |||
|
79 | REQUEST_URI="/test/test/" | |||
|
80 | SCRIPT_URI="http://hg.omnifarious.org/test/test/" | |||
|
81 | SCRIPT_URL="/test/test/" | |||
|
82 | python hgwebdir.cgi >page3 2>&1 ; echo $? | |||
|
83 | fgrep -i error page1 page2 page3 && exit 1 | |||
|
84 | exit 0 |
@@ -125,6 +125,7 b' def gather_stats(ui, repo, amap, revs=No' | |||||
125 | ui.note("rev %d: %d lines by %s\n" % (rev, lines, who)) |
|
125 | ui.note("rev %d: %d lines by %s\n" % (rev, lines, who)) | |
126 |
|
126 | |||
127 | if progress: |
|
127 | if progress: | |
|
128 | nr_revs = max(nr_revs, 1) | |||
128 | if int(100.0*(cur_rev - 1)/nr_revs) < int(100.0*cur_rev/nr_revs): |
|
129 | if int(100.0*(cur_rev - 1)/nr_revs) < int(100.0*cur_rev/nr_revs): | |
129 | ui.write("%d%%.." % (int(100.0*cur_rev/nr_revs),)) |
|
130 | ui.write("%d%%.." % (int(100.0*cur_rev/nr_revs),)) | |
130 | sys.stdout.flush() |
|
131 | sys.stdout.flush() | |
@@ -144,6 +145,7 b' def churn(ui, repo, **opts):' | |||||
144 | return s[0:l] |
|
145 | return s[0:l] | |
145 |
|
146 | |||
146 | def graph(n, maximum, width, char): |
|
147 | def graph(n, maximum, width, char): | |
|
148 | maximum = max(1, maximum) | |||
147 | n = int(n * width / float(maximum)) |
|
149 | n = int(n * width / float(maximum)) | |
148 |
|
150 | |||
149 | return char * (n) |
|
151 | return char * (n) | |
@@ -178,6 +180,8 b' def churn(ui, repo, **opts):' | |||||
178 | ordered = stats.items() |
|
180 | ordered = stats.items() | |
179 | ordered.sort(lambda x, y: cmp(y[1], x[1])) |
|
181 | ordered.sort(lambda x, y: cmp(y[1], x[1])) | |
180 |
|
182 | |||
|
183 | if not ordered: | |||
|
184 | return | |||
181 | maximum = ordered[0][1] |
|
185 | maximum = ordered[0][1] | |
182 |
|
186 | |||
183 | width = get_tty_width() |
|
187 | width = get_tty_width() |
@@ -17,7 +17,9 b' FILES' | |||||
17 |
|
17 | |||
18 | Mercurial reads configuration data from several files, if they exist. |
|
18 | Mercurial reads configuration data from several files, if they exist. | |
19 | The names of these files depend on the system on which Mercurial is |
|
19 | The names of these files depend on the system on which Mercurial is | |
20 | installed. |
|
20 | installed. Windows registry keys contain PATH-like strings, every | |
|
21 | part must reference a Mercurial.ini file or be a directory where *.rc | |||
|
22 | files will be read. | |||
21 |
|
23 | |||
22 | (Unix) <install-root>/etc/mercurial/hgrc.d/*.rc:: |
|
24 | (Unix) <install-root>/etc/mercurial/hgrc.d/*.rc:: | |
23 | (Unix) <install-root>/etc/mercurial/hgrc:: |
|
25 | (Unix) <install-root>/etc/mercurial/hgrc:: | |
@@ -29,6 +31,8 b' installed.' | |||||
29 |
|
31 | |||
30 | (Unix) /etc/mercurial/hgrc.d/*.rc:: |
|
32 | (Unix) /etc/mercurial/hgrc.d/*.rc:: | |
31 | (Unix) /etc/mercurial/hgrc:: |
|
33 | (Unix) /etc/mercurial/hgrc:: | |
|
34 | (Windows) HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial:: | |||
|
35 | or:: | |||
32 | (Windows) C:\Mercurial\Mercurial.ini:: |
|
36 | (Windows) C:\Mercurial\Mercurial.ini:: | |
33 | Per-system configuration files, for the system on which Mercurial |
|
37 | Per-system configuration files, for the system on which Mercurial | |
34 | is running. Options in these files apply to all Mercurial |
|
38 | is running. Options in these files apply to all Mercurial |
@@ -726,37 +726,21 b' class hgweb(object):' | |||||
726 | def rewrite_request(req): |
|
726 | def rewrite_request(req): | |
727 | '''translate new web interface to traditional format''' |
|
727 | '''translate new web interface to traditional format''' | |
728 |
|
728 | |||
729 | def spliturl(req): |
|
729 | req.url = req.env['SCRIPT_NAME'] | |
730 | def firstitem(query): |
|
730 | if not req.url.endswith('/'): | |
731 | return query.split('&', 1)[0].split(';', 1)[0] |
|
731 | req.url += '/' | |
732 |
|
732 | if req.env.has_key('REPO_NAME'): | ||
733 | def normurl(url): |
|
733 | req.url += req.env['REPO_NAME'] + '/' | |
734 | inner = '/'.join([x for x in url.split('/') if x]) |
|
734 | ||
735 | tl = len(url) > 1 and url.endswith('/') and '/' or '' |
|
735 | if req.env.get('PATH_INFO'): | |
736 |
|
736 | parts = req.env.get('PATH_INFO').strip('/').split('/') | ||
737 | return '%s%s%s' % (url.startswith('/') and '/' or '', |
|
737 | repo_parts = req.env.get('REPO_NAME', '').split('/') | |
738 | inner, tl) |
|
738 | if parts[:len(repo_parts)] == repo_parts: | |
739 |
|
739 | parts = parts[len(repo_parts):] | ||
740 | root = normurl(urllib.unquote(req.env.get('REQUEST_URI', '').split('?', 1)[0])) |
|
740 | query = '/'.join(parts) | |
741 | pi = normurl(req.env.get('PATH_INFO', '')) |
|
741 | else: | |
742 | if pi: |
|
742 | query = req.env['QUERY_STRING'].split('&', 1)[0] | |
743 | # strip leading / |
|
743 | query = query.split(';', 1)[0] | |
744 | pi = pi[1:] |
|
|||
745 | if pi: |
|
|||
746 | root = root[:root.rfind(pi)] |
|
|||
747 | if req.env.has_key('REPO_NAME'): |
|
|||
748 | rn = req.env['REPO_NAME'] + '/' |
|
|||
749 | root += rn |
|
|||
750 | query = pi[len(rn):] |
|
|||
751 | else: |
|
|||
752 | query = pi |
|
|||
753 | else: |
|
|||
754 | root += '?' |
|
|||
755 | query = firstitem(req.env['QUERY_STRING']) |
|
|||
756 |
|
||||
757 | return (root, query) |
|
|||
758 |
|
||||
759 | req.url, query = spliturl(req) |
|
|||
760 |
|
744 | |||
761 | if req.form.has_key('cmd'): |
|
745 | if req.form.has_key('cmd'): | |
762 | # old style |
|
746 | # old style |
@@ -17,7 +17,7 b' from request import wsgirequest' | |||||
17 | class hgwebdir(object): |
|
17 | class hgwebdir(object): | |
18 | def __init__(self, config, parentui=None): |
|
18 | def __init__(self, config, parentui=None): | |
19 | def cleannames(items): |
|
19 | def cleannames(items): | |
20 |
return [(util.pconvert(name.strip( |
|
20 | return [(util.pconvert(name).strip('/'), path) | |
21 | for name, path in items] |
|
21 | for name, path in items] | |
22 |
|
22 | |||
23 | self.parentui = parentui |
|
23 | self.parentui = parentui | |
@@ -91,15 +91,11 b' class hgwebdir(object):' | |||||
91 | def config(section, name, default=None, untrusted=True): |
|
91 | def config(section, name, default=None, untrusted=True): | |
92 | return parentui.config(section, name, default, untrusted) |
|
92 | return parentui.config(section, name, default, untrusted) | |
93 |
|
93 | |||
94 | url = req.env['REQUEST_URI'].split('?')[0] |
|
94 | url = req.env.get('SCRIPT_NAME', '') | |
95 | if not url.endswith('/'): |
|
95 | if not url.endswith('/'): | |
96 | url += '/' |
|
96 | url += '/' | |
97 | pathinfo = req.env.get('PATH_INFO', '').strip('/') + '/' |
|
|||
98 | base = url[:len(url) - len(pathinfo)] |
|
|||
99 | if not base.endswith('/'): |
|
|||
100 | base += '/' |
|
|||
101 |
|
97 | |||
102 |
staticurl = config('web', 'staticurl') or |
|
98 | staticurl = config('web', 'staticurl') or url + 'static/' | |
103 | if not staticurl.endswith('/'): |
|
99 | if not staticurl.endswith('/'): | |
104 | staticurl += '/' |
|
100 | staticurl += '/' | |
105 |
|
101 | |||
@@ -158,8 +154,10 b' class hgwebdir(object):' | |||||
158 | if u.configbool("web", "hidden", untrusted=True): |
|
154 | if u.configbool("web", "hidden", untrusted=True): | |
159 | continue |
|
155 | continue | |
160 |
|
156 | |||
161 |
|
|
157 | parts = [req.env['PATH_INFO'], name] | |
162 | .replace("//", "/")) + '/' |
|
158 | if req.env['SCRIPT_NAME']: | |
|
159 | parts.insert(0, req.env['SCRIPT_NAME']) | |||
|
160 | url = ('/'.join(parts).replace("//", "/")) + '/' | |||
163 |
|
161 | |||
164 | # update time with local timezone |
|
162 | # update time with local timezone | |
165 | try: |
|
163 | try: |
@@ -84,6 +84,7 b' class _hgwebhandler(object, BaseHTTPServ' | |||||
84 | env['SERVER_NAME'] = self.server.server_name |
|
84 | env['SERVER_NAME'] = self.server.server_name | |
85 | env['SERVER_PORT'] = str(self.server.server_port) |
|
85 | env['SERVER_PORT'] = str(self.server.server_port) | |
86 | env['REQUEST_URI'] = self.path |
|
86 | env['REQUEST_URI'] = self.path | |
|
87 | env['SCRIPT_NAME'] = '' | |||
87 | env['PATH_INFO'] = path_info |
|
88 | env['PATH_INFO'] = path_info | |
88 | env['REMOTE_HOST'] = self.client_address[0] |
|
89 | env['REMOTE_HOST'] = self.client_address[0] | |
89 | env['REMOTE_ADDR'] = self.client_address[0] |
|
90 | env['REMOTE_ADDR'] = self.client_address[0] |
@@ -16,6 +16,7 b' def launch(application):' | |||||
16 | util.set_binary(sys.stdout) |
|
16 | util.set_binary(sys.stdout) | |
17 |
|
17 | |||
18 | environ = dict(os.environ.items()) |
|
18 | environ = dict(os.environ.items()) | |
|
19 | environ.setdefault('PATH_INFO', '') | |||
19 | environ['wsgi.input'] = sys.stdin |
|
20 | environ['wsgi.input'] = sys.stdin | |
20 | environ['wsgi.errors'] = sys.stderr |
|
21 | environ['wsgi.errors'] = sys.stderr | |
21 | environ['wsgi.version'] = (1, 0) |
|
22 | environ['wsgi.version'] = (1, 0) | |
@@ -61,13 +62,4 b' def launch(application):' | |||||
61 | headers_set[:] = [status, response_headers] |
|
62 | headers_set[:] = [status, response_headers] | |
62 | return write |
|
63 | return write | |
63 |
|
64 | |||
64 |
|
|
65 | application(environ, start_response) | |
65 | try: |
|
|||
66 | for data in result: |
|
|||
67 | if data: # don't send headers until body appears |
|
|||
68 | write(data) |
|
|||
69 | if not headers_sent: |
|
|||
70 | write('') # send headers now if body was empty |
|
|||
71 | finally: |
|
|||
72 | if hasattr(result,'close'): |
|
|||
73 | result.close() |
|
@@ -885,6 +885,19 b' def applydiff(ui, fp, changed, strip=1, ' | |||||
885 | dopatch = True |
|
885 | dopatch = True | |
886 | gitworkdone = False |
|
886 | gitworkdone = False | |
887 |
|
887 | |||
|
888 | def getpatchfile(afile, bfile, hunk): | |||
|
889 | try: | |||
|
890 | if sourcefile: | |||
|
891 | targetfile = patchfile(ui, sourcefile) | |||
|
892 | else: | |||
|
893 | targetfile = selectfile(afile, bfile, hunk, | |||
|
894 | strip, reverse) | |||
|
895 | targetfile = patchfile(ui, targetfile) | |||
|
896 | return targetfile | |||
|
897 | except PatchError, err: | |||
|
898 | ui.warn(str(err) + '\n') | |||
|
899 | return None | |||
|
900 | ||||
888 | while True: |
|
901 | while True: | |
889 | newfile = False |
|
902 | newfile = False | |
890 | x = lr.readline() |
|
903 | x = lr.readline() | |
@@ -912,22 +925,20 b' def applydiff(ui, fp, changed, strip=1, ' | |||||
912 | continue |
|
925 | continue | |
913 | hunknum += 1 |
|
926 | hunknum += 1 | |
914 | if not current_file: |
|
927 | if not current_file: | |
915 | if sourcefile: |
|
928 | current_file = getpatchfile(afile, bfile, current_hunk) | |
916 |
|
|
929 | if not current_file: | |
917 | else: |
|
930 | current_file, current_hunk = None, None | |
918 | current_file = selectfile(afile, bfile, current_hunk, |
|
931 | rejects += 1 | |
919 | strip, reverse) |
|
932 | continue | |
920 | current_file = patchfile(ui, current_file) |
|
|||
921 | elif state == BFILE and x.startswith('GIT binary patch'): |
|
933 | elif state == BFILE and x.startswith('GIT binary patch'): | |
922 | current_hunk = binhunk(changed[bfile[2:]][1]) |
|
934 | current_hunk = binhunk(changed[bfile[2:]][1]) | |
|
935 | hunknum += 1 | |||
923 | if not current_file: |
|
936 | if not current_file: | |
924 | if sourcefile: |
|
937 | current_file = getpatchfile(afile, bfile, current_hunk) | |
925 |
|
|
938 | if not current_file: | |
926 | else: |
|
939 | current_file, current_hunk = None, None | |
927 | current_file = selectfile(afile, bfile, current_hunk, |
|
940 | rejects += 1 | |
928 | strip, reverse) |
|
941 | continue | |
929 | current_file = patchfile(ui, current_file) |
|
|||
930 | hunknum += 1 |
|
|||
931 | current_hunk.extract(fp) |
|
942 | current_hunk.extract(fp) | |
932 | elif x.startswith('diff --git'): |
|
943 | elif x.startswith('diff --git'): | |
933 | # check for git diff, scanning the whole patch file if needed |
|
944 | # check for git diff, scanning the whole patch file if needed |
@@ -16,6 +16,7 b' import win32api' | |||||
16 | from i18n import _ |
|
16 | from i18n import _ | |
17 | import errno, os, pywintypes, win32con, win32file, win32process |
|
17 | import errno, os, pywintypes, win32con, win32file, win32process | |
18 | import cStringIO, winerror |
|
18 | import cStringIO, winerror | |
|
19 | import osutil | |||
19 | from win32com.shell import shell,shellcon |
|
20 | from win32com.shell import shell,shellcon | |
20 |
|
21 | |||
21 | class WinError: |
|
22 | class WinError: | |
@@ -179,6 +180,20 b' def testpid(pid):' | |||||
179 |
|
180 | |||
180 | def system_rcpath_win32(): |
|
181 | def system_rcpath_win32(): | |
181 | '''return default os-specific hgrc search path''' |
|
182 | '''return default os-specific hgrc search path''' | |
|
183 | try: | |||
|
184 | value = win32api.RegQueryValue( | |||
|
185 | win32con.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Mercurial') | |||
|
186 | rcpath = [] | |||
|
187 | for p in value.split(os.pathsep): | |||
|
188 | if p.lower().endswith('mercurial.ini'): | |||
|
189 | rcpath.append(p) | |||
|
190 | elif os.path.isdir(p): | |||
|
191 | for f, kind in osutil.listdir(p): | |||
|
192 | if f.endswith('.rc'): | |||
|
193 | rcpath.append(os.path.join(p, f)) | |||
|
194 | return rcpath | |||
|
195 | except pywintypes.error: | |||
|
196 | pass | |||
182 | proc = win32api.GetCurrentProcess() |
|
197 | proc = win32api.GetCurrentProcess() | |
183 | try: |
|
198 | try: | |
184 | # This will fail on windows < NT |
|
199 | # This will fail on windows < NT |
@@ -1,4 +1,5 b'' | |||||
1 | #!/bin/sh |
|
1 | #!/bin/sh | |
|
2 | # Some tests for hgweb. Tests static files, plain files and different 404's. | |||
2 |
|
3 | |||
3 | hg init test |
|
4 | hg init test | |
4 | cd test |
|
5 | cd test |
@@ -1,4 +1,6 b'' | |||||
1 | #!/bin/sh |
|
1 | #!/bin/sh | |
|
2 | # Tests some basic hgwebdir functionality. Tests setting up paths and | |||
|
3 | # collection, different forms of 404s and the subdirectory support. | |||
2 |
|
4 | |||
3 | mkdir webdir |
|
5 | mkdir webdir | |
4 | cd webdir |
|
6 | cd webdir | |
@@ -39,17 +41,37 b' echo % should succeed' | |||||
39 | echo % should give a 404 - repo is not published |
|
41 | echo % should give a 404 - repo is not published | |
40 | "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/c/file/tip/c?style=raw' |
|
42 | "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/c/file/tip/c?style=raw' | |
41 |
|
43 | |||
|
44 | cat > paths.conf <<EOF | |||
|
45 | [paths] | |||
|
46 | t/a/=$root/a | |||
|
47 | b=$root/b | |||
|
48 | EOF | |||
|
49 | ||||
|
50 | hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \ | |||
|
51 | -A access-paths.log -E error-paths.log | |||
|
52 | cat hg.pid >> $DAEMON_PIDS | |||
|
53 | ||||
|
54 | echo % should succeed, slashy names | |||
|
55 | "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/?style=raw' | |||
|
56 | "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/t?style=raw' | |||
|
57 | "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/t/?style=raw' | |||
|
58 | "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/t/a?style=atom' \ | |||
|
59 | | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//" | |||
|
60 | "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/t/a/?style=atom' \ | |||
|
61 | | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//" | |||
|
62 | "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/t/a/file/tip/a?style=raw' | |||
|
63 | ||||
42 | cat > collections.conf <<EOF |
|
64 | cat > collections.conf <<EOF | |
43 | [collections] |
|
65 | [collections] | |
44 | $root=$root |
|
66 | $root=$root | |
45 | EOF |
|
67 | EOF | |
46 |
|
68 | |||
47 |
hg serve -p $HGPORT |
|
69 | hg serve -p $HGPORT2 -d --pid-file=hg.pid --webdir-conf collections.conf \ | |
48 | -A access-collections.log -E error-collections.log |
|
70 | -A access-collections.log -E error-collections.log | |
49 | cat hg.pid >> $DAEMON_PIDS |
|
71 | cat hg.pid >> $DAEMON_PIDS | |
50 |
|
72 | |||
51 | echo % should succeed |
|
73 | echo % should succeed | |
52 |
"$TESTDIR/get-with-headers.py" localhost:$HGPORT |
|
74 | "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/?style=raw' | |
53 |
"$TESTDIR/get-with-headers.py" localhost:$HGPORT |
|
75 | "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/a/file/tip/a?style=raw' | |
54 |
"$TESTDIR/get-with-headers.py" localhost:$HGPORT |
|
76 | "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/b/file/tip/b?style=raw' | |
55 |
"$TESTDIR/get-with-headers.py" localhost:$HGPORT |
|
77 | "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/c/file/tip/c?style=raw' |
@@ -24,6 +24,84 b' 404 Not Found' | |||||
24 |
|
24 | |||
25 |
|
25 | |||
26 | error: repository c not found |
|
26 | error: repository c not found | |
|
27 | % should succeed, slashy names | |||
|
28 | 200 Script output follows | |||
|
29 | ||||
|
30 | ||||
|
31 | /b/ | |||
|
32 | /t/a/ | |||
|
33 | ||||
|
34 | 200 Script output follows | |||
|
35 | ||||
|
36 | ||||
|
37 | /t/a/ | |||
|
38 | ||||
|
39 | 200 Script output follows | |||
|
40 | ||||
|
41 | ||||
|
42 | /t/a/ | |||
|
43 | ||||
|
44 | 200 Script output follows | |||
|
45 | ||||
|
46 | <?xml version="1.0" encoding="ascii"?> | |||
|
47 | <feed xmlns="http://127.0.0.1/2005/Atom"> | |||
|
48 | <!-- Changelog --> | |||
|
49 | <id>http://127.0.0.1/t/a/</id> | |||
|
50 | <link rel="self" href="http://127.0.0.1/t/a/atom-log"/> | |||
|
51 | <link rel="alternate" href="http://127.0.0.1/t/a/"/> | |||
|
52 | <title>t/a Changelog</title> | |||
|
53 | <updated>1970-01-01T00:00:01+00:00</updated> | |||
|
54 | ||||
|
55 | <entry> | |||
|
56 | <title>a</title> | |||
|
57 | <id>http://127.0.0.1/mercurial/#changeset-8580ff50825a50c8f716709acdf8de0deddcd6ab</id> | |||
|
58 | <link href="http://127.0.0.1/t/a/rev/8580ff50825a50c8f716709acdf8de0deddcd6ab"/> | |||
|
59 | <author> | |||
|
60 | <name>test</name> | |||
|
61 | <email>test</email> | |||
|
62 | </author> | |||
|
63 | <updated>1970-01-01T00:00:01+00:00</updated> | |||
|
64 | <published>1970-01-01T00:00:01+00:00</published> | |||
|
65 | <content type="xhtml"> | |||
|
66 | <div xmlns="http://127.0.0.1/1999/xhtml"> | |||
|
67 | <pre xml:space="preserve">a</pre> | |||
|
68 | </div> | |||
|
69 | </content> | |||
|
70 | </entry> | |||
|
71 | ||||
|
72 | </feed> | |||
|
73 | 200 Script output follows | |||
|
74 | ||||
|
75 | <?xml version="1.0" encoding="ascii"?> | |||
|
76 | <feed xmlns="http://127.0.0.1/2005/Atom"> | |||
|
77 | <!-- Changelog --> | |||
|
78 | <id>http://127.0.0.1/t/a/</id> | |||
|
79 | <link rel="self" href="http://127.0.0.1/t/a/atom-log"/> | |||
|
80 | <link rel="alternate" href="http://127.0.0.1/t/a/"/> | |||
|
81 | <title>t/a Changelog</title> | |||
|
82 | <updated>1970-01-01T00:00:01+00:00</updated> | |||
|
83 | ||||
|
84 | <entry> | |||
|
85 | <title>a</title> | |||
|
86 | <id>http://127.0.0.1/mercurial/#changeset-8580ff50825a50c8f716709acdf8de0deddcd6ab</id> | |||
|
87 | <link href="http://127.0.0.1/t/a/rev/8580ff50825a50c8f716709acdf8de0deddcd6ab"/> | |||
|
88 | <author> | |||
|
89 | <name>test</name> | |||
|
90 | <email>test</email> | |||
|
91 | </author> | |||
|
92 | <updated>1970-01-01T00:00:01+00:00</updated> | |||
|
93 | <published>1970-01-01T00:00:01+00:00</published> | |||
|
94 | <content type="xhtml"> | |||
|
95 | <div xmlns="http://127.0.0.1/1999/xhtml"> | |||
|
96 | <pre xml:space="preserve">a</pre> | |||
|
97 | </div> | |||
|
98 | </content> | |||
|
99 | </entry> | |||
|
100 | ||||
|
101 | </feed> | |||
|
102 | 200 Script output follows | |||
|
103 | ||||
|
104 | a | |||
27 | % should succeed |
|
105 | % should succeed | |
28 | 200 Script output follows |
|
106 | 200 Script output follows | |
29 |
|
107 |
General Comments 0
You need to be logged in to leave comments.
Login now