Show More
@@ -0,0 +1,179 b'' | |||||
|
1 | # churn.py - create a graph showing who changed the most lines | |||
|
2 | # | |||
|
3 | # Copyright 2006 Josef "Jeff" Sipek <jeffpc@josefsipek.net> | |||
|
4 | # | |||
|
5 | # This software may be used and distributed according to the terms | |||
|
6 | # of the GNU General Public License, incorporated herein by reference. | |||
|
7 | # | |||
|
8 | # | |||
|
9 | # Aliases map file format is simple one alias per line in the following | |||
|
10 | # format: | |||
|
11 | # | |||
|
12 | # <alias email> <actual email> | |||
|
13 | ||||
|
14 | from mercurial.demandload import * | |||
|
15 | from mercurial.i18n import gettext as _ | |||
|
16 | demandload(globals(), 'time sys signal os') | |||
|
17 | demandload(globals(), 'mercurial:hg,mdiff,fancyopts,cmdutil,ui,util,templater,node') | |||
|
18 | ||||
|
19 | def __gather(ui, repo, node1, node2): | |||
|
20 | def dirtywork(f, mmap1, mmap2): | |||
|
21 | lines = 0 | |||
|
22 | ||||
|
23 | to = mmap1 and repo.file(f).read(mmap1[f]) or None | |||
|
24 | tn = mmap2 and repo.file(f).read(mmap2[f]) or None | |||
|
25 | ||||
|
26 | diff = mdiff.unidiff(to, "", tn, "", f).split("\n") | |||
|
27 | ||||
|
28 | for line in diff: | |||
|
29 | if not line: | |||
|
30 | continue # skip EOF | |||
|
31 | if line.startswith(" "): | |||
|
32 | continue # context line | |||
|
33 | if line.startswith("--- ") or line.startswith("+++ "): | |||
|
34 | continue # begining of diff | |||
|
35 | if line.startswith("@@ "): | |||
|
36 | continue # info line | |||
|
37 | ||||
|
38 | # changed lines | |||
|
39 | lines += 1 | |||
|
40 | ||||
|
41 | return lines | |||
|
42 | ||||
|
43 | ## | |||
|
44 | ||||
|
45 | lines = 0 | |||
|
46 | ||||
|
47 | changes = repo.status(node1, node2, None, util.always)[:5] | |||
|
48 | ||||
|
49 | modified, added, removed, deleted, unknown = changes | |||
|
50 | ||||
|
51 | who = repo.changelog.read(node2)[1] | |||
|
52 | who = templater.email(who) # get the email of the person | |||
|
53 | ||||
|
54 | mmap1 = repo.manifest.read(repo.changelog.read(node1)[0]) | |||
|
55 | mmap2 = repo.manifest.read(repo.changelog.read(node2)[0]) | |||
|
56 | for f in modified: | |||
|
57 | lines += dirtywork(f, mmap1, mmap2) | |||
|
58 | ||||
|
59 | for f in added: | |||
|
60 | lines += dirtywork(f, None, mmap2) | |||
|
61 | ||||
|
62 | for f in removed: | |||
|
63 | lines += dirtywork(f, mmap1, None) | |||
|
64 | ||||
|
65 | for f in deleted: | |||
|
66 | lines += dirtywork(f, mmap1, mmap2) | |||
|
67 | ||||
|
68 | for f in unknown: | |||
|
69 | lines += dirtywork(f, mmap1, mmap2) | |||
|
70 | ||||
|
71 | return (who, lines) | |||
|
72 | ||||
|
73 | def gather_stats(ui, repo, amap, revs=None, progress=False): | |||
|
74 | stats = {} | |||
|
75 | ||||
|
76 | cl = repo.changelog | |||
|
77 | ||||
|
78 | if not revs: | |||
|
79 | revs = range(0, cl.count()) | |||
|
80 | ||||
|
81 | nr_revs = len(revs) | |||
|
82 | cur_rev = 0 | |||
|
83 | ||||
|
84 | for rev in revs: | |||
|
85 | cur_rev += 1 # next revision | |||
|
86 | ||||
|
87 | node2 = cl.node(rev) | |||
|
88 | node1 = cl.parents(node2)[0] | |||
|
89 | ||||
|
90 | if cl.parents(node2)[1] != node.nullid: | |||
|
91 | ui.note(_('Revision %d is a merge, ignoring...\n') % (rev,)) | |||
|
92 | continue | |||
|
93 | ||||
|
94 | who, lines = __gather(ui, repo, node1, node2) | |||
|
95 | ||||
|
96 | # remap the owner if possible | |||
|
97 | if amap.has_key(who): | |||
|
98 | ui.note("using '%s' alias for '%s'\n" % (amap[who], who)) | |||
|
99 | who = amap[who] | |||
|
100 | ||||
|
101 | if not stats.has_key(who): | |||
|
102 | stats[who] = 0 | |||
|
103 | stats[who] += lines | |||
|
104 | ||||
|
105 | ui.note("rev %d: %d lines by %s\n" % (rev, lines, who)) | |||
|
106 | ||||
|
107 | if progress: | |||
|
108 | if int(100.0*(cur_rev - 1)/nr_revs) < int(100.0*cur_rev/nr_revs): | |||
|
109 | ui.write("%d%%.." % (int(100.0*cur_rev/nr_revs),)) | |||
|
110 | sys.stdout.flush() | |||
|
111 | ||||
|
112 | if progress: | |||
|
113 | ui.write("done\n") | |||
|
114 | sys.stdout.flush() | |||
|
115 | ||||
|
116 | return stats | |||
|
117 | ||||
|
118 | def churn(ui, repo, **opts): | |||
|
119 | "Graphs the number of lines changed" | |||
|
120 | ||||
|
121 | def pad(s, l): | |||
|
122 | if len(s) < l: | |||
|
123 | return s + " " * (l-len(s)) | |||
|
124 | return s[0:l] | |||
|
125 | ||||
|
126 | def graph(n, maximum, width, char): | |||
|
127 | n = int(n * width / float(maximum)) | |||
|
128 | ||||
|
129 | return char * (n) | |||
|
130 | ||||
|
131 | def get_aliases(f): | |||
|
132 | aliases = {} | |||
|
133 | ||||
|
134 | for l in f.readlines(): | |||
|
135 | l = l.strip() | |||
|
136 | alias, actual = l.split(" ") | |||
|
137 | aliases[alias] = actual | |||
|
138 | ||||
|
139 | return aliases | |||
|
140 | ||||
|
141 | amap = {} | |||
|
142 | aliases = opts.get('aliases') | |||
|
143 | if aliases: | |||
|
144 | try: | |||
|
145 | f = open(aliases,"r") | |||
|
146 | except OSError, e: | |||
|
147 | print "Error: " + e | |||
|
148 | return | |||
|
149 | ||||
|
150 | amap = get_aliases(f) | |||
|
151 | f.close() | |||
|
152 | ||||
|
153 | revs = [int(r) for r in cmdutil.revrange(ui, repo, opts['rev'])] | |||
|
154 | revs.sort() | |||
|
155 | stats = gather_stats(ui, repo, amap, revs, opts.get('progress')) | |||
|
156 | ||||
|
157 | # make a list of tuples (name, lines) and sort it in descending order | |||
|
158 | ordered = stats.items() | |||
|
159 | ordered.sort(lambda x, y: cmp(y[1], x[1])) | |||
|
160 | ||||
|
161 | maximum = ordered[0][1] | |||
|
162 | ||||
|
163 | ui.note("Assuming 80 character terminal\n") | |||
|
164 | width = 80 - 1 | |||
|
165 | ||||
|
166 | for i in ordered: | |||
|
167 | person = i[0] | |||
|
168 | lines = i[1] | |||
|
169 | print "%s %6d %s" % (pad(person, 20), lines, | |||
|
170 | graph(lines, maximum, width - 20 - 1 - 6 - 2 - 2, '*')) | |||
|
171 | ||||
|
172 | cmdtable = { | |||
|
173 | "churn": | |||
|
174 | (churn, | |||
|
175 | [('r', 'rev', [], _('limit statistics to the specified revisions')), | |||
|
176 | ('', 'aliases', '', _('file with email aliases')), | |||
|
177 | ('', 'progress', None, _('show progress'))], | |||
|
178 | 'hg churn [-r revision range] [-a file] [--progress]'), | |||
|
179 | } |
@@ -0,0 +1,9 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | echo 'syntax error' > badext.py | |||
|
4 | abspath=`pwd`/badext.py | |||
|
5 | ||||
|
6 | echo '[extensions]' >> $HGRCPATH | |||
|
7 | echo "badext = $abspath" >> $HGRCPATH | |||
|
8 | ||||
|
9 | hg -q help help |
@@ -0,0 +1,4 b'' | |||||
|
1 | *** failed to import extension badext: invalid syntax (badext.py, line 1) | |||
|
2 | hg help [COMMAND] | |||
|
3 | ||||
|
4 | show help for a command, extension, or list of commands |
@@ -0,0 +1,34 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | # | |||
|
3 | # test for branch handling | |||
|
4 | # | |||
|
5 | # XXX: need more tests | |||
|
6 | ||||
|
7 | hg init | |||
|
8 | echo a > a | |||
|
9 | echo b > b | |||
|
10 | hg ci -A -m 0 -d "1000000 0" | |||
|
11 | echo aa > a | |||
|
12 | echo bb > b | |||
|
13 | hg ci -m 1 -d "1000000 0" | |||
|
14 | hg tag -l foo | |||
|
15 | hg update 0 | |||
|
16 | hg parents -b | |||
|
17 | ||||
|
18 | # test update | |||
|
19 | hg update -b foo | |||
|
20 | hg parents | |||
|
21 | ||||
|
22 | # test merge | |||
|
23 | hg update 0 | |||
|
24 | echo c > c | |||
|
25 | hg ci -A -m 0.0 -d "1000000 0" | |||
|
26 | hg merge -b foo | |||
|
27 | hg parents -b | |||
|
28 | ||||
|
29 | # re-test with more branches | |||
|
30 | hg update -C 0 | |||
|
31 | echo d > d | |||
|
32 | hg ci -A -m 0.0 -d "1000000 0" | |||
|
33 | hg merge -b foo | |||
|
34 | hg parents -b |
@@ -0,0 +1,55 b'' | |||||
|
1 | adding a | |||
|
2 | adding b | |||
|
3 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
4 | changeset: 0:b544c4ac4389 | |||
|
5 | user: test | |||
|
6 | date: Mon Jan 12 13:46:40 1970 +0000 | |||
|
7 | summary: 0 | |||
|
8 | ||||
|
9 | Using head f4ac749470f2 for branch foo | |||
|
10 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
11 | changeset: 1:f4ac749470f2 | |||
|
12 | tag: foo | |||
|
13 | tag: tip | |||
|
14 | user: test | |||
|
15 | date: Mon Jan 12 13:46:40 1970 +0000 | |||
|
16 | summary: 1 | |||
|
17 | ||||
|
18 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
19 | adding c | |||
|
20 | Using head f4ac749470f2 for branch foo | |||
|
21 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
22 | (branch merge, don't forget to commit) | |||
|
23 | changeset: 2:1505d56ee00e | |||
|
24 | tag: tip | |||
|
25 | parent: 0:b544c4ac4389 | |||
|
26 | user: test | |||
|
27 | date: Mon Jan 12 13:46:40 1970 +0000 | |||
|
28 | summary: 0.0 | |||
|
29 | ||||
|
30 | changeset: 1:f4ac749470f2 | |||
|
31 | tag: foo | |||
|
32 | branch: foo | |||
|
33 | user: test | |||
|
34 | date: Mon Jan 12 13:46:40 1970 +0000 | |||
|
35 | summary: 1 | |||
|
36 | ||||
|
37 | 2 files updated, 0 files merged, 1 files removed, 0 files unresolved | |||
|
38 | adding d | |||
|
39 | Using head f4ac749470f2 for branch foo | |||
|
40 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
41 | (branch merge, don't forget to commit) | |||
|
42 | changeset: 3:53b72df12ae5 | |||
|
43 | tag: tip | |||
|
44 | parent: 0:b544c4ac4389 | |||
|
45 | user: test | |||
|
46 | date: Mon Jan 12 13:46:40 1970 +0000 | |||
|
47 | summary: 0.0 | |||
|
48 | ||||
|
49 | changeset: 1:f4ac749470f2 | |||
|
50 | tag: foo | |||
|
51 | branch: foo | |||
|
52 | user: test | |||
|
53 | date: Mon Jan 12 13:46:40 1970 +0000 | |||
|
54 | summary: 1 | |||
|
55 |
@@ -0,0 +1,35 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | echo "[extensions]" >> $HGRCPATH | |||
|
4 | echo "mq=" >> $HGRCPATH | |||
|
5 | ||||
|
6 | hg init a | |||
|
7 | cd a | |||
|
8 | ||||
|
9 | echo 'base' > base | |||
|
10 | hg ci -Ambase -d '1 0' | |||
|
11 | ||||
|
12 | hg qnew a | |||
|
13 | hg qnew b | |||
|
14 | hg qnew c | |||
|
15 | ||||
|
16 | hg qdel c | |||
|
17 | hg qpop | |||
|
18 | hg qdel c | |||
|
19 | hg qseries | |||
|
20 | ls .hg/patches | |||
|
21 | hg qpop | |||
|
22 | hg qdel -k b | |||
|
23 | ls .hg/patches | |||
|
24 | hg qdel -f a | |||
|
25 | hg qapplied | |||
|
26 | hg log --template '{rev} {desc}\n' | |||
|
27 | ||||
|
28 | hg qnew d | |||
|
29 | hg qnew e | |||
|
30 | hg qnew f | |||
|
31 | ||||
|
32 | hg qdel -f e | |||
|
33 | hg qdel -f d e | |||
|
34 | hg qapplied | |||
|
35 | hg log --template '{rev} {desc}\n' |
@@ -0,0 +1,23 b'' | |||||
|
1 | adding base | |||
|
2 | abort: cannot delete applied patch c | |||
|
3 | Now at: b | |||
|
4 | a | |||
|
5 | b | |||
|
6 | a | |||
|
7 | b | |||
|
8 | series | |||
|
9 | status | |||
|
10 | Now at: a | |||
|
11 | a | |||
|
12 | b | |||
|
13 | series | |||
|
14 | status | |||
|
15 | 1 New patch: a | |||
|
16 | 0 base | |||
|
17 | abort: patch e not at base | |||
|
18 | f | |||
|
19 | 4 New patch: f | |||
|
20 | 3 New patch: e | |||
|
21 | 2 New patch: d | |||
|
22 | 1 New patch: a | |||
|
23 | 0 base |
@@ -0,0 +1,25 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | echo "[extensions]" >> $HGRCPATH | |||
|
4 | echo "mq=" >> $HGRCPATH | |||
|
5 | ||||
|
6 | hg init a | |||
|
7 | cd a | |||
|
8 | ||||
|
9 | echo 'base' > base | |||
|
10 | hg ci -Ambase -d '1 0' | |||
|
11 | ||||
|
12 | hg qnew -mmqbase mqbase | |||
|
13 | hg qrename mqbase renamed | |||
|
14 | mkdir .hg/patches/foo | |||
|
15 | hg qrename renamed foo | |||
|
16 | hg qseries | |||
|
17 | ls .hg/patches/foo | |||
|
18 | mkdir .hg/patches/bar | |||
|
19 | hg qrename foo/renamed bar | |||
|
20 | hg qseries | |||
|
21 | ls .hg/patches/bar | |||
|
22 | hg qrename bar/renamed baz | |||
|
23 | hg qseries | |||
|
24 | ls .hg/patches/baz | |||
|
25 |
@@ -0,0 +1,7 b'' | |||||
|
1 | adding base | |||
|
2 | foo/renamed | |||
|
3 | renamed | |||
|
4 | bar/renamed | |||
|
5 | renamed | |||
|
6 | baz | |||
|
7 | .hg/patches/baz |
@@ -30,15 +30,29 b' proc getcommits {rargs} {' | |||||
30 | set startmsecs [clock clicks -milliseconds] |
|
30 | set startmsecs [clock clicks -milliseconds] | |
31 | set nextupdate [expr $startmsecs + 100] |
|
31 | set nextupdate [expr $startmsecs + 100] | |
32 | set ncmupdate 1 |
|
32 | set ncmupdate 1 | |
|
33 | set limit 0 | |||
|
34 | set revargs {} | |||
|
35 | for {set i 0} {$i < [llength $rargs]} {incr i} { | |||
|
36 | set opt [lindex $rargs $i] | |||
|
37 | if {$opt == "--limit"} { | |||
|
38 | incr i | |||
|
39 | set limit [lindex $rargs $i] | |||
|
40 | } else { | |||
|
41 | lappend revargs $opt | |||
|
42 | } | |||
|
43 | } | |||
33 | if [catch { |
|
44 | if [catch { | |
34 | set parse_args [concat --default HEAD $rargs] |
|
45 | set parse_args [concat --default HEAD $revargs] | |
35 | set parsed_args [split [eval exec hg debug-rev-parse $parse_args] "\n"] |
|
46 | set parsed_args [split [eval exec hg debug-rev-parse $parse_args] "\n"] | |
36 | }] { |
|
47 | } err] { | |
37 | # if git-rev-parse failed for some reason... |
|
48 | # if git-rev-parse failed for some reason... | |
38 | if {$rargs == {}} { |
|
49 | if {$rargs == {}} { | |
39 | set rargs HEAD |
|
50 | set revargs HEAD | |
40 | } |
|
51 | } | |
41 | set parsed_args $rargs |
|
52 | set parsed_args $revargs | |
|
53 | } | |||
|
54 | if {$limit > 0} { | |||
|
55 | set parsed_args [concat -n $limit $parsed_args] | |||
42 | } |
|
56 | } | |
43 | if [catch { |
|
57 | if [catch { | |
44 | set commfd [open "|hg debug-rev-list --header --topo-order --parents $parsed_args" r] |
|
58 | set commfd [open "|hg debug-rev-list --header --topo-order --parents $parsed_args" r] | |
@@ -100,7 +114,7 b' to allow selection of commits to be disp' | |||||
100 | set ids [string range $cmit 0 [expr {$j - 1}]] |
|
114 | set ids [string range $cmit 0 [expr {$j - 1}]] | |
101 | set ok 1 |
|
115 | set ok 1 | |
102 | foreach id $ids { |
|
116 | foreach id $ids { | |
103 |
if {![regexp {^[0-9a-f]{ |
|
117 | if {![regexp {^[0-9a-f]{12}$} $id]} { | |
104 | set ok 0 |
|
118 | set ok 0 | |
105 | break |
|
119 | break | |
106 | } |
|
120 | } | |
@@ -176,6 +190,7 b' proc parsecommit {id contents listed old' | |||||
176 | set audate {} |
|
190 | set audate {} | |
177 | set comname {} |
|
191 | set comname {} | |
178 | set comdate {} |
|
192 | set comdate {} | |
|
193 | set rev {} | |||
179 | if {![info exists nchildren($id)]} { |
|
194 | if {![info exists nchildren($id)]} { | |
180 | set children($id) {} |
|
195 | set children($id) {} | |
181 | set nchildren($id) 0 |
|
196 | set nchildren($id) 0 | |
@@ -209,6 +224,8 b' proc parsecommit {id contents listed old' | |||||
209 | set x [expr {[llength $line] - 2}] |
|
224 | set x [expr {[llength $line] - 2}] | |
210 | set comdate [lindex $line $x] |
|
225 | set comdate [lindex $line $x] | |
211 | set comname [join [lrange $line 1 [expr {$x - 1}]]] |
|
226 | set comname [join [lrange $line 1 [expr {$x - 1}]]] | |
|
227 | } elseif {$tag == "revision"} { | |||
|
228 | set rev [lindex $line 1] | |||
212 | } |
|
229 | } | |
213 | } |
|
230 | } | |
214 | } else { |
|
231 | } else { | |
@@ -233,7 +250,7 b' proc parsecommit {id contents listed old' | |||||
233 | set comdate [clock format $comdate -format "%Y-%m-%d %H:%M:%S"] |
|
250 | set comdate [clock format $comdate -format "%Y-%m-%d %H:%M:%S"] | |
234 | } |
|
251 | } | |
235 | set commitinfo($id) [list $headline $auname $audate \ |
|
252 | set commitinfo($id) [list $headline $auname $audate \ | |
236 | $comname $comdate $comment] |
|
253 | $comname $comdate $comment $rev] | |
237 | } |
|
254 | } | |
238 |
|
255 | |||
239 | proc readrefs {} { |
|
256 | proc readrefs {} { | |
@@ -261,7 +278,7 b' proc readotherrefs {base dname excl} {' | |||||
261 | catch { |
|
278 | catch { | |
262 | set fd [open $f r] |
|
279 | set fd [open $f r] | |
263 | set line [read $fd 40] |
|
280 | set line [read $fd 40] | |
264 |
if {[regexp {^[0-9a-f]{ |
|
281 | if {[regexp {^[0-9a-f]{12}} $line id]} { | |
265 | set name "$dname[file tail $f]" |
|
282 | set name "$dname[file tail $f]" | |
266 | set otherrefids($name) $id |
|
283 | set otherrefids($name) $id | |
267 | lappend idotherrefs($id) $name |
|
284 | lappend idotherrefs($id) $name | |
@@ -1743,7 +1760,7 b' proc readfindproc {} {' | |||||
1743 | } |
|
1760 | } | |
1744 | return |
|
1761 | return | |
1745 | } |
|
1762 | } | |
1746 |
if {![regexp {^[0-9a-f]{ |
|
1763 | if {![regexp {^[0-9a-f]{12}} $line id]} { | |
1747 | error_popup "Can't parse git-diff-tree output: $line" |
|
1764 | error_popup "Can't parse git-diff-tree output: $line" | |
1748 | stopfindproc |
|
1765 | stopfindproc | |
1749 | return |
|
1766 | return | |
@@ -1856,7 +1873,7 b' proc readfilediffs {df} {' | |||||
1856 | } |
|
1873 | } | |
1857 | return |
|
1874 | return | |
1858 | } |
|
1875 | } | |
1859 |
if {[regexp {^([0-9a-f]{ |
|
1876 | if {[regexp {^([0-9a-f]{12}) \(from ([0-9a-f]{12})\)} $line match id p]} { | |
1860 | # start of a new string of diffs |
|
1877 | # start of a new string of diffs | |
1861 | donefilediff |
|
1878 | donefilediff | |
1862 | set fdiffids [list $id $p] |
|
1879 | set fdiffids [list $id $p] | |
@@ -2002,8 +2019,9 b' proc commit_descriptor {p} {' | |||||
2002 | set l "..." |
|
2019 | set l "..." | |
2003 | if {[info exists commitinfo($p)]} { |
|
2020 | if {[info exists commitinfo($p)]} { | |
2004 | set l [lindex $commitinfo($p) 0] |
|
2021 | set l [lindex $commitinfo($p) 0] | |
|
2022 | set r [lindex $commitinfo($p) 6] | |||
2005 | } |
|
2023 | } | |
2006 | return "$p ($l)" |
|
2024 | return "$r:$p ($l)" | |
2007 | } |
|
2025 | } | |
2008 |
|
2026 | |||
2009 | # append some text to the ctext widget, and make any SHA1 ID |
|
2027 | # append some text to the ctext widget, and make any SHA1 ID | |
@@ -2014,7 +2032,7 b' proc appendwithlinks {text} {' | |||||
2014 | set start [$ctext index "end - 1c"] |
|
2032 | set start [$ctext index "end - 1c"] | |
2015 | $ctext insert end $text |
|
2033 | $ctext insert end $text | |
2016 | $ctext insert end "\n" |
|
2034 | $ctext insert end "\n" | |
2017 |
set links [regexp -indices -all -inline {[0-9a-f]{ |
|
2035 | set links [regexp -indices -all -inline {[0-9a-f]{12}} $text] | |
2018 | foreach l $links { |
|
2036 | foreach l $links { | |
2019 | set s [lindex $l 0] |
|
2037 | set s [lindex $l 0] | |
2020 | set e [lindex $l 1] |
|
2038 | set e [lindex $l 1] | |
@@ -2107,6 +2125,7 b' proc selectline {l isnew} {' | |||||
2107 | $ctext mark set fmark.0 0.0 |
|
2125 | $ctext mark set fmark.0 0.0 | |
2108 | $ctext mark gravity fmark.0 left |
|
2126 | $ctext mark gravity fmark.0 left | |
2109 | set info $commitinfo($id) |
|
2127 | set info $commitinfo($id) | |
|
2128 | $ctext insert end "Revision: [lindex $info 6]\n" | |||
2110 | $ctext insert end "Author: [lindex $info 1] [lindex $info 2]\n" |
|
2129 | $ctext insert end "Author: [lindex $info 1] [lindex $info 2]\n" | |
2111 | $ctext insert end "Committer: [lindex $info 3] [lindex $info 4]\n" |
|
2130 | $ctext insert end "Committer: [lindex $info 3] [lindex $info 4]\n" | |
2112 | if {[info exists idtags($id)]} { |
|
2131 | if {[info exists idtags($id)]} { |
@@ -193,6 +193,10 b' FILES' | |||||
193 | global /etc/mercurial/hgrc configuration. See hgrc(5) for details of |
|
193 | global /etc/mercurial/hgrc configuration. See hgrc(5) for details of | |
194 | the contents and format of these files. |
|
194 | the contents and format of these files. | |
195 |
|
195 | |||
|
196 | Some commands (e.g. revert) produce backup files ending in .orig, if | |||
|
197 | the .orig file already exists and is not tracked by Mercurial, it | |||
|
198 | will be overwritten. | |||
|
199 | ||||
196 | BUGS |
|
200 | BUGS | |
197 | ---- |
|
201 | ---- | |
198 | Probably lots, please post them to the mailing list (See Resources below) |
|
202 | Probably lots, please post them to the mailing list (See Resources below) |
@@ -133,6 +133,21 b' decode/encode::' | |||||
133 | # them to the working dir |
|
133 | # them to the working dir | |
134 | **.txt = tempfile: unix2dos -n INFILE OUTFILE |
|
134 | **.txt = tempfile: unix2dos -n INFILE OUTFILE | |
135 |
|
135 | |||
|
136 | defaults:: | |||
|
137 | Use the [defaults] section to define command defaults, i.e. the | |||
|
138 | default options/arguments to pass to the specified commands. | |||
|
139 | ||||
|
140 | The following example makes 'hg log' run in verbose mode, and | |||
|
141 | 'hg status' show only the modified files, by default. | |||
|
142 | ||||
|
143 | [defaults] | |||
|
144 | log = -v | |||
|
145 | status = -m | |||
|
146 | ||||
|
147 | The actual commands, instead of their aliases, must be used when | |||
|
148 | defining command defaults. The command defaults will also be | |||
|
149 | applied to the aliases of the commands defined. | |||
|
150 | ||||
136 | email:: |
|
151 | email:: | |
137 | Settings for extensions that send email messages. |
|
152 | Settings for extensions that send email messages. | |
138 | from;; |
|
153 | from;; |
@@ -41,13 +41,15 b' HGTMP="${TMPDIR-/tmp}/hgeditor.$RANDOM.$' | |||||
41 |
|
41 | |||
42 | cat "$1" > "$HGTMP/msg" |
|
42 | cat "$1" > "$HGTMP/msg" | |
43 |
|
43 | |||
44 | CHECKSUM=`md5sum "$HGTMP/msg"` |
|
44 | MD5=$(which md5sum 2>/dev/null) || \ | |
|
45 | MD5=$(which md5 2>/dev/null) | |||
|
46 | [ -x "${MD5}" ] && CHECKSUM=`${MD5} "$HGTMP/msg"` | |||
45 | if [ -s "$HGTMP/diff" ]; then |
|
47 | if [ -s "$HGTMP/diff" ]; then | |
46 | $EDITOR "$HGTMP/msg" "$HGTMP/diff" || exit $? |
|
48 | $EDITOR "$HGTMP/msg" "$HGTMP/diff" || exit $? | |
47 | else |
|
49 | else | |
48 | $EDITOR "$HGTMP/msg" || exit $? |
|
50 | $EDITOR "$HGTMP/msg" || exit $? | |
49 | fi |
|
51 | fi | |
50 |
echo "$CHECKSUM" | |
|
52 | [ -x "${MD5}" ] && (echo "$CHECKSUM" | ${MD5} -c >/dev/null 2>&1 && exit 13) | |
51 |
|
53 | |||
52 | mv "$HGTMP/msg" "$1" |
|
54 | mv "$HGTMP/msg" "$1" | |
53 |
|
55 |
@@ -60,8 +60,8 b' class checker(object):' | |||||
60 | return None, False |
|
60 | return None, False | |
61 |
|
61 | |||
62 | thisuser = self.getuser() |
|
62 | thisuser = self.getuser() | |
63 | pats = [pat for pat, user in self.ui.configitems(key) |
|
63 | pats = [pat for pat, users in self.ui.configitems(key) | |
64 | if user == thisuser] |
|
64 | if thisuser in users.replace(',', ' ').split()] | |
65 | self.ui.debug(_('acl: %s enabled, %d entries for user %s\n') % |
|
65 | self.ui.debug(_('acl: %s enabled, %d entries for user %s\n') % | |
66 | (key, len(pats), thisuser)) |
|
66 | (key, len(pats), thisuser)) | |
67 | if pats: |
|
67 | if pats: |
@@ -45,7 +45,7 b'' | |||||
45 | from mercurial.demandload import demandload |
|
45 | from mercurial.demandload import demandload | |
46 | from mercurial.i18n import gettext as _ |
|
46 | from mercurial.i18n import gettext as _ | |
47 | from mercurial.node import * |
|
47 | from mercurial.node import * | |
48 |
demandload(globals(), 'mercurial:c |
|
48 | demandload(globals(), 'mercurial:cmdutil,util os shutil tempfile') | |
49 |
|
49 | |||
50 | def dodiff(ui, repo, diffcmd, diffopts, pats, opts): |
|
50 | def dodiff(ui, repo, diffcmd, diffopts, pats, opts): | |
51 | def snapshot_node(files, node): |
|
51 | def snapshot_node(files, node): | |
@@ -90,7 +90,7 b' def dodiff(ui, repo, diffcmd, diffopts, ' | |||||
90 | fp.write(chunk) |
|
90 | fp.write(chunk) | |
91 | return dirname |
|
91 | return dirname | |
92 |
|
92 | |||
93 |
node1, node2 = c |
|
93 | node1, node2 = cmdutil.revpair(ui, repo, opts['rev']) | |
94 | files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) |
|
94 | files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) | |
95 | modified, added, removed, deleted, unknown = repo.status( |
|
95 | modified, added, removed, deleted, unknown = repo.status( | |
96 | node1, node2, files, match=matchfn)[:5] |
|
96 | node1, node2, files, match=matchfn)[:5] | |
@@ -105,8 +105,7 b' def dodiff(ui, repo, diffcmd, diffopts, ' | |||||
105 | else: |
|
105 | else: | |
106 | dir2 = snapshot_wdir(modified + added) |
|
106 | dir2 = snapshot_wdir(modified + added) | |
107 | cmdline = ('%s %s %s %s' % |
|
107 | cmdline = ('%s %s %s %s' % | |
108 | (util.shellquote(diffcmd), |
|
108 | (util.shellquote(diffcmd), ' '.join(diffopts), | |
109 | ' '.join(map(util.shellquote, diffopts)), |
|
|||
110 | util.shellquote(dir1), util.shellquote(dir2))) |
|
109 | util.shellquote(dir1), util.shellquote(dir2))) | |
111 | ui.debug('running %r in %s\n' % (cmdline, tmproot)) |
|
110 | ui.debug('running %r in %s\n' % (cmdline, tmproot)) | |
112 | util.system(cmdline, cwd=tmproot) |
|
111 | util.system(cmdline, cwd=tmproot) |
@@ -7,92 +7,39 b'' | |||||
7 |
|
7 | |||
8 | from mercurial.demandload import * |
|
8 | from mercurial.demandload import * | |
9 | demandload(globals(), 'time sys signal os') |
|
9 | demandload(globals(), 'time sys signal os') | |
10 |
demandload(globals(), 'mercurial:hg, |
|
10 | demandload(globals(), 'mercurial:hg,fancyopts,commands,ui,util,patch,revlog') | |
11 |
|
||||
12 | def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always, |
|
|||
13 | changes=None, text=False): |
|
|||
14 | def date(c): |
|
|||
15 | return time.asctime(time.gmtime(c[2][0])) |
|
|||
16 |
|
||||
17 | if not changes: |
|
|||
18 | changes = repo.status(node1, node2, files, match=match)[:5] |
|
|||
19 | modified, added, removed, deleted, unknown = changes |
|
|||
20 | if files: |
|
|||
21 | modified, added, removed = map(lambda x: filterfiles(files, x), |
|
|||
22 | (modified, added, removed)) |
|
|||
23 |
|
||||
24 | if not modified and not added and not removed: |
|
|||
25 | return |
|
|||
26 |
|
||||
27 | if node2: |
|
|||
28 | change = repo.changelog.read(node2) |
|
|||
29 | mmap2 = repo.manifest.read(change[0]) |
|
|||
30 | date2 = date(change) |
|
|||
31 | def read(f): |
|
|||
32 | return repo.file(f).read(mmap2[f]) |
|
|||
33 | else: |
|
|||
34 | date2 = time.asctime() |
|
|||
35 | if not node1: |
|
|||
36 | node1 = repo.dirstate.parents()[0] |
|
|||
37 | def read(f): |
|
|||
38 | return repo.wfile(f).read() |
|
|||
39 |
|
11 | |||
40 | change = repo.changelog.read(node1) |
|
12 | def difftree(ui, repo, node1=None, node2=None, *files, **opts): | |
41 | mmap = repo.manifest.read(change[0]) |
|
|||
42 | date1 = date(change) |
|
|||
43 |
|
||||
44 | for f in modified: |
|
|||
45 | to = None |
|
|||
46 | if f in mmap: |
|
|||
47 | to = repo.file(f).read(mmap[f]) |
|
|||
48 | tn = read(f) |
|
|||
49 | opts = mdiff.diffopts() |
|
|||
50 | opts.text = text |
|
|||
51 | fp.write("diff --git a/%s b/%s\n" % (f, f)) |
|
|||
52 | fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, opts=opts)) |
|
|||
53 | for f in added: |
|
|||
54 | to = None |
|
|||
55 | tn = read(f) |
|
|||
56 | fp.write("diff --git /dev/null b/%s\n" % (f)) |
|
|||
57 | fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, opts=opts)) |
|
|||
58 | for f in removed: |
|
|||
59 | to = repo.file(f).read(mmap[f]) |
|
|||
60 | tn = None |
|
|||
61 | fp.write("diff --git a/%s /dev/null\n" % (f)) |
|
|||
62 | fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, opts=opts)) |
|
|||
63 |
|
||||
64 | def difftree(ui, repo, node1=None, node2=None, **opts): |
|
|||
65 | """diff trees from two commits""" |
|
13 | """diff trees from two commits""" | |
66 | def __difftree(repo, node1, node2): |
|
14 | def __difftree(repo, node1, node2, files=[]): | |
67 | def date(c): |
|
|||
68 | return time.asctime(time.gmtime(c[2][0])) |
|
|||
69 |
|
||||
70 | if node2: |
|
15 | if node2: | |
71 | change = repo.changelog.read(node2) |
|
16 | change = repo.changelog.read(node2) | |
72 | mmap2 = repo.manifest.read(change[0]) |
|
17 | mmap2 = repo.manifest.read(change[0]) | |
73 |
|
|
18 | status = repo.status(node1, node2, files=files)[:5] | |
74 | def read(f): return repo.file(f).read(mmap2[f]) |
|
19 | modified, added, removed, deleted, unknown = status | |
75 | date2 = date(change) |
|
|||
76 | else: |
|
20 | else: | |
77 | date2 = time.asctime() |
|
21 | status = repo.status(node1, files=files)[:5] | |
78 |
modified, added, removed, deleted, unknown = |
|
22 | modified, added, removed, deleted, unknown = status | |
79 | if not node1: |
|
23 | if not node1: | |
80 | node1 = repo.dirstate.parents()[0] |
|
24 | node1 = repo.dirstate.parents()[0] | |
81 | def read(f): return file(os.path.join(repo.root, f)).read() |
|
|||
82 |
|
25 | |||
83 | change = repo.changelog.read(node1) |
|
26 | change = repo.changelog.read(node1) | |
84 | mmap = repo.manifest.read(change[0]) |
|
27 | mmap = repo.manifest.read(change[0]) | |
85 | date1 = date(change) |
|
28 | empty = hg.short(hg.nullid) | |
86 | empty = "0" * 40; |
|
|||
87 |
|
29 | |||
88 | for f in modified: |
|
30 | for f in modified: | |
89 | # TODO get file permissions |
|
31 | # TODO get file permissions | |
90 |
print ":100664 100664 %s %s M\t%s\t%s" % (hg. |
|
32 | print ":100664 100664 %s %s M\t%s\t%s" % (hg.short(mmap[f]), | |
91 |
hg. |
|
33 | hg.short(mmap2[f]), | |
|
34 | f, f) | |||
92 | for f in added: |
|
35 | for f in added: | |
93 |
print ":000000 100664 %s %s N\t%s\t%s" % (empty, |
|
36 | print ":000000 100664 %s %s N\t%s\t%s" % (empty, | |
|
37 | hg.short(mmap2[f]), | |||
|
38 | f, f) | |||
94 | for f in removed: |
|
39 | for f in removed: | |
95 |
print ":100664 000000 %s %s D\t%s\t%s" % (hg. |
|
40 | print ":100664 000000 %s %s D\t%s\t%s" % (hg.short(mmap[f]), | |
|
41 | empty, | |||
|
42 | f, f) | |||
96 | ## |
|
43 | ## | |
97 |
|
44 | |||
98 | while True: |
|
45 | while True: | |
@@ -115,20 +62,22 b' def difftree(ui, repo, node1=None, node2' | |||||
115 | if opts['patch']: |
|
62 | if opts['patch']: | |
116 | if opts['pretty']: |
|
63 | if opts['pretty']: | |
117 | catcommit(repo, node2, "") |
|
64 | catcommit(repo, node2, "") | |
118 |
|
|
65 | patch.diff(repo, node1, node2, | |
|
66 | files=files, | |||
|
67 | opts=patch.diffopts(ui, {'git': True})) | |||
119 | else: |
|
68 | else: | |
120 | __difftree(repo, node1, node2) |
|
69 | __difftree(repo, node1, node2, files=files) | |
121 | if not opts['stdin']: |
|
70 | if not opts['stdin']: | |
122 | break |
|
71 | break | |
123 |
|
72 | |||
124 | def catcommit(repo, n, prefix, changes=None): |
|
73 | def catcommit(repo, n, prefix, changes=None): | |
125 | nlprefix = '\n' + prefix; |
|
74 | nlprefix = '\n' + prefix; | |
126 | (p1, p2) = repo.changelog.parents(n) |
|
75 | (p1, p2) = repo.changelog.parents(n) | |
127 |
(h, h1, h2) = map(hg. |
|
76 | (h, h1, h2) = map(hg.short, (n, p1, p2)) | |
128 | (i1, i2) = map(repo.changelog.rev, (p1, p2)) |
|
77 | (i1, i2) = map(repo.changelog.rev, (p1, p2)) | |
129 | if not changes: |
|
78 | if not changes: | |
130 | changes = repo.changelog.read(n) |
|
79 | changes = repo.changelog.read(n) | |
131 |
print "tree %s" % (hg. |
|
80 | print "tree %s" % (hg.short(changes[0])) | |
132 | if i1 != -1: print "parent %s" % (h1) |
|
81 | if i1 != -1: print "parent %s" % (h1) | |
133 | if i2 != -1: print "parent %s" % (h2) |
|
82 | if i2 != -1: print "parent %s" % (h2) | |
134 | date_ar = changes[2] |
|
83 | date_ar = changes[2] | |
@@ -141,6 +90,7 b' def catcommit(repo, n, prefix, changes=N' | |||||
141 |
|
90 | |||
142 | print "author %s %s %s" % (changes[1], date, date_ar[1]) |
|
91 | print "author %s %s %s" % (changes[1], date, date_ar[1]) | |
143 | print "committer %s %s %s" % (committer, date, date_ar[1]) |
|
92 | print "committer %s %s %s" % (committer, date, date_ar[1]) | |
|
93 | print "revision %d" % repo.changelog.rev(n) | |||
144 | print "" |
|
94 | print "" | |
145 | if prefix != "": |
|
95 | if prefix != "": | |
146 | print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip()) |
|
96 | print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip()) | |
@@ -154,7 +104,7 b' def base(ui, repo, node1, node2):' | |||||
154 | node1 = repo.lookup(node1) |
|
104 | node1 = repo.lookup(node1) | |
155 | node2 = repo.lookup(node2) |
|
105 | node2 = repo.lookup(node2) | |
156 | n = repo.changelog.ancestor(node1, node2) |
|
106 | n = repo.changelog.ancestor(node1, node2) | |
157 |
print hg. |
|
107 | print hg.short(n) | |
158 |
|
108 | |||
159 | def catfile(ui, repo, type=None, r=None, **opts): |
|
109 | def catfile(ui, repo, type=None, r=None, **opts): | |
160 | """cat a specific revision""" |
|
110 | """cat a specific revision""" | |
@@ -267,7 +217,6 b' def revtree(args, repo, full="tree", max' | |||||
267 |
|
217 | |||
268 | # walk the repository looking for commits that are in our |
|
218 | # walk the repository looking for commits that are in our | |
269 | # reachability graph |
|
219 | # reachability graph | |
270 | #for i in range(repo.changelog.count()-1, -1, -1): |
|
|||
271 | for i, changes in chlogwalk(): |
|
220 | for i, changes in chlogwalk(): | |
272 | n = repo.changelog.node(i) |
|
221 | n = repo.changelog.node(i) | |
273 | mask = is_reachable(want_sha1, reachable, n) |
|
222 | mask = is_reachable(want_sha1, reachable, n) | |
@@ -276,17 +225,17 b' def revtree(args, repo, full="tree", max' | |||||
276 | if parents: |
|
225 | if parents: | |
277 | pp = repo.changelog.parents(n) |
|
226 | pp = repo.changelog.parents(n) | |
278 | if pp[0] != hg.nullid: |
|
227 | if pp[0] != hg.nullid: | |
279 |
parentstr += " " + hg. |
|
228 | parentstr += " " + hg.short(pp[0]) | |
280 | if pp[1] != hg.nullid: |
|
229 | if pp[1] != hg.nullid: | |
281 |
parentstr += " " + hg. |
|
230 | parentstr += " " + hg.short(pp[1]) | |
282 | if not full: |
|
231 | if not full: | |
283 |
print hg. |
|
232 | print hg.short(n) + parentstr | |
284 |
elif full |
|
233 | elif full == "commit": | |
285 |
print hg. |
|
234 | print hg.short(n) + parentstr | |
286 | catcommit(repo, n, ' ', changes) |
|
235 | catcommit(repo, n, ' ', changes) | |
287 | else: |
|
236 | else: | |
288 | (p1, p2) = repo.changelog.parents(n) |
|
237 | (p1, p2) = repo.changelog.parents(n) | |
289 |
(h, h1, h2) = map(hg. |
|
238 | (h, h1, h2) = map(hg.short, (n, p1, p2)) | |
290 | (i1, i2) = map(repo.changelog.rev, (p1, p2)) |
|
239 | (i1, i2) = map(repo.changelog.rev, (p1, p2)) | |
291 |
|
240 | |||
292 | date = changes[2][0] |
|
241 | date = changes[2][0] | |
@@ -302,6 +251,19 b' def revtree(args, repo, full="tree", max' | |||||
302 | break |
|
251 | break | |
303 | count += 1 |
|
252 | count += 1 | |
304 |
|
253 | |||
|
254 | def revparse(ui, repo, *revs, **opts): | |||
|
255 | """Parse given revisions""" | |||
|
256 | def revstr(rev): | |||
|
257 | if rev == 'HEAD': | |||
|
258 | rev = 'tip' | |||
|
259 | return revlog.hex(repo.lookup(rev)) | |||
|
260 | ||||
|
261 | for r in revs: | |||
|
262 | revrange = r.split(':', 1) | |||
|
263 | ui.write('%s\n' % revstr(revrange[0])) | |||
|
264 | if len(revrange) == 2: | |||
|
265 | ui.write('^%s\n' % revstr(revrange[1])) | |||
|
266 | ||||
305 | # git rev-list tries to order things by date, and has the ability to stop |
|
267 | # git rev-list tries to order things by date, and has the ability to stop | |
306 | # at a given commit without walking the whole repo. TODO add the stop |
|
268 | # at a given commit without walking the whole repo. TODO add the stop | |
307 | # parameter |
|
269 | # parameter | |
@@ -314,23 +276,29 b' def revlist(ui, repo, *revs, **opts):' | |||||
314 | copy = [x for x in revs] |
|
276 | copy = [x for x in revs] | |
315 | revtree(copy, repo, full, opts['max_count'], opts['parents']) |
|
277 | revtree(copy, repo, full, opts['max_count'], opts['parents']) | |
316 |
|
278 | |||
317 | def view(ui, repo, *etc): |
|
279 | def view(ui, repo, *etc, **opts): | |
318 | "start interactive history viewer" |
|
280 | "start interactive history viewer" | |
319 | os.chdir(repo.root) |
|
281 | os.chdir(repo.root) | |
320 | os.system(ui.config("hgk", "path", "hgk") + " " + " ".join(etc)) |
|
282 | optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems()]) | |
|
283 | os.system(ui.config("hgk", "path", "hgk") + " %s %s" % (optstr, " ".join(etc))) | |||
321 |
|
284 | |||
322 | cmdtable = { |
|
285 | cmdtable = { | |
323 |
"view": (view, |
|
286 | "view": (view, | |
|
287 | [('l', 'limit', '', 'limit number of changes displayed')], | |||
|
288 | 'hg view [-l LIMIT] [REVRANGE]'), | |||
324 | "debug-diff-tree": (difftree, [('p', 'patch', None, 'generate patch'), |
|
289 | "debug-diff-tree": (difftree, [('p', 'patch', None, 'generate patch'), | |
325 | ('r', 'recursive', None, 'recursive'), |
|
290 | ('r', 'recursive', None, 'recursive'), | |
326 | ('P', 'pretty', None, 'pretty'), |
|
291 | ('P', 'pretty', None, 'pretty'), | |
327 | ('s', 'stdin', None, 'stdin'), |
|
292 | ('s', 'stdin', None, 'stdin'), | |
328 | ('C', 'copy', None, 'detect copies'), |
|
293 | ('C', 'copy', None, 'detect copies'), | |
329 | ('S', 'search', "", 'search')], |
|
294 | ('S', 'search', "", 'search')], | |
330 | "hg git-diff-tree [options] node1 node2"), |
|
295 | "hg git-diff-tree [options] node1 node2 [files...]"), | |
331 | "debug-cat-file": (catfile, [('s', 'stdin', None, 'stdin')], |
|
296 | "debug-cat-file": (catfile, [('s', 'stdin', None, 'stdin')], | |
332 | "hg debug-cat-file [options] type file"), |
|
297 | "hg debug-cat-file [options] type file"), | |
333 | "debug-merge-base": (base, [], "hg debug-merge-base node node"), |
|
298 | "debug-merge-base": (base, [], "hg debug-merge-base node node"), | |
|
299 | 'debug-rev-parse': (revparse, | |||
|
300 | [('', 'default', '', 'ignored')], | |||
|
301 | "hg debug-rev-parse rev"), | |||
334 | "debug-rev-list": (revlist, [('H', 'header', None, 'header'), |
|
302 | "debug-rev-list": (revlist, [('H', 'header', None, 'header'), | |
335 | ('t', 'topo-order', None, 'topo-order'), |
|
303 | ('t', 'topo-order', None, 'topo-order'), | |
336 | ('p', 'parents', None, 'parents'), |
|
304 | ('p', 'parents', None, 'parents'), |
@@ -40,7 +40,7 b' commands.norepo += " qclone qversion"' | |||||
40 | class statusentry: |
|
40 | class statusentry: | |
41 | def __init__(self, rev, name=None): |
|
41 | def __init__(self, rev, name=None): | |
42 | if not name: |
|
42 | if not name: | |
43 | fields = rev.split(':') |
|
43 | fields = rev.split(':', 1) | |
44 | if len(fields) == 2: |
|
44 | if len(fields) == 2: | |
45 | self.rev, self.name = fields |
|
45 | self.rev, self.name = fields | |
46 | else: |
|
46 | else: | |
@@ -483,24 +483,35 b' class queue:' | |||||
483 | tr.close() |
|
483 | tr.close() | |
484 | return (err, n) |
|
484 | return (err, n) | |
485 |
|
485 | |||
486 |
def delete(self, repo, patches, |
|
486 | def delete(self, repo, patches, opts): | |
487 | realpatches = [] |
|
487 | realpatches = [] | |
|
488 | appliedbase = 0 | |||
|
489 | forget = opts.get('forget') | |||
488 | for patch in patches: |
|
490 | for patch in patches: | |
489 | patch = self.lookup(patch, strict=True) |
|
491 | patch = self.lookup(patch, strict=True) | |
490 | info = self.isapplied(patch) |
|
492 | info = self.isapplied(patch) | |
491 | if info: |
|
493 | if info and not forget: | |
492 | raise util.Abort(_("cannot delete applied patch %s") % patch) |
|
494 | raise util.Abort(_("cannot delete applied patch %s") % patch) | |
493 | if patch not in self.series: |
|
495 | if patch not in self.series: | |
494 | raise util.Abort(_("patch %s not in series file") % patch) |
|
496 | raise util.Abort(_("patch %s not in series file") % patch) | |
|
497 | if forget: | |||
|
498 | if not info: | |||
|
499 | raise util.Abort(_("cannot forget unapplied patch %s") % patch) | |||
|
500 | if info[0] != appliedbase: | |||
|
501 | raise util.Abort(_("patch %s not at base") % patch) | |||
|
502 | appliedbase += 1 | |||
495 | realpatches.append(patch) |
|
503 | realpatches.append(patch) | |
496 |
|
504 | |||
497 | if not keep: |
|
505 | if not opts.get('keep'): | |
498 | r = self.qrepo() |
|
506 | r = self.qrepo() | |
499 | if r: |
|
507 | if r: | |
500 | r.remove(realpatches, True) |
|
508 | r.remove(realpatches, True) | |
501 | else: |
|
509 | else: | |
502 | os.unlink(self.join(patch)) |
|
510 | os.unlink(self.join(patch)) | |
503 |
|
511 | |||
|
512 | if forget: | |||
|
513 | del self.applied[:appliedbase] | |||
|
514 | self.applied_dirty = 1 | |||
504 | indices = [self.find_series(p) for p in realpatches] |
|
515 | indices = [self.find_series(p) for p in realpatches] | |
505 | indices.sort() |
|
516 | indices.sort() | |
506 | for i in indices[-1::-1]: |
|
517 | for i in indices[-1::-1]: | |
@@ -694,8 +705,8 b' class queue:' | |||||
694 | stripall(rev, revnum) |
|
705 | stripall(rev, revnum) | |
695 |
|
706 | |||
696 | change = chlog.read(rev) |
|
707 | change = chlog.read(rev) | |
|
708 | chlog.strip(revnum, revnum) | |||
697 | repo.manifest.strip(repo.manifest.rev(change[0]), revnum) |
|
709 | repo.manifest.strip(repo.manifest.rev(change[0]), revnum) | |
698 | chlog.strip(revnum, revnum) |
|
|||
699 | if saveheads: |
|
710 | if saveheads: | |
700 | self.ui.status("adding branch\n") |
|
711 | self.ui.status("adding branch\n") | |
701 | commands.unbundle(self.ui, repo, chgrpfile, update=False) |
|
712 | commands.unbundle(self.ui, repo, chgrpfile, update=False) | |
@@ -757,25 +768,25 b' class queue:' | |||||
757 | # return any partial match made above |
|
768 | # return any partial match made above | |
758 | if res: |
|
769 | if res: | |
759 | return res |
|
770 | return res | |
760 |
minus = patch.r |
|
771 | minus = patch.rfind('-') | |
761 |
if |
|
772 | if minus >= 0: | |
762 |
res = partial_name(minus |
|
773 | res = partial_name(patch[:minus]) | |
763 | if res: |
|
774 | if res: | |
764 | i = self.series.index(res) |
|
775 | i = self.series.index(res) | |
765 | try: |
|
776 | try: | |
766 |
off = int(minus |
|
777 | off = int(patch[minus+1:] or 1) | |
767 | except(ValueError, OverflowError): |
|
778 | except(ValueError, OverflowError): | |
768 | pass |
|
779 | pass | |
769 | else: |
|
780 | else: | |
770 | if i - off >= 0: |
|
781 | if i - off >= 0: | |
771 | return self.series[i - off] |
|
782 | return self.series[i - off] | |
772 |
plus = patch.r |
|
783 | plus = patch.rfind('+') | |
773 |
if |
|
784 | if plus >= 0: | |
774 |
res = partial_name(plus |
|
785 | res = partial_name(patch[:plus]) | |
775 | if res: |
|
786 | if res: | |
776 | i = self.series.index(res) |
|
787 | i = self.series.index(res) | |
777 | try: |
|
788 | try: | |
778 |
off = int(plus |
|
789 | off = int(patch[plus+1:] or 1) | |
779 | except(ValueError, OverflowError): |
|
790 | except(ValueError, OverflowError): | |
780 | pass |
|
791 | pass | |
781 | else: |
|
792 | else: | |
@@ -919,13 +930,13 b' class queue:' | |||||
919 | return 1 |
|
930 | return 1 | |
920 | wlock = repo.wlock() |
|
931 | wlock = repo.wlock() | |
921 | self.check_toppatch(repo) |
|
932 | self.check_toppatch(repo) | |
922 | (top, patch) = (self.applied[-1].rev, self.applied[-1].name) |
|
933 | (top, patchfn) = (self.applied[-1].rev, self.applied[-1].name) | |
923 | top = revlog.bin(top) |
|
934 | top = revlog.bin(top) | |
924 | cparents = repo.changelog.parents(top) |
|
935 | cparents = repo.changelog.parents(top) | |
925 | patchparent = self.qparents(repo, top) |
|
936 | patchparent = self.qparents(repo, top) | |
926 | message, comments, user, date, patchfound = self.readheaders(patch) |
|
937 | message, comments, user, date, patchfound = self.readheaders(patchfn) | |
927 |
|
938 | |||
928 | patchf = self.opener(patch, "w") |
|
939 | patchf = self.opener(patchfn, "w") | |
929 | msg = opts.get('msg', '').rstrip() |
|
940 | msg = opts.get('msg', '').rstrip() | |
930 | if msg: |
|
941 | if msg: | |
931 | if comments: |
|
942 | if comments: | |
@@ -995,8 +1006,11 b' class queue:' | |||||
995 | r = list(util.unique(dd)) |
|
1006 | r = list(util.unique(dd)) | |
996 | a = list(util.unique(aa)) |
|
1007 | a = list(util.unique(aa)) | |
997 | filelist = filter(matchfn, util.unique(m + r + a)) |
|
1008 | filelist = filter(matchfn, util.unique(m + r + a)) | |
998 | self.printdiff(repo, patchparent, files=filelist, |
|
1009 | if opts.get('git'): | |
999 | changes=(m, a, r, [], u), fp=patchf) |
|
1010 | self.diffopts().git = True | |
|
1011 | patch.diff(repo, patchparent, files=filelist, match=matchfn, | |||
|
1012 | fp=patchf, changes=(m, a, r, [], u), | |||
|
1013 | opts=self.diffopts()) | |||
1000 | patchf.close() |
|
1014 | patchf.close() | |
1001 |
|
1015 | |||
1002 | changes = repo.changelog.read(tip) |
|
1016 | changes = repo.changelog.read(tip) | |
@@ -1019,7 +1033,7 b' class queue:' | |||||
1019 |
|
1033 | |||
1020 | if not msg: |
|
1034 | if not msg: | |
1021 | if not message: |
|
1035 | if not message: | |
1022 | message = "patch queue: %s\n" % patch |
|
1036 | message = "patch queue: %s\n" % patchfn | |
1023 | else: |
|
1037 | else: | |
1024 | message = "\n".join(message) |
|
1038 | message = "\n".join(message) | |
1025 | else: |
|
1039 | else: | |
@@ -1027,7 +1041,7 b' class queue:' | |||||
1027 |
|
1041 | |||
1028 | self.strip(repo, top, update=False, backup='strip', wlock=wlock) |
|
1042 | self.strip(repo, top, update=False, backup='strip', wlock=wlock) | |
1029 | n = repo.commit(filelist, message, changes[1], force=1, wlock=wlock) |
|
1043 | n = repo.commit(filelist, message, changes[1], force=1, wlock=wlock) | |
1030 | self.applied[-1] = statusentry(revlog.hex(n), patch) |
|
1044 | self.applied[-1] = statusentry(revlog.hex(n), patchfn) | |
1031 | self.applied_dirty = 1 |
|
1045 | self.applied_dirty = 1 | |
1032 | else: |
|
1046 | else: | |
1033 | self.printdiff(repo, patchparent, fp=patchf) |
|
1047 | self.printdiff(repo, patchparent, fp=patchf) | |
@@ -1303,10 +1317,15 b' class queue:' | |||||
1303 | def delete(ui, repo, patch, *patches, **opts): |
|
1317 | def delete(ui, repo, patch, *patches, **opts): | |
1304 | """remove patches from queue |
|
1318 | """remove patches from queue | |
1305 |
|
1319 | |||
1306 | The patches must not be applied. |
|
1320 | With --forget, mq will stop managing the named patches. The | |
1307 | With -k, the patch files are preserved in the patch directory.""" |
|
1321 | patches must be applied and at the base of the stack. This option | |
|
1322 | is useful when the patches have been applied upstream. | |||
|
1323 | ||||
|
1324 | Otherwise, the patches must not be applied. | |||
|
1325 | ||||
|
1326 | With --keep, the patch files are preserved in the patch directory.""" | |||
1308 | q = repo.mq |
|
1327 | q = repo.mq | |
1309 |
q.delete(repo, (patch,) + patches, |
|
1328 | q.delete(repo, (patch,) + patches, opts) | |
1310 | q.save_dirty() |
|
1329 | q.save_dirty() | |
1311 | return 0 |
|
1330 | return 0 | |
1312 |
|
1331 | |||
@@ -1478,7 +1497,7 b' def fold(ui, repo, *files, **opts):' | |||||
1478 | if not files: |
|
1497 | if not files: | |
1479 | raise util.Abort(_('qfold requires at least one patch name')) |
|
1498 | raise util.Abort(_('qfold requires at least one patch name')) | |
1480 | if not q.check_toppatch(repo): |
|
1499 | if not q.check_toppatch(repo): | |
1481 |
raise util.Abort(_('No patches applied |
|
1500 | raise util.Abort(_('No patches applied')) | |
1482 |
|
1501 | |||
1483 | message = commands.logmessage(opts) |
|
1502 | message = commands.logmessage(opts) | |
1484 | if opts['edit']: |
|
1503 | if opts['edit']: | |
@@ -1650,13 +1669,6 b' def rename(ui, repo, patch, name=None, *' | |||||
1650 | name = patch |
|
1669 | name = patch | |
1651 | patch = None |
|
1670 | patch = None | |
1652 |
|
1671 | |||
1653 | if name in q.series: |
|
|||
1654 | raise util.Abort(_('A patch named %s already exists in the series file') % name) |
|
|||
1655 |
|
||||
1656 | absdest = q.join(name) |
|
|||
1657 | if os.path.exists(absdest): |
|
|||
1658 | raise util.Abort(_('%s already exists') % absdest) |
|
|||
1659 |
|
||||
1660 | if patch: |
|
1672 | if patch: | |
1661 | patch = q.lookup(patch) |
|
1673 | patch = q.lookup(patch) | |
1662 | else: |
|
1674 | else: | |
@@ -1664,6 +1676,15 b' def rename(ui, repo, patch, name=None, *' | |||||
1664 | ui.write(_('No patches applied\n')) |
|
1676 | ui.write(_('No patches applied\n')) | |
1665 | return |
|
1677 | return | |
1666 | patch = q.lookup('qtip') |
|
1678 | patch = q.lookup('qtip') | |
|
1679 | absdest = q.join(name) | |||
|
1680 | if os.path.isdir(absdest): | |||
|
1681 | name = os.path.join(name, os.path.basename(patch)) | |||
|
1682 | absdest = q.join(name) | |||
|
1683 | if os.path.exists(absdest): | |||
|
1684 | raise util.Abort(_('%s already exists') % absdest) | |||
|
1685 | ||||
|
1686 | if name in q.series: | |||
|
1687 | raise util.Abort(_('A patch named %s already exists in the series file') % name) | |||
1667 |
|
1688 | |||
1668 | if ui.verbose: |
|
1689 | if ui.verbose: | |
1669 | ui.write('Renaming %s to %s\n' % (patch, name)) |
|
1690 | ui.write('Renaming %s to %s\n' % (patch, name)) | |
@@ -1735,7 +1756,8 b' def strip(ui, repo, rev, **opts):' | |||||
1735 | backup = 'strip' |
|
1756 | backup = 'strip' | |
1736 | elif opts['nobackup']: |
|
1757 | elif opts['nobackup']: | |
1737 | backup = 'none' |
|
1758 | backup = 'none' | |
1738 | repo.mq.strip(repo, rev, backup=backup) |
|
1759 | update = repo.dirstate.parents()[0] != revlog.nullid | |
|
1760 | repo.mq.strip(repo, rev, backup=backup, update=update) | |||
1739 | return 0 |
|
1761 | return 0 | |
1740 |
|
1762 | |||
1741 | def select(ui, repo, *args, **opts): |
|
1763 | def select(ui, repo, *args, **opts): | |
@@ -1911,8 +1933,9 b' cmdtable = {' | |||||
1911 | 'hg qdiff [-I] [-X] [FILE]...'), |
|
1933 | 'hg qdiff [-I] [-X] [FILE]...'), | |
1912 | "qdelete|qremove|qrm": |
|
1934 | "qdelete|qremove|qrm": | |
1913 | (delete, |
|
1935 | (delete, | |
1914 |
[(' |
|
1936 | [('f', 'forget', None, _('stop managing an applied patch')), | |
1915 | 'hg qdelete [-k] PATCH'), |
|
1937 | ('k', 'keep', None, _('keep patch file'))], | |
|
1938 | 'hg qdelete [-f] [-k] PATCH'), | |||
1916 | 'qfold': |
|
1939 | 'qfold': | |
1917 | (fold, |
|
1940 | (fold, | |
1918 | [('e', 'edit', None, _('edit patch header')), |
|
1941 | [('e', 'edit', None, _('edit patch header')), | |
@@ -1963,6 +1986,7 b' cmdtable = {' | |||||
1963 | [('e', 'edit', None, _('edit commit message')), |
|
1986 | [('e', 'edit', None, _('edit commit message')), | |
1964 | ('m', 'message', '', _('change commit message with <text>')), |
|
1987 | ('m', 'message', '', _('change commit message with <text>')), | |
1965 | ('l', 'logfile', '', _('change commit message with <file> content')), |
|
1988 | ('l', 'logfile', '', _('change commit message with <file> content')), | |
|
1989 | ('g', 'git', None, _('use git extended diff format')), | |||
1966 | ('s', 'short', None, 'short refresh'), |
|
1990 | ('s', 'short', None, 'short refresh'), | |
1967 | ('I', 'include', [], _('include names matching the given patterns')), |
|
1991 | ('I', 'include', [], _('include names matching the given patterns')), | |
1968 | ('X', 'exclude', [], _('exclude names matching the given patterns'))], |
|
1992 | ('X', 'exclude', [], _('exclude names matching the given patterns'))], | |
@@ -1994,7 +2018,7 b' cmdtable = {' | |||||
1994 | (series, |
|
2018 | (series, | |
1995 | [('m', 'missing', None, 'print patches not in series'), |
|
2019 | [('m', 'missing', None, 'print patches not in series'), | |
1996 | ('s', 'summary', None, _('print first line of patch header'))], |
|
2020 | ('s', 'summary', None, _('print first line of patch header'))], | |
1997 | 'hg qseries [-m]'), |
|
2021 | 'hg qseries [-ms]'), | |
1998 | "^strip": |
|
2022 | "^strip": | |
1999 | (strip, |
|
2023 | (strip, | |
2000 | [('f', 'force', None, 'force multi-head removal'), |
|
2024 | [('f', 'force', None, 'force multi-head removal'), |
@@ -238,8 +238,11 b' class notifier(object):' | |||||
238 | return |
|
238 | return | |
239 | fp = templater.stringio() |
|
239 | fp = templater.stringio() | |
240 | prev = self.repo.changelog.parents(node)[0] |
|
240 | prev = self.repo.changelog.parents(node)[0] | |
241 |
patch.diff(self.repo, |
|
241 | patch.diff(self.repo, prev, ref, fp=fp) | |
242 | difflines = fp.getvalue().splitlines(1) |
|
242 | difflines = fp.getvalue().splitlines(1) | |
|
243 | if self.ui.configbool('notify', 'diffstat', True): | |||
|
244 | s = patch.diffstat(difflines) | |||
|
245 | self.sio.write('\ndiffstat:\n\n' + s) | |||
243 | if maxdiff > 0 and len(difflines) > maxdiff: |
|
246 | if maxdiff > 0 and len(difflines) > maxdiff: | |
244 | self.sio.write(_('\ndiffs (truncated from %d to %d lines):\n\n') % |
|
247 | self.sio.write(_('\ndiffs (truncated from %d to %d lines):\n\n') % | |
245 | (len(difflines), maxdiff)) |
|
248 | (len(difflines), maxdiff)) |
@@ -65,7 +65,7 b'' | |||||
65 |
|
65 | |||
66 | from mercurial.demandload import * |
|
66 | from mercurial.demandload import * | |
67 | demandload(globals(), '''email.MIMEMultipart email.MIMEText email.Utils |
|
67 | demandload(globals(), '''email.MIMEMultipart email.MIMEText email.Utils | |
68 | mercurial:commands,hg,mail,ui |
|
68 | mercurial:commands,hg,mail,ui,patch | |
69 | os errno popen2 socket sys tempfile time''') |
|
69 | os errno popen2 socket sys tempfile time''') | |
70 | from mercurial.i18n import gettext as _ |
|
70 | from mercurial.i18n import gettext as _ | |
71 | from mercurial.node import * |
|
71 | from mercurial.node import * | |
@@ -76,27 +76,6 b' try:' | |||||
76 | import readline |
|
76 | import readline | |
77 | except ImportError: pass |
|
77 | except ImportError: pass | |
78 |
|
78 | |||
79 | def diffstat(patch): |
|
|||
80 | fd, name = tempfile.mkstemp(prefix="hg-patchbomb-", suffix=".txt") |
|
|||
81 | try: |
|
|||
82 | p = popen2.Popen3('diffstat -p1 -w79 2>/dev/null > ' + name) |
|
|||
83 | try: |
|
|||
84 | for line in patch: print >> p.tochild, line |
|
|||
85 | p.tochild.close() |
|
|||
86 | if p.wait(): return |
|
|||
87 | fp = os.fdopen(fd, 'r') |
|
|||
88 | stat = [] |
|
|||
89 | for line in fp: stat.append(line.lstrip()) |
|
|||
90 | last = stat.pop() |
|
|||
91 | stat.insert(0, last) |
|
|||
92 | stat = ''.join(stat) |
|
|||
93 | if stat.startswith('0 files'): raise ValueError |
|
|||
94 | return stat |
|
|||
95 | except: raise |
|
|||
96 | finally: |
|
|||
97 | try: os.unlink(name) |
|
|||
98 | except: pass |
|
|||
99 |
|
||||
100 | def patchbomb(ui, repo, *revs, **opts): |
|
79 | def patchbomb(ui, repo, *revs, **opts): | |
101 | '''send changesets as a series of patch emails |
|
80 | '''send changesets as a series of patch emails | |
102 |
|
81 | |||
@@ -123,8 +102,8 b' def patchbomb(ui, repo, *revs, **opts):' | |||||
123 | if not prompt(s, default = 'y', rest = '? ').lower().startswith('y'): |
|
102 | if not prompt(s, default = 'y', rest = '? ').lower().startswith('y'): | |
124 | raise ValueError |
|
103 | raise ValueError | |
125 |
|
104 | |||
126 | def cdiffstat(summary, patch): |
|
105 | def cdiffstat(summary, patchlines): | |
127 | s = diffstat(patch) |
|
106 | s = patch.diffstat(patchlines) | |
128 | if s: |
|
107 | if s: | |
129 | if summary: |
|
108 | if summary: | |
130 | ui.write(summary, '\n') |
|
109 | ui.write(summary, '\n') | |
@@ -140,7 +119,9 b' def patchbomb(ui, repo, *revs, **opts):' | |||||
140 | if line.startswith('#'): |
|
119 | if line.startswith('#'): | |
141 | if line.startswith('# Node ID'): node = line.split()[-1] |
|
120 | if line.startswith('# Node ID'): node = line.split()[-1] | |
142 | continue |
|
121 | continue | |
143 |
if line.startswith('diff -r') |
|
122 | if (line.startswith('diff -r') | |
|
123 | or line.startswith('diff --git')): | |||
|
124 | break | |||
144 | desc.append(line) |
|
125 | desc.append(line) | |
145 | if not node: raise ValueError |
|
126 | if not node: raise ValueError | |
146 |
|
127 | |||
@@ -205,7 +186,8 b' def patchbomb(ui, repo, *revs, **opts):' | |||||
205 |
|
186 | |||
206 | commands.export(ui, repo, *revs, **{'output': exportee(patches), |
|
187 | commands.export(ui, repo, *revs, **{'output': exportee(patches), | |
207 | 'switch_parent': False, |
|
188 | 'switch_parent': False, | |
208 |
'text': None |
|
189 | 'text': None, | |
|
190 | 'git': opts.get('git')}) | |||
209 |
|
191 | |||
210 | jumbo = [] |
|
192 | jumbo = [] | |
211 | msgs = [] |
|
193 | msgs = [] | |
@@ -322,6 +304,7 b' cmdtable = {' | |||||
322 | ('', 'bcc', [], 'email addresses of blind copy recipients'), |
|
304 | ('', 'bcc', [], 'email addresses of blind copy recipients'), | |
323 | ('c', 'cc', [], 'email addresses of copy recipients'), |
|
305 | ('c', 'cc', [], 'email addresses of copy recipients'), | |
324 | ('d', 'diffstat', None, 'add diffstat output to messages'), |
|
306 | ('d', 'diffstat', None, 'add diffstat output to messages'), | |
|
307 | ('g', 'git', None, _('use git extended diff format')), | |||
325 | ('f', 'from', '', 'email address of sender'), |
|
308 | ('f', 'from', '', 'email address of sender'), | |
326 | ('', 'plain', None, 'omit hg patch header'), |
|
309 | ('', 'plain', None, 'omit hg patch header'), | |
327 | ('n', 'test', None, 'print messages that would be sent'), |
|
310 | ('n', 'test', None, 'print messages that would be sent'), |
@@ -16,6 +16,14 b' class changelog(revlog):' | |||||
16 | defversion) |
|
16 | defversion) | |
17 |
|
17 | |||
18 | def extract(self, text): |
|
18 | def extract(self, text): | |
|
19 | """ | |||
|
20 | format used: | |||
|
21 | nodeid\n : manifest node in ascii | |||
|
22 | user\n : user, no \n or \r allowed | |||
|
23 | time tz\n : date (time is int or float, timezone is int) | |||
|
24 | files\n\n : files modified by the cset, no \n or \r allowed | |||
|
25 | (.*) : comment (free text, ideally utf-8) | |||
|
26 | """ | |||
19 | if not text: |
|
27 | if not text: | |
20 | return (nullid, "", (0, 0), [], "") |
|
28 | return (nullid, "", (0, 0), [], "") | |
21 | last = text.index("\n\n") |
|
29 | last = text.index("\n\n") |
@@ -11,6 +11,76 b' from i18n import gettext as _' | |||||
11 | demandload(globals(), 'mdiff util') |
|
11 | demandload(globals(), 'mdiff util') | |
12 | demandload(globals(), 'os sys') |
|
12 | demandload(globals(), 'os sys') | |
13 |
|
13 | |||
|
14 | revrangesep = ':' | |||
|
15 | ||||
|
16 | def revfix(repo, val, defval): | |||
|
17 | '''turn user-level id of changeset into rev number. | |||
|
18 | user-level id can be tag, changeset, rev number, or negative rev | |||
|
19 | number relative to number of revs (-1 is tip, etc).''' | |||
|
20 | if not val: | |||
|
21 | return defval | |||
|
22 | try: | |||
|
23 | num = int(val) | |||
|
24 | if str(num) != val: | |||
|
25 | raise ValueError | |||
|
26 | if num < 0: | |||
|
27 | num += repo.changelog.count() | |||
|
28 | if num < 0: | |||
|
29 | num = 0 | |||
|
30 | elif num >= repo.changelog.count(): | |||
|
31 | raise ValueError | |||
|
32 | except ValueError: | |||
|
33 | try: | |||
|
34 | num = repo.changelog.rev(repo.lookup(val)) | |||
|
35 | except KeyError: | |||
|
36 | raise util.Abort(_('invalid revision identifier %s') % val) | |||
|
37 | return num | |||
|
38 | ||||
|
39 | def revpair(ui, repo, revs): | |||
|
40 | '''return pair of nodes, given list of revisions. second item can | |||
|
41 | be None, meaning use working dir.''' | |||
|
42 | if not revs: | |||
|
43 | return repo.dirstate.parents()[0], None | |||
|
44 | end = None | |||
|
45 | if len(revs) == 1: | |||
|
46 | start = revs[0] | |||
|
47 | if revrangesep in start: | |||
|
48 | start, end = start.split(revrangesep, 1) | |||
|
49 | start = revfix(repo, start, 0) | |||
|
50 | end = revfix(repo, end, repo.changelog.count() - 1) | |||
|
51 | else: | |||
|
52 | start = revfix(repo, start, None) | |||
|
53 | elif len(revs) == 2: | |||
|
54 | if revrangesep in revs[0] or revrangesep in revs[1]: | |||
|
55 | raise util.Abort(_('too many revisions specified')) | |||
|
56 | start = revfix(repo, revs[0], None) | |||
|
57 | end = revfix(repo, revs[1], None) | |||
|
58 | else: | |||
|
59 | raise util.Abort(_('too many revisions specified')) | |||
|
60 | if end is not None: end = repo.lookup(str(end)) | |||
|
61 | return repo.lookup(str(start)), end | |||
|
62 | ||||
|
63 | def revrange(ui, repo, revs): | |||
|
64 | """Yield revision as strings from a list of revision specifications.""" | |||
|
65 | seen = {} | |||
|
66 | for spec in revs: | |||
|
67 | if revrangesep in spec: | |||
|
68 | start, end = spec.split(revrangesep, 1) | |||
|
69 | start = revfix(repo, start, 0) | |||
|
70 | end = revfix(repo, end, repo.changelog.count() - 1) | |||
|
71 | step = start > end and -1 or 1 | |||
|
72 | for rev in xrange(start, end+step, step): | |||
|
73 | if rev in seen: | |||
|
74 | continue | |||
|
75 | seen[rev] = 1 | |||
|
76 | yield str(rev) | |||
|
77 | else: | |||
|
78 | rev = revfix(repo, spec, None) | |||
|
79 | if rev in seen: | |||
|
80 | continue | |||
|
81 | seen[rev] = 1 | |||
|
82 | yield str(rev) | |||
|
83 | ||||
14 | def make_filename(repo, pat, node, |
|
84 | def make_filename(repo, pat, node, | |
15 | total=None, seqno=None, revwidth=None, pathname=None): |
|
85 | total=None, seqno=None, revwidth=None, pathname=None): | |
16 | node_expander = { |
|
86 | node_expander = { | |
@@ -53,8 +123,8 b' def make_filename(repo, pat, node,' | |||||
53 | i += 1 |
|
123 | i += 1 | |
54 | return ''.join(newname) |
|
124 | return ''.join(newname) | |
55 | except KeyError, inst: |
|
125 | except KeyError, inst: | |
56 |
raise util.Abort(_("invalid format spec '%%%s' in output file name") |
|
126 | raise util.Abort(_("invalid format spec '%%%s' in output file name") % | |
57 | inst.args[0]) |
|
127 | inst.args[0]) | |
58 |
|
128 | |||
59 | def make_file(repo, pat, node=None, |
|
129 | def make_file(repo, pat, node=None, | |
60 | total=None, seqno=None, revwidth=None, mode='wb', pathname=None): |
|
130 | total=None, seqno=None, revwidth=None, mode='wb', pathname=None): |
@@ -8,7 +8,7 b'' | |||||
8 | from demandload import demandload |
|
8 | from demandload import demandload | |
9 | from node import * |
|
9 | from node import * | |
10 | from i18n import gettext as _ |
|
10 | from i18n import gettext as _ | |
11 | demandload(globals(), "os re sys signal shutil imp urllib pdb") |
|
11 | demandload(globals(), "os re sys signal shutil imp urllib pdb shlex") | |
12 | demandload(globals(), "fancyopts ui hg util lock revlog templater bundlerepo") |
|
12 | demandload(globals(), "fancyopts ui hg util lock revlog templater bundlerepo") | |
13 | demandload(globals(), "fnmatch difflib patch random signal tempfile time") |
|
13 | demandload(globals(), "fnmatch difflib patch random signal tempfile time") | |
14 | demandload(globals(), "traceback errno socket version struct atexit sets bz2") |
|
14 | demandload(globals(), "traceback errno socket version struct atexit sets bz2") | |
@@ -50,6 +50,21 b' def logmessage(opts):' | |||||
50 | (logfile, inst.strerror)) |
|
50 | (logfile, inst.strerror)) | |
51 | return message |
|
51 | return message | |
52 |
|
52 | |||
|
53 | def defaultrev(repo, rev=None, default='tip'): | |||
|
54 | """returns rev if it is specified, otherwise the working dir | |||
|
55 | parent if there is only one, or tip if there is no working | |||
|
56 | dir""" | |||
|
57 | if rev: | |||
|
58 | return rev | |||
|
59 | ||||
|
60 | p1, p2 = repo.dirstate.parents() | |||
|
61 | if p2 != nullid: | |||
|
62 | raise util.Abort(_('uncommitted merge - please provide a ' | |||
|
63 | 'specific revision')) | |||
|
64 | if p1 != nullid: | |||
|
65 | return hex(p1) | |||
|
66 | return default | |||
|
67 | ||||
53 | def walkchangerevs(ui, repo, pats, opts): |
|
68 | def walkchangerevs(ui, repo, pats, opts): | |
54 | '''Iterate over files and the revs they changed in. |
|
69 | '''Iterate over files and the revs they changed in. | |
55 |
|
70 | |||
@@ -99,16 +114,10 b' def walkchangerevs(ui, repo, pats, opts)' | |||||
99 | return [], False, matchfn |
|
114 | return [], False, matchfn | |
100 |
|
115 | |||
101 | if follow: |
|
116 | if follow: | |
102 | p = repo.dirstate.parents()[0] |
|
117 | defrange = '%s:0' % defaultrev(repo) | |
103 | if p == nullid: |
|
|||
104 | ui.warn(_('No working directory revision; defaulting to tip\n')) |
|
|||
105 | start = 'tip' |
|
|||
106 | else: |
|
|||
107 | start = repo.changelog.rev(p) |
|
|||
108 | defrange = '%s:0' % start |
|
|||
109 | else: |
|
118 | else: | |
110 | defrange = 'tip:0' |
|
119 | defrange = 'tip:0' | |
111 | revs = map(int, revrange(ui, repo, opts['rev'] or [defrange])) |
|
120 | revs = map(int, cmdutil.revrange(ui, repo, opts['rev'] or [defrange])) | |
112 | wanted = {} |
|
121 | wanted = {} | |
113 | slowpath = anypats |
|
122 | slowpath = anypats | |
114 | fncache = {} |
|
123 | fncache = {} | |
@@ -252,76 +261,6 b' def walkchangerevs(ui, repo, pats, opts)' | |||||
252 | yield 'iter', rev, None |
|
261 | yield 'iter', rev, None | |
253 | return iterate(), getchange, matchfn |
|
262 | return iterate(), getchange, matchfn | |
254 |
|
263 | |||
255 | revrangesep = ':' |
|
|||
256 |
|
||||
257 | def revfix(repo, val, defval): |
|
|||
258 | '''turn user-level id of changeset into rev number. |
|
|||
259 | user-level id can be tag, changeset, rev number, or negative rev |
|
|||
260 | number relative to number of revs (-1 is tip, etc).''' |
|
|||
261 | if not val: |
|
|||
262 | return defval |
|
|||
263 | try: |
|
|||
264 | num = int(val) |
|
|||
265 | if str(num) != val: |
|
|||
266 | raise ValueError |
|
|||
267 | if num < 0: |
|
|||
268 | num += repo.changelog.count() |
|
|||
269 | if num < 0: |
|
|||
270 | num = 0 |
|
|||
271 | elif num >= repo.changelog.count(): |
|
|||
272 | raise ValueError |
|
|||
273 | except ValueError: |
|
|||
274 | try: |
|
|||
275 | num = repo.changelog.rev(repo.lookup(val)) |
|
|||
276 | except KeyError: |
|
|||
277 | raise util.Abort(_('invalid revision identifier %s'), val) |
|
|||
278 | return num |
|
|||
279 |
|
||||
280 | def revpair(ui, repo, revs): |
|
|||
281 | '''return pair of nodes, given list of revisions. second item can |
|
|||
282 | be None, meaning use working dir.''' |
|
|||
283 | if not revs: |
|
|||
284 | return repo.dirstate.parents()[0], None |
|
|||
285 | end = None |
|
|||
286 | if len(revs) == 1: |
|
|||
287 | start = revs[0] |
|
|||
288 | if revrangesep in start: |
|
|||
289 | start, end = start.split(revrangesep, 1) |
|
|||
290 | start = revfix(repo, start, 0) |
|
|||
291 | end = revfix(repo, end, repo.changelog.count() - 1) |
|
|||
292 | else: |
|
|||
293 | start = revfix(repo, start, None) |
|
|||
294 | elif len(revs) == 2: |
|
|||
295 | if revrangesep in revs[0] or revrangesep in revs[1]: |
|
|||
296 | raise util.Abort(_('too many revisions specified')) |
|
|||
297 | start = revfix(repo, revs[0], None) |
|
|||
298 | end = revfix(repo, revs[1], None) |
|
|||
299 | else: |
|
|||
300 | raise util.Abort(_('too many revisions specified')) |
|
|||
301 | if end is not None: end = repo.lookup(str(end)) |
|
|||
302 | return repo.lookup(str(start)), end |
|
|||
303 |
|
||||
304 | def revrange(ui, repo, revs): |
|
|||
305 | """Yield revision as strings from a list of revision specifications.""" |
|
|||
306 | seen = {} |
|
|||
307 | for spec in revs: |
|
|||
308 | if revrangesep in spec: |
|
|||
309 | start, end = spec.split(revrangesep, 1) |
|
|||
310 | start = revfix(repo, start, 0) |
|
|||
311 | end = revfix(repo, end, repo.changelog.count() - 1) |
|
|||
312 | step = start > end and -1 or 1 |
|
|||
313 | for rev in xrange(start, end+step, step): |
|
|||
314 | if rev in seen: |
|
|||
315 | continue |
|
|||
316 | seen[rev] = 1 |
|
|||
317 | yield str(rev) |
|
|||
318 | else: |
|
|||
319 | rev = revfix(repo, spec, None) |
|
|||
320 | if rev in seen: |
|
|||
321 | continue |
|
|||
322 | seen[rev] = 1 |
|
|||
323 | yield str(rev) |
|
|||
324 |
|
||||
325 | def write_bundle(cg, filename=None, compress=True): |
|
264 | def write_bundle(cg, filename=None, compress=True): | |
326 | """Write a bundle file and return its filename. |
|
265 | """Write a bundle file and return its filename. | |
327 |
|
266 | |||
@@ -341,7 +280,7 b' def write_bundle(cg, filename=None, comp' | |||||
341 | try: |
|
280 | try: | |
342 | if filename: |
|
281 | if filename: | |
343 | if os.path.exists(filename): |
|
282 | if os.path.exists(filename): | |
344 |
raise util.Abort(_("file '%s' already exists") |
|
283 | raise util.Abort(_("file '%s' already exists") % filename) | |
345 | fh = open(filename, "wb") |
|
284 | fh = open(filename, "wb") | |
346 | else: |
|
285 | else: | |
347 | fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg") |
|
286 | fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg") | |
@@ -707,7 +646,7 b' def annotate(ui, repo, *pats, **opts):' | |||||
707 | if not opts['user'] and not opts['changeset'] and not opts['date']: |
|
646 | if not opts['user'] and not opts['changeset'] and not opts['date']: | |
708 | opts['number'] = 1 |
|
647 | opts['number'] = 1 | |
709 |
|
648 | |||
710 |
ctx = repo.changectx(opts['rev'] |
|
649 | ctx = repo.changectx(defaultrev(repo, opts['rev'])) | |
711 |
|
650 | |||
712 | for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, |
|
651 | for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, | |
713 | node=ctx.node()): |
|
652 | node=ctx.node()): | |
@@ -754,14 +693,7 b' def archive(ui, repo, dest, **opts):' | |||||
754 | The default is the basename of the archive, with suffixes removed. |
|
693 | The default is the basename of the archive, with suffixes removed. | |
755 | ''' |
|
694 | ''' | |
756 |
|
695 | |||
757 | if opts['rev']: |
|
696 | node = repo.lookup(defaultrev(repo, opts['rev'])) | |
758 | node = repo.lookup(opts['rev']) |
|
|||
759 | else: |
|
|||
760 | node, p2 = repo.dirstate.parents() |
|
|||
761 | if p2 != nullid: |
|
|||
762 | raise util.Abort(_('uncommitted merge - please provide a ' |
|
|||
763 | 'specific revision')) |
|
|||
764 |
|
||||
765 | dest = cmdutil.make_filename(repo, dest, node) |
|
697 | dest = cmdutil.make_filename(repo, dest, node) | |
766 | if os.path.realpath(dest) == repo.root: |
|
698 | if os.path.realpath(dest) == repo.root: | |
767 | raise util.Abort(_('repository root cannot be destination')) |
|
699 | raise util.Abort(_('repository root cannot be destination')) | |
@@ -867,7 +799,8 b' def cat(ui, repo, file1, *pats, **opts):' | |||||
867 | """output the latest or given revisions of files |
|
799 | """output the latest or given revisions of files | |
868 |
|
800 | |||
869 | Print the specified files as they were at the given revision. |
|
801 | Print the specified files as they were at the given revision. | |
870 |
If no revision is given then |
|
802 | If no revision is given then working dir parent is used, or tip | |
|
803 | if no revision is checked out. | |||
871 |
|
804 | |||
872 | Output may be to a file, in which case the name of the file is |
|
805 | Output may be to a file, in which case the name of the file is | |
873 | given using a format string. The formatting rules are the same as |
|
806 | given using a format string. The formatting rules are the same as | |
@@ -877,7 +810,7 b' def cat(ui, repo, file1, *pats, **opts):' | |||||
877 | %d dirname of file being printed, or '.' if in repo root |
|
810 | %d dirname of file being printed, or '.' if in repo root | |
878 | %p root-relative path name of file being printed |
|
811 | %p root-relative path name of file being printed | |
879 | """ |
|
812 | """ | |
880 |
ctx = repo.changectx(opts['rev'] |
|
813 | ctx = repo.changectx(defaultrev(repo, opts['rev'])) | |
881 | for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts, |
|
814 | for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts, | |
882 | ctx.node()): |
|
815 | ctx.node()): | |
883 | fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs) |
|
816 | fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs) | |
@@ -1269,7 +1202,7 b' def debugdata(ui, file_, rev):' | |||||
1269 | try: |
|
1202 | try: | |
1270 | ui.write(r.revision(r.lookup(rev))) |
|
1203 | ui.write(r.revision(r.lookup(rev))) | |
1271 | except KeyError: |
|
1204 | except KeyError: | |
1272 |
raise util.Abort(_('invalid revision identifier %s') |
|
1205 | raise util.Abort(_('invalid revision identifier %s') % rev) | |
1273 |
|
1206 | |||
1274 | def debugindex(ui, file_): |
|
1207 | def debugindex(ui, file_): | |
1275 | """dump the contents of an index file""" |
|
1208 | """dump the contents of an index file""" | |
@@ -1344,7 +1277,7 b' def diff(ui, repo, *pats, **opts):' | |||||
1344 | it detects as binary. With -a, diff will generate a diff anyway, |
|
1277 | it detects as binary. With -a, diff will generate a diff anyway, | |
1345 | probably with undesirable results. |
|
1278 | probably with undesirable results. | |
1346 | """ |
|
1279 | """ | |
1347 | node1, node2 = revpair(ui, repo, opts['rev']) |
|
1280 | node1, node2 = cmdutil.revpair(ui, repo, opts['rev']) | |
1348 |
|
1281 | |||
1349 | fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) |
|
1282 | fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) | |
1350 |
|
1283 | |||
@@ -1380,7 +1313,7 b' def export(ui, repo, *changesets, **opts' | |||||
1380 | """ |
|
1313 | """ | |
1381 | if not changesets: |
|
1314 | if not changesets: | |
1382 | raise util.Abort(_("export requires at least one changeset")) |
|
1315 | raise util.Abort(_("export requires at least one changeset")) | |
1383 | revs = list(revrange(ui, repo, changesets)) |
|
1316 | revs = list(cmdutil.revrange(ui, repo, changesets)) | |
1384 | if len(revs) > 1: |
|
1317 | if len(revs) > 1: | |
1385 | ui.note(_('exporting patches:\n')) |
|
1318 | ui.note(_('exporting patches:\n')) | |
1386 | else: |
|
1319 | else: | |
@@ -1940,7 +1873,7 b' def merge(ui, repo, node=None, force=Non' | |||||
1940 | revision to merge with must be provided. |
|
1873 | revision to merge with must be provided. | |
1941 | """ |
|
1874 | """ | |
1942 |
|
1875 | |||
1943 | if node: |
|
1876 | if node or branch: | |
1944 | node = _lookup(repo, node, branch) |
|
1877 | node = _lookup(repo, node, branch) | |
1945 | else: |
|
1878 | else: | |
1946 | heads = repo.heads() |
|
1879 | heads = repo.heads() | |
@@ -2272,8 +2205,8 b' def revert(ui, repo, *pats, **opts):' | |||||
2272 | Modified files are saved with a .orig suffix before reverting. |
|
2205 | Modified files are saved with a .orig suffix before reverting. | |
2273 | To disable these backups, use --no-backup. |
|
2206 | To disable these backups, use --no-backup. | |
2274 |
|
2207 | |||
2275 | Using the -r option, revert the given files or directories to |
|
2208 | Using the -r option, revert the given files or directories to their | |
2276 |
|
|
2209 | contents as of a specific revision. This can be helpful to "roll | |
2277 | back" some or all of a change that should not have been committed. |
|
2210 | back" some or all of a change that should not have been committed. | |
2278 |
|
2211 | |||
2279 | Revert modifies the working directory. It does not commit any |
|
2212 | Revert modifies the working directory. It does not commit any | |
@@ -2291,16 +2224,11 b' def revert(ui, repo, *pats, **opts):' | |||||
2291 | """ |
|
2224 | """ | |
2292 |
|
2225 | |||
2293 | if not pats and not opts['all']: |
|
2226 | if not pats and not opts['all']: | |
2294 |
raise util.Abort(_('no files or directories specified' |
|
2227 | raise util.Abort(_('no files or directories specified; ' | |
|
2228 | 'use --all to revert the whole repo')) | |||
2295 |
|
2229 | |||
2296 | parent, p2 = repo.dirstate.parents() |
|
2230 | parent, p2 = repo.dirstate.parents() | |
2297 | if opts['rev']: |
|
2231 | node = repo.lookup(defaultrev(repo, opts['rev'])) | |
2298 | node = repo.lookup(opts['rev']) |
|
|||
2299 | elif p2 != nullid: |
|
|||
2300 | raise util.Abort(_('working dir has two parents; ' |
|
|||
2301 | 'you must specify the revision to revert to')) |
|
|||
2302 | else: |
|
|||
2303 | node = parent |
|
|||
2304 | mf = repo.manifest.read(repo.changelog.read(node)[0]) |
|
2232 | mf = repo.manifest.read(repo.changelog.read(node)[0]) | |
2305 | if node == parent: |
|
2233 | if node == parent: | |
2306 | pmf = mf |
|
2234 | pmf = mf | |
@@ -2457,7 +2385,8 b' def serve(ui, repo, **opts):' | |||||
2457 |
|
2385 | |||
2458 | if opts["stdio"]: |
|
2386 | if opts["stdio"]: | |
2459 | if repo is None: |
|
2387 | if repo is None: | |
2460 |
raise hg.RepoError(_( |
|
2388 | raise hg.RepoError(_("There is no Mercurial repository here" | |
|
2389 | " (.hg not found)")) | |||
2461 | s = sshserver.sshserver(ui, repo) |
|
2390 | s = sshserver.sshserver(ui, repo) | |
2462 | s.serve_forever() |
|
2391 | s.serve_forever() | |
2463 |
|
2392 | |||
@@ -2468,7 +2397,8 b' def serve(ui, repo, **opts):' | |||||
2468 | ui.setconfig("web", o, opts[o]) |
|
2397 | ui.setconfig("web", o, opts[o]) | |
2469 |
|
2398 | |||
2470 | if repo is None and not ui.config("web", "webdir_conf"): |
|
2399 | if repo is None and not ui.config("web", "webdir_conf"): | |
2471 |
raise hg.RepoError(_( |
|
2400 | raise hg.RepoError(_("There is no Mercurial repository here" | |
|
2401 | " (.hg not found)")) | |||
2472 |
|
2402 | |||
2473 | if opts['daemon'] and not opts['daemon_pipefds']: |
|
2403 | if opts['daemon'] and not opts['daemon_pipefds']: | |
2474 | rfd, wfd = os.pipe() |
|
2404 | rfd, wfd = os.pipe() | |
@@ -2483,7 +2413,7 b' def serve(ui, repo, **opts):' | |||||
2483 | try: |
|
2413 | try: | |
2484 | httpd = hgweb.server.create_server(ui, repo) |
|
2414 | httpd = hgweb.server.create_server(ui, repo) | |
2485 | except socket.error, inst: |
|
2415 | except socket.error, inst: | |
2486 |
raise util.Abort(_('cannot start server: ') |
|
2416 | raise util.Abort(_('cannot start server: %s') % inst.args[1]) | |
2487 |
|
2417 | |||
2488 | if ui.verbose: |
|
2418 | if ui.verbose: | |
2489 | addr, port = httpd.socket.getsockname() |
|
2419 | addr, port = httpd.socket.getsockname() | |
@@ -2598,15 +2528,10 b' def tag(ui, repo, name, rev_=None, **opt' | |||||
2598 | raise util.Abort(_("use only one form to specify the revision")) |
|
2528 | raise util.Abort(_("use only one form to specify the revision")) | |
2599 | if opts['rev']: |
|
2529 | if opts['rev']: | |
2600 | rev_ = opts['rev'] |
|
2530 | rev_ = opts['rev'] | |
2601 | if rev_: |
|
2531 | r = defaultrev(repo, rev_, nullid) | |
2602 | r = repo.lookup(rev_) |
|
2532 | if r == nullid: | |
2603 | else: |
|
2533 | raise util.Abort(_('no revision to tag')) | |
2604 | p1, p2 = repo.dirstate.parents() |
|
2534 | r = repo.lookup(r) | |
2605 | if p1 == nullid: |
|
|||
2606 | raise util.Abort(_('no revision to tag')) |
|
|||
2607 | if p2 != nullid: |
|
|||
2608 | raise util.Abort(_('outstanding uncommitted merges')) |
|
|||
2609 | r = p1 |
|
|||
2610 |
|
2535 | |||
2611 | message = opts['message'] |
|
2536 | message = opts['message'] | |
2612 | if not message: |
|
2537 | if not message: | |
@@ -2733,7 +2658,7 b' def _lookup(repo, node, branch=None):' | |||||
2733 | repo.ui.warn(_("Using head %s for branch %s\n") |
|
2658 | repo.ui.warn(_("Using head %s for branch %s\n") | |
2734 | % (short(node), branch)) |
|
2659 | % (short(node), branch)) | |
2735 | else: |
|
2660 | else: | |
2736 |
raise util.Abort(_("branch %s not found |
|
2661 | raise util.Abort(_("branch %s not found") % branch) | |
2737 | else: |
|
2662 | else: | |
2738 | node = node and repo.lookup(node) or repo.changelog.tip() |
|
2663 | node = node and repo.lookup(node) or repo.changelog.tip() | |
2739 | return node |
|
2664 | return node | |
@@ -2886,6 +2811,7 b' table = {' | |||||
2886 | (export, |
|
2811 | (export, | |
2887 | [('o', 'output', '', _('print output to file with formatted name')), |
|
2812 | [('o', 'output', '', _('print output to file with formatted name')), | |
2888 | ('a', 'text', None, _('treat all files as text')), |
|
2813 | ('a', 'text', None, _('treat all files as text')), | |
|
2814 | ('g', 'git', None, _('use git extended diff format')), | |||
2889 | ('', 'switch-parent', None, _('diff against the second parent'))], |
|
2815 | ('', 'switch-parent', None, _('diff against the second parent'))], | |
2890 | _('hg export [-a] [-o OUTFILESPEC] REV...')), |
|
2816 | _('hg export [-a] [-o OUTFILESPEC] REV...')), | |
2891 | "debugforget|forget": |
|
2817 | "debugforget|forget": | |
@@ -3221,7 +3147,7 b' def parse(ui, args):' | |||||
3221 | cmd = aliases[0] |
|
3147 | cmd = aliases[0] | |
3222 | defaults = ui.config("defaults", cmd) |
|
3148 | defaults = ui.config("defaults", cmd) | |
3223 | if defaults: |
|
3149 | if defaults: | |
3224 |
args = |
|
3150 | args = shlex.split(defaults) + args | |
3225 | c = list(i[1]) |
|
3151 | c = list(i[1]) | |
3226 | else: |
|
3152 | else: | |
3227 | cmd = None |
|
3153 | cmd = None | |
@@ -3305,12 +3231,14 b' def dispatch(args):' | |||||
3305 | if num: signal.signal(num, catchterm) |
|
3231 | if num: signal.signal(num, catchterm) | |
3306 |
|
3232 | |||
3307 | try: |
|
3233 | try: | |
3308 |
u = ui.ui(traceback='--traceback' in sys.argv[1:] |
|
3234 | u = ui.ui(traceback='--traceback' in sys.argv[1:]) | |
3309 | readhooks=[load_extensions]) |
|
|||
3310 | except util.Abort, inst: |
|
3235 | except util.Abort, inst: | |
3311 | sys.stderr.write(_("abort: %s\n") % inst) |
|
3236 | sys.stderr.write(_("abort: %s\n") % inst) | |
3312 | return -1 |
|
3237 | return -1 | |
3313 |
|
3238 | |||
|
3239 | load_extensions(u) | |||
|
3240 | u.addreadhook(load_extensions) | |||
|
3241 | ||||
3314 | try: |
|
3242 | try: | |
3315 | cmd, func, args, options, cmdoptions = parse(u, args) |
|
3243 | cmd, func, args, options, cmdoptions = parse(u, args) | |
3316 | if options["time"]: |
|
3244 | if options["time"]: | |
@@ -3445,7 +3373,7 b' def dispatch(args):' | |||||
3445 | u.warn(_("abort: could not lock %s: %s\n") % |
|
3373 | u.warn(_("abort: could not lock %s: %s\n") % | |
3446 | (inst.desc or inst.filename, inst.strerror)) |
|
3374 | (inst.desc or inst.filename, inst.strerror)) | |
3447 | except revlog.RevlogError, inst: |
|
3375 | except revlog.RevlogError, inst: | |
3448 |
u.warn(_("abort: |
|
3376 | u.warn(_("abort: %s!\n") % inst) | |
3449 | except util.SignalInterrupt: |
|
3377 | except util.SignalInterrupt: | |
3450 | u.warn(_("killed!\n")) |
|
3378 | u.warn(_("killed!\n")) | |
3451 | except KeyboardInterrupt: |
|
3379 | except KeyboardInterrupt: | |
@@ -3467,18 +3395,18 b' def dispatch(args):' | |||||
3467 | u.warn(_("broken pipe\n")) |
|
3395 | u.warn(_("broken pipe\n")) | |
3468 | elif getattr(inst, "strerror", None): |
|
3396 | elif getattr(inst, "strerror", None): | |
3469 | if getattr(inst, "filename", None): |
|
3397 | if getattr(inst, "filename", None): | |
3470 |
u.warn(_("abort: %s |
|
3398 | u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename)) | |
3471 | else: |
|
3399 | else: | |
3472 | u.warn(_("abort: %s\n") % inst.strerror) |
|
3400 | u.warn(_("abort: %s\n") % inst.strerror) | |
3473 | else: |
|
3401 | else: | |
3474 | raise |
|
3402 | raise | |
3475 | except OSError, inst: |
|
3403 | except OSError, inst: | |
3476 |
if |
|
3404 | if getattr(inst, "filename", None): | |
3477 | u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename)) |
|
3405 | u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename)) | |
3478 | else: |
|
3406 | else: | |
3479 | u.warn(_("abort: %s\n") % inst.strerror) |
|
3407 | u.warn(_("abort: %s\n") % inst.strerror) | |
3480 | except util.Abort, inst: |
|
3408 | except util.Abort, inst: | |
3481 |
u.warn(_( |
|
3409 | u.warn(_("abort: %s\n") % inst) | |
3482 | except TypeError, inst: |
|
3410 | except TypeError, inst: | |
3483 | # was this an argument error? |
|
3411 | # was this an argument error? | |
3484 | tb = traceback.extract_tb(sys.exc_info()[2]) |
|
3412 | tb = traceback.extract_tb(sys.exc_info()[2]) |
@@ -115,7 +115,7 b' def clone(ui, source, dest=None, pull=Fa' | |||||
115 | source = localpath(source) |
|
115 | source = localpath(source) | |
116 |
|
116 | |||
117 | if os.path.exists(dest): |
|
117 | if os.path.exists(dest): | |
118 |
raise util.Abort(_("destination '%s' already exists") |
|
118 | raise util.Abort(_("destination '%s' already exists") % dest) | |
119 |
|
119 | |||
120 | class DirCleanup(object): |
|
120 | class DirCleanup(object): | |
121 | def __init__(self, dir_): |
|
121 | def __init__(self, dir_): | |
@@ -127,12 +127,7 b' def clone(ui, source, dest=None, pull=Fa' | |||||
127 | if self.dir_: |
|
127 | if self.dir_: | |
128 | self.rmtree(self.dir_, True) |
|
128 | self.rmtree(self.dir_, True) | |
129 |
|
129 | |||
130 | dest_repo = None |
|
130 | dest_repo = repository(ui, dest, create=True) | |
131 | try: |
|
|||
132 | dest_repo = repository(ui, dest) |
|
|||
133 | raise util.Abort(_("destination '%s' already exists." % dest)) |
|
|||
134 | except RepoError: |
|
|||
135 | dest_repo = repository(ui, dest, create=True) |
|
|||
136 |
|
131 | |||
137 | dest_path = None |
|
132 | dest_path = None | |
138 | dir_cleanup = None |
|
133 | dir_cleanup = None |
@@ -207,7 +207,8 b' def create_server(ui, repo):' | |||||
207 | hgwebobj = self.repoviewmaker(repo.__class__(repo.ui, |
|
207 | hgwebobj = self.repoviewmaker(repo.__class__(repo.ui, | |
208 | repo.origroot)) |
|
208 | repo.origroot)) | |
209 | else: |
|
209 | else: | |
210 |
raise hg.RepoError(_( |
|
210 | raise hg.RepoError(_("There is no Mercurial repository here" | |
|
211 | " (.hg not found)")) | |||
211 | return hgwebobj |
|
212 | return hgwebobj | |
212 |
|
213 | |||
213 | class IPv6HTTPServer(MercurialHTTPServer): |
|
214 | class IPv6HTTPServer(MercurialHTTPServer): |
@@ -325,7 +325,7 b' class httprepository(remoterepository):' | |||||
325 | rfp.close() |
|
325 | rfp.close() | |
326 | except socket.error, err: |
|
326 | except socket.error, err: | |
327 | if err[0] in (errno.ECONNRESET, errno.EPIPE): |
|
327 | if err[0] in (errno.ECONNRESET, errno.EPIPE): | |
328 |
raise util.Abort(_('push failed: %s') |
|
328 | raise util.Abort(_('push failed: %s') % err[1]) | |
329 | raise util.Abort(err[1]) |
|
329 | raise util.Abort(err[1]) | |
330 | finally: |
|
330 | finally: | |
331 | fp.close() |
|
331 | fp.close() |
@@ -27,12 +27,21 b' class localrepository(repo.repository):' | |||||
27 | oldp = p |
|
27 | oldp = p | |
28 | p = os.path.dirname(p) |
|
28 | p = os.path.dirname(p) | |
29 | if p == oldp: |
|
29 | if p == oldp: | |
30 |
raise repo.RepoError(_(" |
|
30 | raise repo.RepoError(_("There is no Mercurial repository" | |
|
31 | " here (.hg not found)")) | |||
31 | path = p |
|
32 | path = p | |
32 | self.path = os.path.join(path, ".hg") |
|
33 | self.path = os.path.join(path, ".hg") | |
33 |
|
34 | |||
34 |
if |
|
35 | if not os.path.isdir(self.path): | |
35 | raise repo.RepoError(_("repository %s not found") % path) |
|
36 | if create: | |
|
37 | if not os.path.exists(path): | |||
|
38 | os.mkdir(path) | |||
|
39 | os.mkdir(self.path) | |||
|
40 | os.mkdir(self.join("data")) | |||
|
41 | else: | |||
|
42 | raise repo.RepoError(_("repository %s not found") % path) | |||
|
43 | elif create: | |||
|
44 | raise repo.RepoError(_("repository %s already exists") % path) | |||
36 |
|
45 | |||
37 | self.root = os.path.abspath(path) |
|
46 | self.root = os.path.abspath(path) | |
38 | self.origroot = path |
|
47 | self.origroot = path | |
@@ -75,12 +84,6 b' class localrepository(repo.repository):' | |||||
75 | self.decodepats = None |
|
84 | self.decodepats = None | |
76 | self.transhandle = None |
|
85 | self.transhandle = None | |
77 |
|
86 | |||
78 | if create: |
|
|||
79 | if not os.path.exists(path): |
|
|||
80 | os.mkdir(path) |
|
|||
81 | os.mkdir(self.path) |
|
|||
82 | os.mkdir(self.join("data")) |
|
|||
83 |
|
||||
84 | self.dirstate = dirstate.dirstate(self.opener, self.ui, self.root) |
|
87 | self.dirstate = dirstate.dirstate(self.opener, self.ui, self.root) | |
85 |
|
88 | |||
86 | def url(self): |
|
89 | def url(self): | |
@@ -131,7 +134,7 b' class localrepository(repo.repository):' | |||||
131 | except Exception, exc: |
|
134 | except Exception, exc: | |
132 | if isinstance(exc, util.Abort): |
|
135 | if isinstance(exc, util.Abort): | |
133 | self.ui.warn(_('error: %s hook failed: %s\n') % |
|
136 | self.ui.warn(_('error: %s hook failed: %s\n') % | |
134 |
(hname, exc.args[0] |
|
137 | (hname, exc.args[0])) | |
135 | else: |
|
138 | else: | |
136 | self.ui.warn(_('error: %s hook raised an exception: ' |
|
139 | self.ui.warn(_('error: %s hook raised an exception: ' | |
137 | '%s\n') % (hname, exc)) |
|
140 | '%s\n') % (hname, exc)) | |
@@ -641,7 +644,11 b' class localrepository(repo.repository):' | |||||
641 | if node: |
|
644 | if node: | |
642 | fdict = dict.fromkeys(files) |
|
645 | fdict = dict.fromkeys(files) | |
643 | for fn in self.manifest.read(self.changelog.read(node)[0]): |
|
646 | for fn in self.manifest.read(self.changelog.read(node)[0]): | |
644 |
fdict |
|
647 | for ffn in fdict: | |
|
648 | # match if the file is the exact name or a directory | |||
|
649 | if ffn == fn or fn.startswith("%s/" % ffn): | |||
|
650 | del fdict[ffn] | |||
|
651 | break | |||
645 | if match(fn): |
|
652 | if match(fn): | |
646 | yield 'm', fn |
|
653 | yield 'm', fn | |
647 | for fn in fdict: |
|
654 | for fn in fdict: |
@@ -50,6 +50,9 b' class diffopts(object):' | |||||
50 | defaultopts = diffopts() |
|
50 | defaultopts = diffopts() | |
51 |
|
51 | |||
52 | def unidiff(a, ad, b, bd, fn, r=None, opts=defaultopts): |
|
52 | def unidiff(a, ad, b, bd, fn, r=None, opts=defaultopts): | |
|
53 | def datetag(date): | |||
|
54 | return opts.git and '\n' or '\t%s\n' % date | |||
|
55 | ||||
53 | if not a and not b: return "" |
|
56 | if not a and not b: return "" | |
54 | epoch = util.datestr((0, 0)) |
|
57 | epoch = util.datestr((0, 0)) | |
55 |
|
58 | |||
@@ -58,19 +61,19 b' def unidiff(a, ad, b, bd, fn, r=None, op' | |||||
58 | elif not a: |
|
61 | elif not a: | |
59 | b = splitnewlines(b) |
|
62 | b = splitnewlines(b) | |
60 | if a is None: |
|
63 | if a is None: | |
61 |
l1 = |
|
64 | l1 = '--- /dev/null%s' % datetag(epoch) | |
62 | else: |
|
65 | else: | |
63 |
l1 = "--- %s |
|
66 | l1 = "--- %s%s" % ("a/" + fn, datetag(ad)) | |
64 |
l2 = "+++ %s |
|
67 | l2 = "+++ %s%s" % ("b/" + fn, datetag(bd)) | |
65 | l3 = "@@ -0,0 +1,%d @@\n" % len(b) |
|
68 | l3 = "@@ -0,0 +1,%d @@\n" % len(b) | |
66 | l = [l1, l2, l3] + ["+" + e for e in b] |
|
69 | l = [l1, l2, l3] + ["+" + e for e in b] | |
67 | elif not b: |
|
70 | elif not b: | |
68 | a = splitnewlines(a) |
|
71 | a = splitnewlines(a) | |
69 |
l1 = "--- %s |
|
72 | l1 = "--- %s%s" % ("a/" + fn, datetag(ad)) | |
70 | if b is None: |
|
73 | if b is None: | |
71 |
l2 = |
|
74 | l2 = '+++ /dev/null%s' % datetag(epoch) | |
72 | else: |
|
75 | else: | |
73 |
l2 = "+++ %s |
|
76 | l2 = "+++ %s%s" % ("b/" + fn, datetag(bd)) | |
74 | l3 = "@@ -1,%d +0,0 @@\n" % len(a) |
|
77 | l3 = "@@ -1,%d +0,0 @@\n" % len(a) | |
75 | l = [l1, l2, l3] + ["-" + e for e in a] |
|
78 | l = [l1, l2, l3] + ["-" + e for e in a] | |
76 | else: |
|
79 | else: | |
@@ -79,8 +82,8 b' def unidiff(a, ad, b, bd, fn, r=None, op' | |||||
79 | l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn, opts=opts)) |
|
82 | l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn, opts=opts)) | |
80 | if not l: return "" |
|
83 | if not l: return "" | |
81 | # difflib uses a space, rather than a tab |
|
84 | # difflib uses a space, rather than a tab | |
82 |
l[0] = "%s |
|
85 | l[0] = "%s%s" % (l[0][:-2], datetag(ad)) | |
83 |
l[1] = "%s |
|
86 | l[1] = "%s%s" % (l[1][:-2], datetag(bd)) | |
84 |
|
87 | |||
85 | for ln in xrange(len(l)): |
|
88 | for ln in xrange(len(l)): | |
86 | if l[ln][-1] != '\n': |
|
89 | if l[ln][-1] != '\n': |
@@ -8,7 +8,7 b'' | |||||
8 | from node import * |
|
8 | from node import * | |
9 | from i18n import gettext as _ |
|
9 | from i18n import gettext as _ | |
10 | from demandload import * |
|
10 | from demandload import * | |
11 | demandload(globals(), "util os tempfile") |
|
11 | demandload(globals(), "errno util os tempfile") | |
12 |
|
12 | |||
13 | def fmerge(f, local, other, ancestor): |
|
13 | def fmerge(f, local, other, ancestor): | |
14 | """merge executable flags""" |
|
14 | """merge executable flags""" | |
@@ -88,12 +88,9 b' def update(repo, node, branchmerge=False' | |||||
88 | if modified or added or removed: |
|
88 | if modified or added or removed: | |
89 | raise util.Abort(_("outstanding uncommitted changes")) |
|
89 | raise util.Abort(_("outstanding uncommitted changes")) | |
90 |
|
90 | |||
91 | m1n = repo.changelog.read(p1)[0] |
|
91 | m1 = repo.changectx(p1).manifest().copy() | |
92 | m2n = repo.changelog.read(p2)[0] |
|
92 | m2 = repo.changectx(p2).manifest().copy() | |
93 |
ma |
|
93 | ma = repo.changectx(pa).manifest() | |
94 | m1 = repo.manifest.read(m1n).copy() |
|
|||
95 | m2 = repo.manifest.read(m2n).copy() |
|
|||
96 | ma = repo.manifest.read(man) |
|
|||
97 |
|
94 | |||
98 | if not force: |
|
95 | if not force: | |
99 | for f in unknown: |
|
96 | for f in unknown: | |
@@ -108,7 +105,7 b' def update(repo, node, branchmerge=False' | |||||
108 | repo.ui.debug(_(" overwrite %s branchmerge %s partial %s linear %s\n") % |
|
105 | repo.ui.debug(_(" overwrite %s branchmerge %s partial %s linear %s\n") % | |
109 | (overwrite, branchmerge, bool(partial), linear_path)) |
|
106 | (overwrite, branchmerge, bool(partial), linear_path)) | |
110 | repo.ui.debug(_(" ancestor %s local %s remote %s\n") % |
|
107 | repo.ui.debug(_(" ancestor %s local %s remote %s\n") % | |
111 |
(short( |
|
108 | (short(p1), short(p2), short(pa))) | |
112 |
|
109 | |||
113 | action = {} |
|
110 | action = {} | |
114 | forget = [] |
|
111 | forget = [] | |
@@ -116,9 +113,10 b' def update(repo, node, branchmerge=False' | |||||
116 | # update m1 from working dir |
|
113 | # update m1 from working dir | |
117 | umap = dict.fromkeys(unknown) |
|
114 | umap = dict.fromkeys(unknown) | |
118 |
|
115 | |||
119 |
for |
|
116 | for i,l in (("a", added), ("m", modified), ("u", unknown)): | |
120 | m1[f] = m1.get(f, nullid) + "+" |
|
117 | for f in l: | |
121 | m1.set(f, util.is_exec(repo.wjoin(f), m1.execf(f))) |
|
118 | m1[f] = m1.get(f, nullid) + i | |
|
119 | m1.set(f, util.is_exec(repo.wjoin(f), m1.execf(f))) | |||
122 |
|
120 | |||
123 | for f in deleted + removed: |
|
121 | for f in deleted + removed: | |
124 | del m1[f] |
|
122 | del m1[f] | |
@@ -157,7 +155,7 b' def update(repo, node, branchmerge=False' | |||||
157 | repo.ui.debug(_(" remote %s is newer, get\n") % f) |
|
155 | repo.ui.debug(_(" remote %s is newer, get\n") % f) | |
158 | action[f] = (m2.execf(f), m2[f], None) |
|
156 | action[f] = (m2.execf(f), m2[f], None) | |
159 | queued = 1 |
|
157 | queued = 1 | |
160 |
elif |
|
158 | elif n[20:] in ("u","a"): | |
161 | # this unknown file is the same as the checkout |
|
159 | # this unknown file is the same as the checkout | |
162 | # we need to reset the dirstate if the file was added |
|
160 | # we need to reset the dirstate if the file was added | |
163 | action[f] = (m2.execf(f), m2[f], None) |
|
161 | action[f] = (m2.execf(f), m2[f], None) | |
@@ -168,7 +166,8 b' def update(repo, node, branchmerge=False' | |||||
168 | repo.ui.debug(_(" updating permissions for %s\n") % f) |
|
166 | repo.ui.debug(_(" updating permissions for %s\n") % f) | |
169 | util.set_exec(repo.wjoin(f), m2.execf(f)) |
|
167 | util.set_exec(repo.wjoin(f), m2.execf(f)) | |
170 | else: |
|
168 | else: | |
171 |
|
|
169 | mode = fmerge(f, m1, m2, ma) | |
|
170 | if mode != m1.execf(f): | |||
172 | repo.ui.debug(_(" updating permissions for %s\n") |
|
171 | repo.ui.debug(_(" updating permissions for %s\n") | |
173 | % f) |
|
172 | % f) | |
174 | util.set_exec(repo.wjoin(f), mode) |
|
173 | util.set_exec(repo.wjoin(f), mode) | |
@@ -187,7 +186,7 b' def update(repo, node, branchmerge=False' | |||||
187 | action[f] = (None, None, None) |
|
186 | action[f] = (None, None, None) | |
188 | else: |
|
187 | else: | |
189 | # file is created on branch or in working directory |
|
188 | # file is created on branch or in working directory | |
190 |
if overwrite and |
|
189 | if overwrite and n[20:] != "u": | |
191 | repo.ui.debug(_("remote deleted %s, clobbering\n") % f) |
|
190 | repo.ui.debug(_("remote deleted %s, clobbering\n") % f) | |
192 | action[f] = (None, None, None) |
|
191 | action[f] = (None, None, None) | |
193 | elif not n[20:]: # same as parent |
|
192 | elif not n[20:]: # same as parent | |
@@ -236,8 +235,7 b' def update(repo, node, branchmerge=False' | |||||
236 | repo.hook('preupdate', throw=True, parent1=xp1, parent2=xxp2) |
|
235 | repo.hook('preupdate', throw=True, parent1=xp1, parent2=xxp2) | |
237 |
|
236 | |||
238 | # update files |
|
237 | # update files | |
239 | unresolved = [] |
|
238 | updated, merged, removed, unresolved = 0, 0, 0, 0 | |
240 | updated, merged, removed = 0, 0, 0 |
|
|||
241 | files = action.keys() |
|
239 | files = action.keys() | |
242 | files.sort() |
|
240 | files.sort() | |
243 | for f in files: |
|
241 | for f in files: | |
@@ -257,7 +255,7 b' def update(repo, node, branchmerge=False' | |||||
257 | elif other: |
|
255 | elif other: | |
258 | repo.ui.status(_("merging %s\n") % f) |
|
256 | repo.ui.status(_("merging %s\n") % f) | |
259 | if merge3(repo, f, my, other, xp1, xp2): |
|
257 | if merge3(repo, f, my, other, xp1, xp2): | |
260 |
unresolved |
|
258 | unresolved += 1 | |
261 | util.set_exec(repo.wjoin(f), flag) |
|
259 | util.set_exec(repo.wjoin(f), flag) | |
262 | merged += 1 |
|
260 | merged += 1 | |
263 | else: |
|
261 | else: | |
@@ -302,9 +300,9 b' def update(repo, node, branchmerge=False' | |||||
302 |
|
300 | |||
303 | if show_stats: |
|
301 | if show_stats: | |
304 | stats = ((updated, _("updated")), |
|
302 | stats = ((updated, _("updated")), | |
305 |
(merged - |
|
303 | (merged - unresolved, _("merged")), | |
306 | (removed, _("removed")), |
|
304 | (removed, _("removed")), | |
307 |
( |
|
305 | (unresolved, _("unresolved"))) | |
308 | note = ", ".join([_("%d files %s") % s for s in stats]) |
|
306 | note = ", ".join([_("%d files %s") % s for s in stats]) | |
309 | repo.ui.status("%s\n" % note) |
|
307 | repo.ui.status("%s\n" % note) | |
310 | if not partial: |
|
308 | if not partial: | |
@@ -322,6 +320,6 b' def update(repo, node, branchmerge=False' | |||||
322 | repo.ui.status(_("There are unresolved merges with" |
|
320 | repo.ui.status(_("There are unresolved merges with" | |
323 | " locally modified files.\n")) |
|
321 | " locally modified files.\n")) | |
324 |
|
322 | |||
325 |
repo.hook('update', parent1=xp1, parent2=xxp2, error= |
|
323 | repo.hook('update', parent1=xp1, parent2=xxp2, error=unresolved) | |
326 |
return |
|
324 | return unresolved | |
327 |
|
325 |
@@ -9,7 +9,8 b' from demandload import demandload' | |||||
9 | from i18n import gettext as _ |
|
9 | from i18n import gettext as _ | |
10 | from node import * |
|
10 | from node import * | |
11 | demandload(globals(), "cmdutil mdiff util") |
|
11 | demandload(globals(), "cmdutil mdiff util") | |
12 |
demandload(globals(), |
|
12 | demandload(globals(), '''cStringIO email.Parser errno os re shutil sys tempfile | |
|
13 | popen2''') | |||
13 |
|
14 | |||
14 | # helper functions |
|
15 | # helper functions | |
15 |
|
16 | |||
@@ -182,7 +183,7 b' def readgitpatch(patchname):' | |||||
182 |
|
183 | |||
183 | return (dopatch, gitpatches) |
|
184 | return (dopatch, gitpatches) | |
184 |
|
185 | |||
185 | def dogitpatch(patchname, gitpatches): |
|
186 | def dogitpatch(patchname, gitpatches, cwd=None): | |
186 | """Preprocess git patch so that vanilla patch can handle it""" |
|
187 | """Preprocess git patch so that vanilla patch can handle it""" | |
187 | pf = file(patchname) |
|
188 | pf = file(patchname) | |
188 | pfline = 1 |
|
189 | pfline = 1 | |
@@ -196,7 +197,7 b' def dogitpatch(patchname, gitpatches):' | |||||
196 | if not p.copymod: |
|
197 | if not p.copymod: | |
197 | continue |
|
198 | continue | |
198 |
|
199 | |||
199 | copyfile(p.oldpath, p.path) |
|
200 | copyfile(p.oldpath, p.path, basedir=cwd) | |
200 |
|
201 | |||
201 | # rewrite patch hunk |
|
202 | # rewrite patch hunk | |
202 | while pfline < p.lineno: |
|
203 | while pfline < p.lineno: | |
@@ -227,23 +228,20 b' def patch(patchname, ui, strip=1, cwd=No' | |||||
227 | """apply the patch <patchname> to the working directory. |
|
228 | """apply the patch <patchname> to the working directory. | |
228 | a list of patched files is returned""" |
|
229 | a list of patched files is returned""" | |
229 |
|
230 | |||
230 | (dopatch, gitpatches) = readgitpatch(patchname) |
|
231 | # helper function | |
|
232 | def __patch(patchname): | |||
|
233 | """patch and updates the files and fuzz variables""" | |||
|
234 | files = {} | |||
|
235 | fuzz = False | |||
231 |
|
236 | |||
232 | files = {} |
|
237 | patcher = util.find_in_path('gpatch', os.environ.get('PATH', ''), | |
233 | fuzz = False |
|
238 | 'patch') | |
234 | if dopatch: |
|
|||
235 | if dopatch == 'filter': |
|
|||
236 | patchname = dogitpatch(patchname, gitpatches) |
|
|||
237 | patcher = util.find_in_path('gpatch', os.environ.get('PATH', ''), 'patch') |
|
|||
238 | args = [] |
|
239 | args = [] | |
239 | if cwd: |
|
240 | if cwd: | |
240 | args.append('-d %s' % util.shellquote(cwd)) |
|
241 | args.append('-d %s' % util.shellquote(cwd)) | |
241 | fp = os.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip, |
|
242 | fp = os.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip, | |
242 | util.shellquote(patchname))) |
|
243 | util.shellquote(patchname))) | |
243 |
|
244 | |||
244 | if dopatch == 'filter': |
|
|||
245 | False and os.unlink(patchname) |
|
|||
246 |
|
||||
247 | for line in fp: |
|
245 | for line in fp: | |
248 | line = line.rstrip() |
|
246 | line = line.rstrip() | |
249 | ui.note(line + '\n') |
|
247 | ui.note(line + '\n') | |
@@ -264,11 +262,24 b' def patch(patchname, ui, strip=1, cwd=No' | |||||
264 | ui.warn(pf + '\n') |
|
262 | ui.warn(pf + '\n') | |
265 | printed_file = True |
|
263 | printed_file = True | |
266 | ui.warn(line + '\n') |
|
264 | ui.warn(line + '\n') | |
267 |
|
||||
268 | code = fp.close() |
|
265 | code = fp.close() | |
269 | if code: |
|
266 | if code: | |
270 | raise util.Abort(_("patch command failed: %s") % |
|
267 | raise util.Abort(_("patch command failed: %s") % | |
271 | util.explain_exit(code)[0]) |
|
268 | util.explain_exit(code)[0]) | |
|
269 | return files, fuzz | |||
|
270 | ||||
|
271 | (dopatch, gitpatches) = readgitpatch(patchname) | |||
|
272 | ||||
|
273 | if dopatch: | |||
|
274 | if dopatch == 'filter': | |||
|
275 | patchname = dogitpatch(patchname, gitpatches, cwd=cwd) | |||
|
276 | try: | |||
|
277 | files, fuzz = __patch(patchname) | |||
|
278 | finally: | |||
|
279 | if dopatch == 'filter': | |||
|
280 | os.unlink(patchname) | |||
|
281 | else: | |||
|
282 | files, fuzz = {}, False | |||
272 |
|
283 | |||
273 | for gp in gitpatches: |
|
284 | for gp in gitpatches: | |
274 | files[gp.path] = (gp.op, gp) |
|
285 | files[gp.path] = (gp.op, gp) | |
@@ -492,7 +503,10 b' def diff(repo, node1=None, node2=None, f' | |||||
492 | header.append('deleted file mode %s\n' % mode) |
|
503 | header.append('deleted file mode %s\n' % mode) | |
493 | else: |
|
504 | else: | |
494 | omode = gitmode(mmap.execf(f)) |
|
505 | omode = gitmode(mmap.execf(f)) | |
495 | nmode = gitmode(util.is_exec(repo.wjoin(f), mmap.execf(f))) |
|
506 | if node2: | |
|
507 | nmode = gitmode(mmap2.execf(f)) | |||
|
508 | else: | |||
|
509 | nmode = gitmode(util.is_exec(repo.wjoin(f), mmap.execf(f))) | |||
496 | addmodehdr(header, omode, nmode) |
|
510 | addmodehdr(header, omode, nmode) | |
497 | r = None |
|
511 | r = None | |
498 | if dodiff: |
|
512 | if dodiff: | |
@@ -537,3 +551,24 b" def export(repo, revs, template='hg-%h.p" | |||||
537 |
|
551 | |||
538 | for seqno, cset in enumerate(revs): |
|
552 | for seqno, cset in enumerate(revs): | |
539 | single(cset, seqno, fp) |
|
553 | single(cset, seqno, fp) | |
|
554 | ||||
|
555 | def diffstat(patchlines): | |||
|
556 | fd, name = tempfile.mkstemp(prefix="hg-patchbomb-", suffix=".txt") | |||
|
557 | try: | |||
|
558 | p = popen2.Popen3('diffstat -p1 -w79 2>/dev/null > ' + name) | |||
|
559 | try: | |||
|
560 | for line in patchlines: print >> p.tochild, line | |||
|
561 | p.tochild.close() | |||
|
562 | if p.wait(): return | |||
|
563 | fp = os.fdopen(fd, 'r') | |||
|
564 | stat = [] | |||
|
565 | for line in fp: stat.append(line.lstrip()) | |||
|
566 | last = stat.pop() | |||
|
567 | stat.insert(0, last) | |||
|
568 | stat = ''.join(stat) | |||
|
569 | if stat.startswith('0 files'): raise ValueError | |||
|
570 | return stat | |||
|
571 | except: raise | |||
|
572 | finally: | |||
|
573 | try: os.unlink(name) | |||
|
574 | except: pass |
@@ -139,6 +139,11 b' class lazyparser(object):' | |||||
139 | if self.all: return |
|
139 | if self.all: return | |
140 | if data is None: |
|
140 | if data is None: | |
141 | self.dataf.seek(blockstart) |
|
141 | self.dataf.seek(blockstart) | |
|
142 | if blockstart + blocksize > self.datasize: | |||
|
143 | # the revlog may have grown since we've started running, | |||
|
144 | # but we don't have space in self.index for more entries. | |||
|
145 | # limit blocksize so that we don't get too much data. | |||
|
146 | blocksize = max(self.datasize - blockstart, 0) | |||
142 | data = self.dataf.read(blocksize) |
|
147 | data = self.dataf.read(blocksize) | |
143 | lend = len(data) / self.s |
|
148 | lend = len(data) / self.s | |
144 | i = blockstart / self.s |
|
149 | i = blockstart / self.s |
@@ -32,12 +32,6 b' class sshrepository(remoterepository):' | |||||
32 | remotecmd = self.ui.config("ui", "remotecmd", "hg") |
|
32 | remotecmd = self.ui.config("ui", "remotecmd", "hg") | |
33 |
|
33 | |||
34 | if create: |
|
34 | if create: | |
35 | try: |
|
|||
36 | self.validate_repo(ui, sshcmd, args, remotecmd) |
|
|||
37 | return # the repo is good, nothing more to do |
|
|||
38 | except hg.RepoError: |
|
|||
39 | pass |
|
|||
40 |
|
||||
41 | cmd = '%s %s "%s init %s"' |
|
35 | cmd = '%s %s "%s init %s"' | |
42 | cmd = cmd % (sshcmd, args, remotecmd, self.path) |
|
36 | cmd = cmd % (sshcmd, args, remotecmd, self.path) | |
43 |
|
37 | |||
@@ -52,6 +46,9 b' class sshrepository(remoterepository):' | |||||
52 | return self._url |
|
46 | return self._url | |
53 |
|
47 | |||
54 | def validate_repo(self, ui, sshcmd, args, remotecmd): |
|
48 | def validate_repo(self, ui, sshcmd, args, remotecmd): | |
|
49 | # cleanup up previous run | |||
|
50 | self.cleanup() | |||
|
51 | ||||
55 | cmd = '%s %s "%s -R %s serve --stdio"' |
|
52 | cmd = '%s %s "%s -R %s serve --stdio"' | |
56 | cmd = cmd % (sshcmd, args, remotecmd, self.path) |
|
53 | cmd = cmd % (sshcmd, args, remotecmd, self.path) | |
57 |
|
54 | |||
@@ -90,7 +87,7 b' class sshrepository(remoterepository):' | |||||
90 | if not l: break |
|
87 | if not l: break | |
91 | self.ui.status(_("remote: "), l) |
|
88 | self.ui.status(_("remote: "), l) | |
92 |
|
89 | |||
93 |
def |
|
90 | def cleanup(self): | |
94 | try: |
|
91 | try: | |
95 | self.pipeo.close() |
|
92 | self.pipeo.close() | |
96 | self.pipei.close() |
|
93 | self.pipei.close() | |
@@ -101,6 +98,8 b' class sshrepository(remoterepository):' | |||||
101 | except: |
|
98 | except: | |
102 | pass |
|
99 | pass | |
103 |
|
100 | |||
|
101 | __del__ = cleanup | |||
|
102 | ||||
104 | def do_cmd(self, cmd, **args): |
|
103 | def do_cmd(self, cmd, **args): | |
105 | self.ui.debug(_("sending %s command\n") % cmd) |
|
104 | self.ui.debug(_("sending %s command\n") % cmd) | |
106 | self.pipeo.write("%s\n" % cmd) |
|
105 | self.pipeo.write("%s\n" % cmd) |
@@ -12,13 +12,12 b' demandload(globals(), "ConfigParser mdif' | |||||
12 |
|
12 | |||
13 | class ui(object): |
|
13 | class ui(object): | |
14 | def __init__(self, verbose=False, debug=False, quiet=False, |
|
14 | def __init__(self, verbose=False, debug=False, quiet=False, | |
15 |
interactive=True, traceback=False, parentui=None |
|
15 | interactive=True, traceback=False, parentui=None): | |
16 | readhooks=[]): |
|
|||
17 | self.overlay = {} |
|
16 | self.overlay = {} | |
18 | if parentui is None: |
|
17 | if parentui is None: | |
19 | # this is the parent of all ui children |
|
18 | # this is the parent of all ui children | |
20 | self.parentui = None |
|
19 | self.parentui = None | |
21 |
self.readhooks = |
|
20 | self.readhooks = [] | |
22 | self.cdata = ConfigParser.SafeConfigParser() |
|
21 | self.cdata = ConfigParser.SafeConfigParser() | |
23 | self.readconfig(util.rcpath()) |
|
22 | self.readconfig(util.rcpath()) | |
24 |
|
23 | |||
@@ -36,7 +35,7 b' class ui(object):' | |||||
36 | else: |
|
35 | else: | |
37 | # parentui may point to an ui object which is already a child |
|
36 | # parentui may point to an ui object which is already a child | |
38 | self.parentui = parentui.parentui or parentui |
|
37 | self.parentui = parentui.parentui or parentui | |
39 |
self.readhooks = |
|
38 | self.readhooks = parentui.readhooks[:] | |
40 | parent_cdata = self.parentui.cdata |
|
39 | parent_cdata = self.parentui.cdata | |
41 | self.cdata = ConfigParser.SafeConfigParser(parent_cdata.defaults()) |
|
40 | self.cdata = ConfigParser.SafeConfigParser(parent_cdata.defaults()) | |
42 | # make interpolation work |
|
41 | # make interpolation work | |
@@ -51,7 +50,7 b' class ui(object):' | |||||
51 | def updateopts(self, verbose=False, debug=False, quiet=False, |
|
50 | def updateopts(self, verbose=False, debug=False, quiet=False, | |
52 | interactive=True, traceback=False, config=[]): |
|
51 | interactive=True, traceback=False, config=[]): | |
53 | self.quiet = (self.quiet or quiet) and not verbose and not debug |
|
52 | self.quiet = (self.quiet or quiet) and not verbose and not debug | |
54 | self.verbose = (self.verbose or verbose) or debug |
|
53 | self.verbose = ((self.verbose or verbose) or debug) and not self.quiet | |
55 | self.debugflag = (self.debugflag or debug) |
|
54 | self.debugflag = (self.debugflag or debug) | |
56 | self.interactive = (self.interactive and interactive) |
|
55 | self.interactive = (self.interactive and interactive) | |
57 | self.traceback = self.traceback or traceback |
|
56 | self.traceback = self.traceback or traceback | |
@@ -84,6 +83,9 b' class ui(object):' | |||||
84 | for hook in self.readhooks: |
|
83 | for hook in self.readhooks: | |
85 | hook(self) |
|
84 | hook(self) | |
86 |
|
85 | |||
|
86 | def addreadhook(self, hook): | |||
|
87 | self.readhooks.append(hook) | |||
|
88 | ||||
87 | def setconfig(self, section, name, val): |
|
89 | def setconfig(self, section, name, val): | |
88 | self.overlay[(section, name)] = val |
|
90 | self.overlay[(section, name)] = val | |
89 |
|
91 | |||
@@ -94,7 +96,9 b' class ui(object):' | |||||
94 | try: |
|
96 | try: | |
95 | return self.cdata.get(section, name) |
|
97 | return self.cdata.get(section, name) | |
96 | except ConfigParser.InterpolationError, inst: |
|
98 | except ConfigParser.InterpolationError, inst: | |
97 |
raise util.Abort(_("Error in configuration |
|
99 | raise util.Abort(_("Error in configuration section [%s] " | |
|
100 | "parameter '%s':\n%s") | |||
|
101 | % (section, name, inst)) | |||
98 | if self.parentui is None: |
|
102 | if self.parentui is None: | |
99 | return default |
|
103 | return default | |
100 | else: |
|
104 | else: | |
@@ -116,7 +120,9 b' class ui(object):' | |||||
116 | try: |
|
120 | try: | |
117 | return self.cdata.getboolean(section, name) |
|
121 | return self.cdata.getboolean(section, name) | |
118 | except ConfigParser.InterpolationError, inst: |
|
122 | except ConfigParser.InterpolationError, inst: | |
119 |
raise util.Abort(_("Error in configuration |
|
123 | raise util.Abort(_("Error in configuration section [%s] " | |
|
124 | "parameter '%s':\n%s") | |||
|
125 | % (section, name, inst)) | |||
120 | if self.parentui is None: |
|
126 | if self.parentui is None: | |
121 | return default |
|
127 | return default | |
122 | else: |
|
128 | else: | |
@@ -134,7 +140,8 b' class ui(object):' | |||||
134 | try: |
|
140 | try: | |
135 | items.update(dict(self.cdata.items(section))) |
|
141 | items.update(dict(self.cdata.items(section))) | |
136 | except ConfigParser.InterpolationError, inst: |
|
142 | except ConfigParser.InterpolationError, inst: | |
137 |
raise util.Abort(_("Error in configuration:\n%s") |
|
143 | raise util.Abort(_("Error in configuration section [%s]:\n%s") | |
|
144 | % (section, inst)) | |||
138 | x = items.items() |
|
145 | x = items.items() | |
139 | x.sort() |
|
146 | x.sort() | |
140 | return x |
|
147 | return x | |
@@ -146,10 +153,14 b' class ui(object):' | |||||
146 | yield section, name, value |
|
153 | yield section, name, value | |
147 | seen[section, name] = 1 |
|
154 | seen[section, name] = 1 | |
148 | for section in self.cdata.sections(): |
|
155 | for section in self.cdata.sections(): | |
149 | for name, value in self.cdata.items(section): |
|
156 | try: | |
150 | if (section, name) in seen: continue |
|
157 | for name, value in self.cdata.items(section): | |
151 | yield section, name, value.replace('\n', '\\n') |
|
158 | if (section, name) in seen: continue | |
152 |
|
|
159 | yield section, name, value.replace('\n', '\\n') | |
|
160 | seen[section, name] = 1 | |||
|
161 | except ConfigParser.InterpolationError, inst: | |||
|
162 | raise util.Abort(_("Error in configuration section [%s]:\n%s") | |||
|
163 | % (section, inst)) | |||
153 | if self.parentui is not None: |
|
164 | if self.parentui is not None: | |
154 | for parent in self.parentui.walkconfig(seen): |
|
165 | for parent in self.parentui.walkconfig(seen): | |
155 | yield parent |
|
166 | yield parent |
@@ -8,7 +8,7 b' error = error-gitweb.tmpl' | |||||
8 | naventry = '<a href="?cmd=changelog;rev=#rev#;style=gitweb">#label|escape#</a> ' |
|
8 | naventry = '<a href="?cmd=changelog;rev=#rev#;style=gitweb">#label|escape#</a> ' | |
9 | navshortentry = '<a href="?cmd=shortlog;rev=#rev#;style=gitweb">#label|escape#</a> ' |
|
9 | navshortentry = '<a href="?cmd=shortlog;rev=#rev#;style=gitweb">#label|escape#</a> ' | |
10 | filedifflink = '<a href="?cmd=filediff;node=#node#;file=#file|urlescape#;style=gitweb">#file|escape#</a> ' |
|
10 | filedifflink = '<a href="?cmd=filediff;node=#node#;file=#file|urlescape#;style=gitweb">#file|escape#</a> ' | |
11 | filenodelink = '<tr class="light"><td><a class="list" href="">#file|escape#</a></td><td></td><td class="link"><a href="?cmd=file;filenode=#filenode#;file=#file|urlescape#;style=gitweb">file</a> | <!-- FIXME: <a href="?fd=#filenode|short#;file=#file|urlescape#;style=gitweb">diff</a> | --> <a href="?cmd=filelog;filenode=#filenode|short#;file=#file|urlescape#;style=gitweb">revisions</a></td></tr>' |
|
11 | filenodelink = '<tr class="light"><td><a class="list" href="">#file|escape#</a></td><td></td><td class="link"><a href="?cmd=file;filenode=#filenode#;file=#file|urlescape#;style=gitweb">file</a> | <a href="?fa=#filenode|short#;file=#file|urlescape#;style=gitweb">annotate</a> | <!-- FIXME: <a href="?fd=#filenode|short#;file=#file|urlescape#;style=gitweb">diff</a> | --> <a href="?cmd=filelog;filenode=#filenode|short#;file=#file|urlescape#;style=gitweb">revisions</a></td></tr>' | |
12 | fileellipses = '...' |
|
12 | fileellipses = '...' | |
13 | changelogentry = changelogentry-gitweb.tmpl |
|
13 | changelogentry = changelogentry-gitweb.tmpl | |
14 | searchentry = changelogentry-gitweb.tmpl |
|
14 | searchentry = changelogentry-gitweb.tmpl | |
@@ -19,12 +19,12 b' manifestfileentry = \'<tr class="parity#p' | |||||
19 | filerevision = filerevision-gitweb.tmpl |
|
19 | filerevision = filerevision-gitweb.tmpl | |
20 | fileannotate = fileannotate-gitweb.tmpl |
|
20 | fileannotate = fileannotate-gitweb.tmpl | |
21 | filelog = filelog-gitweb.tmpl |
|
21 | filelog = filelog-gitweb.tmpl | |
22 |
fileline = '<div style="font-family:monospace |
|
22 | fileline = '<div style="font-family:monospace" class="parity#parity#"><pre><span class="linenr"> #linenumber#</span> #line|escape#</pre></div>' | |
23 | annotateline = '<tr style="font-family:monospace; white-space: pre;" class="parity#parity#"><td class="linenr" style="text-align: right;"><a href="?cs=#node|short#;style=gitweb">#author|obfuscate#@#rev#</a></td><td>#line|escape#</td></tr>' |
|
23 | annotateline = '<tr style="font-family:monospace" class="parity#parity#"><td class="linenr" style="text-align: right;"><a href="?cs=#node|short#;style=gitweb">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>' | |
24 |
difflineplus = '<div |
|
24 | difflineplus = '<div style="color:#008800;">#line|escape#</div>' | |
25 |
difflineminus = '<div |
|
25 | difflineminus = '<div style="color:#cc0000;">#line|escape#</div>' | |
26 |
difflineat = '<div |
|
26 | difflineat = '<div style="color:#990099;">#line|escape#</div>' | |
27 |
diffline = '<div |
|
27 | diffline = '<div>#line|escape#</div>' | |
28 | changelogparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cmd=changeset;node=#node#;style=gitweb">#node|short#</a></td></tr>' |
|
28 | changelogparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cmd=changeset;node=#node#;style=gitweb">#node|short#</a></td></tr>' | |
29 | changesetparent = '<tr><td>parent</td><td style="font-family:monospace"><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb">#node|short#</a></td></tr>' |
|
29 | changesetparent = '<tr><td>parent</td><td style="font-family:monospace"><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb">#node|short#</a></td></tr>' | |
30 | filerevparent = '<tr><td class="metatag">parent:</td><td><a href="?cmd=file;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>' |
|
30 | filerevparent = '<tr><td class="metatag">parent:</td><td><a href="?cmd=file;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>' | |
@@ -37,7 +37,7 b' filerevchild = \'<tr><td class="metatag">' | |||||
37 | fileannotatechild = '<tr><td class="metatag">child:</td><td><a href="?cmd=annotate;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>' |
|
37 | fileannotatechild = '<tr><td class="metatag">child:</td><td><a href="?cmd=annotate;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>' | |
38 | tags = tags-gitweb.tmpl |
|
38 | tags = tags-gitweb.tmpl | |
39 | tagentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#tag|escape#</b></a></td><td class="link"><a href="?cmd=changeset;node=#node|short#;style=gitweb">changeset</a> | <a href="?cmd=changelog;rev=#node|short#;style=gitweb">changelog</a> | <a href="?mf=#tagmanifest|short#;path=/;style=gitweb">manifest</a></td></tr>' |
|
39 | tagentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#tag|escape#</b></a></td><td class="link"><a href="?cmd=changeset;node=#node|short#;style=gitweb">changeset</a> | <a href="?cmd=changelog;rev=#node|short#;style=gitweb">changelog</a> | <a href="?mf=#tagmanifest|short#;path=/;style=gitweb">manifest</a></td></tr>' | |
40 | diffblock = '#lines#' |
|
40 | diffblock = '<pre>#lines#</pre>' | |
41 | changelogtag = '<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>' |
|
41 | changelogtag = '<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>' | |
42 | changesettag = '<tr><td>tag</td><td>#tag|escape#</td></tr>' |
|
42 | changesettag = '<tr><td>tag</td><td>#tag|escape#</td></tr>' | |
43 | filediffparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cmd=changeset;node=#node#;style=gitweb">#node|short#</a></td></tr>' |
|
43 | filediffparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cmd=changeset;node=#node#;style=gitweb">#node|short#</a></td></tr>' | |
@@ -46,5 +46,5 b' filediffchild = \'<tr><th class="child">c' | |||||
46 | filelogchild = '<tr><td align="right">child #rev#: </td><td><a href="?cmd=file;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>' |
|
46 | filelogchild = '<tr><td align="right">child #rev#: </td><td><a href="?cmd=file;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>' | |
47 | shortlog = shortlog-gitweb.tmpl |
|
47 | shortlog = shortlog-gitweb.tmpl | |
48 | shortlogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><i>#author#</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><a href="?cmd=changeset;node=#node|short#;style=gitweb">changeset</a> | <a href="?cmd=manifest;manifest=#manifest|short#;path=/;style=gitweb">manifest</a></td></tr>' |
|
48 | shortlogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><i>#author#</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><a href="?cmd=changeset;node=#node|short#;style=gitweb">changeset</a> | <a href="?cmd=manifest;manifest=#manifest|short#;path=/;style=gitweb">manifest</a></td></tr>' | |
49 | filelogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><!-- FIXME: <a href="?fd=#node|short#;file=#file|urlescape#;style=gitweb">diff</a> | --> <a href="?fa=#filenode|short#;file=#file|urlescape#;style=gitweb">annotate</a> #rename%filelogrename#</td></tr>' |
|
49 | filelogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><a href="?f=#node|short#;file=#file|urlescape#;style=gitweb">file</a> | <!-- FIXME: <a href="?fd=#node|short#;file=#file|urlescape#;style=gitweb">diff</a> | --> <a href="?fa=#filenode|short#;file=#file|urlescape#;style=gitweb">annotate</a> #rename%filelogrename#</td></tr>' | |
50 | archiveentry = ' | <a href="?ca=#node|short#;type=#type|urlescape#">#type|escape#</a> ' |
|
50 | archiveentry = ' | <a href="?ca=#node|short#;type=#type|urlescape#">#type|escape#</a> ' |
@@ -47,3 +47,4 b' a.rss_logo {' | |||||
47 | text-align:center; text-decoration:none; |
|
47 | text-align:center; text-decoration:none; | |
48 | } |
|
48 | } | |
49 | a.rss_logo:hover { background-color:#ee5500; } |
|
49 | a.rss_logo:hover { background-color:#ee5500; } | |
|
50 | pre { margin: 0; } |
@@ -59,9 +59,9 b' 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:4' | |||||
59 | line 1 |
|
59 | line 1 | |
60 |
|
60 | |||
61 | # error if style not readable |
|
61 | # error if style not readable | |
62 |
abort: Permission denied |
|
62 | abort: Permission denied: ./q | |
63 | # error if no style |
|
63 | # error if no style | |
64 |
abort: No such file or directory |
|
64 | abort: No such file or directory: notexist | |
65 | # error if style missing key |
|
65 | # error if style missing key | |
66 | abort: ./t: no key named 'changeset' |
|
66 | abort: ./t: no key named 'changeset' | |
67 | # error if include fails |
|
67 | # error if include fails |
@@ -17,7 +17,7 b' foo-b' | |||||
17 | A b |
|
17 | A b | |
18 | R a |
|
18 | R a | |
19 | %%% revert should fail |
|
19 | %%% revert should fail | |
20 | abort: working dir has two parents; you must specify the revision to revert to |
|
20 | abort: uncommitted merge - please provide a specific revision | |
21 | %%% revert should be ok now |
|
21 | %%% revert should be ok now | |
22 | undeleting a |
|
22 | undeleting a | |
23 | forgetting b |
|
23 | forgetting b |
@@ -50,3 +50,7 b" hg ci -mrenamemod -d '0 0'" | |||||
50 | echo '% rename+mod+chmod' |
|
50 | echo '% rename+mod+chmod' | |
51 | hg diff --git -r 6:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ |
|
51 | hg diff --git -r 6:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |
52 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" |
|
52 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |
|
53 | ||||
|
54 | echo '% nonexistent in tip+chmod' | |||
|
55 | hg diff --git -r 5:6 | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
56 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" |
@@ -40,3 +40,7 b' rename to dst' | |||||
40 | 4 |
|
40 | 4 | |
41 | 5 |
|
41 | 5 | |
42 | +a |
|
42 | +a | |
|
43 | % nonexistent in tip+chmod | |||
|
44 | diff --git a/src b/src | |||
|
45 | old mode 100644 | |||
|
46 | new mode 100755 |
@@ -11,7 +11,7 b' cat hg1.pid hg2.pid >> $DAEMON_PIDS' | |||||
11 |
|
11 | |||
12 | echo % clone via stream |
|
12 | echo % clone via stream | |
13 | http_proxy= hg clone --uncompressed http://localhost:20059/ copy 2>&1 | \ |
|
13 | http_proxy= hg clone --uncompressed http://localhost:20059/ copy 2>&1 | \ | |
14 |
sed -e 's/[0-9][0-9.]*/XXX/g' -e 's/ |
|
14 | sed -e 's/[0-9][0-9.]*/XXX/g' -e 's/[KM]\(B\/sec\)/X\1/' | |
15 | hg verify -R copy |
|
15 | hg verify -R copy | |
16 |
|
16 | |||
17 | echo % try to clone via stream, should use pull instead |
|
17 | echo % try to clone via stream, should use pull instead |
@@ -15,7 +15,7 b' sleep 2' | |||||
15 |
|
15 | |||
16 | echo %% url for proxy, stream |
|
16 | echo %% url for proxy, stream | |
17 | http_proxy=http://localhost:20060/ hg --config http_proxy.always=True clone --uncompressed http://localhost:20059/ b | \ |
|
17 | http_proxy=http://localhost:20060/ hg --config http_proxy.always=True clone --uncompressed http://localhost:20059/ b | \ | |
18 | sed -e 's/[0-9][0-9.]*/XXX/g' |
|
18 | sed -e 's/[0-9][0-9.]*/XXX/g' -e 's/[KM]\(B\/sec\)/X\1/' | |
19 | cd b |
|
19 | cd b | |
20 | hg verify |
|
20 | hg verify | |
21 | cd .. |
|
21 | cd .. |
@@ -2,7 +2,7 b' adding a' | |||||
2 | %% url for proxy, stream |
|
2 | %% url for proxy, stream | |
3 | streaming all changes |
|
3 | streaming all changes | |
4 | XXX files to transfer, XXX bytes of data |
|
4 | XXX files to transfer, XXX bytes of data | |
5 |
transferred XXX bytes in XXX seconds (XXX |
|
5 | transferred XXX bytes in XXX seconds (XXX XB/sec) | |
6 | XXX files updated, XXX files merged, XXX files removed, XXX files unresolved |
|
6 | XXX files updated, XXX files merged, XXX files removed, XXX files unresolved | |
7 | checking changesets |
|
7 | checking changesets | |
8 | checking manifests |
|
8 | checking manifests |
@@ -27,6 +27,9 b' hg init local' | |||||
27 | echo this > local/foo |
|
27 | echo this > local/foo | |
28 | hg ci --cwd local -A -m "init" -d "1000000 0" |
|
28 | hg ci --cwd local -A -m "init" -d "1000000 0" | |
29 |
|
29 | |||
|
30 | echo "#test failure" | |||
|
31 | hg init local | |||
|
32 | ||||
30 | echo "# init+push to remote2" |
|
33 | echo "# init+push to remote2" | |
31 | hg init -e ./dummyssh ssh://user@dummy/remote2 |
|
34 | hg init -e ./dummyssh ssh://user@dummy/remote2 | |
32 | hg incoming -R remote2 local |
|
35 | hg incoming -R remote2 local | |
@@ -35,6 +38,12 b' hg push -R local -e ./dummyssh ssh://use' | |||||
35 | echo "# clone to remote1" |
|
38 | echo "# clone to remote1" | |
36 | hg clone -e ./dummyssh local ssh://user@dummy/remote1 |
|
39 | hg clone -e ./dummyssh local ssh://user@dummy/remote1 | |
37 |
|
40 | |||
|
41 | echo "# init to existing repo" | |||
|
42 | hg init -e ./dummyssh ssh://user@dummy/remote1 | |||
|
43 | ||||
|
44 | echo "# clone to existing repo" | |||
|
45 | hg clone -e ./dummyssh local ssh://user@dummy/remote1 | |||
|
46 | ||||
38 | echo "# output of dummyssh" |
|
47 | echo "# output of dummyssh" | |
39 | cat dummylog |
|
48 | cat dummylog | |
40 |
|
49 |
@@ -1,5 +1,7 b'' | |||||
1 | # creating 'local' |
|
1 | # creating 'local' | |
2 | adding foo |
|
2 | adding foo | |
|
3 | #test failure | |||
|
4 | abort: repository local already exists! | |||
3 | # init+push to remote2 |
|
5 | # init+push to remote2 | |
4 | changeset: 0:c4e059d443be |
|
6 | changeset: 0:c4e059d443be | |
5 | tag: tip |
|
7 | tag: tip | |
@@ -15,20 +17,24 b' remote: adding file changes' | |||||
15 | remote: added 1 changesets with 1 changes to 1 files |
|
17 | remote: added 1 changesets with 1 changes to 1 files | |
16 | # clone to remote1 |
|
18 | # clone to remote1 | |
17 | searching for changes |
|
19 | searching for changes | |
18 | remote: abort: repository remote1 not found! |
|
|||
19 | remote: adding changesets |
|
20 | remote: adding changesets | |
20 | remote: adding manifests |
|
21 | remote: adding manifests | |
21 | remote: adding file changes |
|
22 | remote: adding file changes | |
22 | remote: added 1 changesets with 1 changes to 1 files |
|
23 | remote: added 1 changesets with 1 changes to 1 files | |
|
24 | # init to existing repo | |||
|
25 | abort: repository remote1 already exists! | |||
|
26 | abort: could not create remote repo! | |||
|
27 | # clone to existing repo | |||
|
28 | abort: repository remote1 already exists! | |||
|
29 | abort: could not create remote repo! | |||
23 | # output of dummyssh |
|
30 | # output of dummyssh | |
24 | Got arguments 1:user@dummy 2:hg -R remote2 serve --stdio 3: 4: 5: |
|
|||
25 | Got arguments 1:user@dummy 2:hg init remote2 3: 4: 5: |
|
31 | Got arguments 1:user@dummy 2:hg init remote2 3: 4: 5: | |
26 | Got arguments 1:user@dummy 2:hg -R remote2 serve --stdio 3: 4: 5: |
|
32 | Got arguments 1:user@dummy 2:hg -R remote2 serve --stdio 3: 4: 5: | |
27 | Got arguments 1:user@dummy 2:hg -R remote2 serve --stdio 3: 4: 5: |
|
33 | Got arguments 1:user@dummy 2:hg -R remote2 serve --stdio 3: 4: 5: | |
28 |
Got arguments 1:user@dummy 2:hg |
|
34 | Got arguments 1:user@dummy 2:hg init remote1 3: 4: 5: | |
29 | Got arguments 1:user@dummy 2:hg -R remote1 serve --stdio 3: 4: 5: |
|
35 | Got arguments 1:user@dummy 2:hg -R remote1 serve --stdio 3: 4: 5: | |
30 | Got arguments 1:user@dummy 2:hg init remote1 3: 4: 5: |
|
36 | Got arguments 1:user@dummy 2:hg init remote1 3: 4: 5: | |
31 |
Got arguments 1:user@dummy 2:hg |
|
37 | Got arguments 1:user@dummy 2:hg init remote1 3: 4: 5: | |
32 | # comparing repositories |
|
38 | # comparing repositories | |
33 | 0:c4e059d443be |
|
39 | 0:c4e059d443be | |
34 | 0:c4e059d443be |
|
40 | 0:c4e059d443be |
@@ -23,7 +23,7 b' added 1 changesets with 1 changes to 1 f' | |||||
23 | merge: warning: conflicts during merge |
|
23 | merge: warning: conflicts during merge | |
24 | resolving manifests |
|
24 | resolving manifests | |
25 | overwrite None branchmerge True partial False linear False |
|
25 | overwrite None branchmerge True partial False linear False | |
26 | ancestor 055d847dd401 local 2eded9ab0a5c remote 84cf5750dd20 |
|
26 | ancestor 451c744aabcc local a070d41e8360 remote faaea63e63a9 | |
27 | test.txt versions differ, resolve |
|
27 | test.txt versions differ, resolve | |
28 | merging test.txt |
|
28 | merging test.txt | |
29 | resolving test.txt |
|
29 | resolving test.txt |
@@ -115,6 +115,19 b' hg push ../../k' | |||||
115 | echo % qunapplied |
|
115 | echo % qunapplied | |
116 | hg qunapplied |
|
116 | hg qunapplied | |
117 |
|
117 | |||
|
118 | echo % qpush/qpop with index | |||
|
119 | hg qnew test1b.patch | |||
|
120 | echo 1b > 1b | |||
|
121 | hg add 1b | |||
|
122 | hg qrefresh | |||
|
123 | hg qpush 2 | |||
|
124 | hg qpop 0 | |||
|
125 | hg qpush test.patch+1 | |||
|
126 | hg qpush test.patch+2 | |||
|
127 | hg qpop test2.patch-1 | |||
|
128 | hg qpop test2.patch-2 | |||
|
129 | hg qpush test1b.patch+1 | |||
|
130 | ||||
118 | echo % push should succeed |
|
131 | echo % push should succeed | |
119 | hg qpop -a |
|
132 | hg qpop -a | |
120 | hg push ../../k |
|
133 | hg push ../../k | |
@@ -126,6 +139,27 b' hg ci -Ama' | |||||
126 | hg strip tip 2>&1 | sed 's/\(saving bundle to \).*/\1/' |
|
139 | hg strip tip 2>&1 | sed 's/\(saving bundle to \).*/\1/' | |
127 | hg unbundle .hg/strip-backup/* |
|
140 | hg unbundle .hg/strip-backup/* | |
128 |
|
141 | |||
|
142 | echo '% cd b; hg qrefresh' | |||
|
143 | hg init refresh | |||
|
144 | cd refresh | |||
|
145 | echo a > a | |||
|
146 | hg ci -Ama -d'0 0' | |||
|
147 | hg qnew -mfoo foo | |||
|
148 | echo a >> a | |||
|
149 | hg qrefresh | |||
|
150 | mkdir b | |||
|
151 | cd b | |||
|
152 | echo f > f | |||
|
153 | hg add f | |||
|
154 | hg qrefresh | |||
|
155 | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
156 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" ../.hg/patches/foo | |||
|
157 | echo % hg qrefresh . | |||
|
158 | hg qrefresh . | |||
|
159 | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
160 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" ../.hg/patches/foo | |||
|
161 | hg status | |||
|
162 | ||||
129 | cat >>$HGRCPATH <<EOF |
|
163 | cat >>$HGRCPATH <<EOF | |
130 | [diff] |
|
164 | [diff] | |
131 | git = True |
|
165 | git = True |
@@ -110,6 +110,19 b' pushing to ../../k' | |||||
110 | abort: source has mq patches applied |
|
110 | abort: source has mq patches applied | |
111 | % qunapplied |
|
111 | % qunapplied | |
112 | test2.patch |
|
112 | test2.patch | |
|
113 | % qpush/qpop with index | |||
|
114 | applying test2.patch | |||
|
115 | Now at: test2.patch | |||
|
116 | Now at: test.patch | |||
|
117 | applying test1b.patch | |||
|
118 | Now at: test1b.patch | |||
|
119 | applying test2.patch | |||
|
120 | Now at: test2.patch | |||
|
121 | Now at: test1b.patch | |||
|
122 | Now at: test.patch | |||
|
123 | applying test1b.patch | |||
|
124 | applying test2.patch | |||
|
125 | Now at: test2.patch | |||
113 | % push should succeed |
|
126 | % push should succeed | |
114 | Patch queue now empty |
|
127 | Patch queue now empty | |
115 | pushing to ../../k |
|
128 | pushing to ../../k | |
@@ -127,6 +140,30 b' adding manifests' | |||||
127 | adding file changes |
|
140 | adding file changes | |
128 | added 1 changesets with 1 changes to 1 files |
|
141 | added 1 changesets with 1 changes to 1 files | |
129 | (run 'hg update' to get a working copy) |
|
142 | (run 'hg update' to get a working copy) | |
|
143 | % cd b; hg qrefresh | |||
|
144 | adding a | |||
|
145 | foo | |||
|
146 | ||||
|
147 | diff -r cb9a9f314b8b a | |||
|
148 | --- a/a | |||
|
149 | +++ b/a | |||
|
150 | @@ -1,1 +1,2 @@ a | |||
|
151 | a | |||
|
152 | +a | |||
|
153 | diff -r cb9a9f314b8b b/f | |||
|
154 | --- /dev/null | |||
|
155 | +++ b/b/f | |||
|
156 | @@ -0,0 +1,1 @@ | |||
|
157 | +f | |||
|
158 | % hg qrefresh . | |||
|
159 | foo | |||
|
160 | ||||
|
161 | diff -r cb9a9f314b8b b/f | |||
|
162 | --- /dev/null | |||
|
163 | +++ b/b/f | |||
|
164 | @@ -0,0 +1,1 @@ | |||
|
165 | +f | |||
|
166 | M a | |||
130 | new file |
|
167 | new file | |
131 |
|
168 | |||
132 | diff --git a/new b/new |
|
169 | diff --git a/new b/new |
@@ -85,4 +85,8 b' hg revert -rtip' | |||||
85 | echo % should succeed |
|
85 | echo % should succeed | |
86 | hg revert --all -rtip |
|
86 | hg revert --all -rtip | |
87 |
|
87 | |||
|
88 | echo %% issue332 | |||
|
89 | hg ci -A -m b -d '1000001 0' | |||
|
90 | echo foobar > b/b | |||
|
91 | hg revert b | |||
88 | true |
|
92 | true |
@@ -55,6 +55,9 b' executable' | |||||
55 | adding a |
|
55 | adding a | |
56 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
56 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
57 | % should fail - no arguments |
|
57 | % should fail - no arguments | |
58 | abort: no files or directories specified |
|
58 | abort: no files or directories specified; use --all to revert the whole repo | |
59 | % should succeed |
|
59 | % should succeed | |
60 | reverting a |
|
60 | reverting a | |
|
61 | %% issue332 | |||
|
62 | adding b/b | |||
|
63 | reverting b/b |
@@ -1,3 +1,3 b'' | |||||
1 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
1 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
2 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
2 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
3 |
abort: Permission denied |
|
3 | abort: Permission denied: test-ro-message/b/vehicle |
@@ -38,7 +38,7 b' cd ..' | |||||
38 |
|
38 | |||
39 | echo "# clone remote via stream" |
|
39 | echo "# clone remote via stream" | |
40 | hg clone -e ./dummyssh --uncompressed ssh://user@dummy/remote local-stream 2>&1 | \ |
|
40 | hg clone -e ./dummyssh --uncompressed ssh://user@dummy/remote local-stream 2>&1 | \ | |
41 | sed -e 's/[0-9][0-9.]*/XXX/g' |
|
41 | sed -e 's/[0-9][0-9.]*/XXX/g' -e 's/[KM]\(B\/sec\)/X\1/' | |
42 | cd local-stream |
|
42 | cd local-stream | |
43 | hg verify |
|
43 | hg verify | |
44 | cd .. |
|
44 | cd .. | |
@@ -80,7 +80,7 b' cd ../remote' | |||||
80 | echo "# check remote tip" |
|
80 | echo "# check remote tip" | |
81 | hg tip |
|
81 | hg tip | |
82 | hg verify |
|
82 | hg verify | |
83 | hg cat foo |
|
83 | hg cat -r tip foo | |
84 |
|
84 | |||
85 | echo z > z |
|
85 | echo z > z | |
86 | hg ci -A -m z -d '1000001 0' z |
|
86 | hg ci -A -m z -d '1000001 0' z |
@@ -2,7 +2,7 b'' | |||||
2 | # clone remote via stream |
|
2 | # clone remote via stream | |
3 | streaming all changes |
|
3 | streaming all changes | |
4 | XXX files to transfer, XXX bytes of data |
|
4 | XXX files to transfer, XXX bytes of data | |
5 |
transferred XXX bytes in XXX seconds (XXX |
|
5 | transferred XXX bytes in XXX seconds (XXX XB/sec) | |
6 | XXX files updated, XXX files merged, XXX files removed, XXX files unresolved |
|
6 | XXX files updated, XXX files merged, XXX files removed, XXX files unresolved | |
7 | checking changesets |
|
7 | checking changesets | |
8 | checking manifests |
|
8 | checking manifests |
@@ -1,6 +1,6 b'' | |||||
1 | #!/usr/bin/env python |
|
1 | #!/usr/bin/env python | |
2 |
|
2 | |||
3 | from mercurial import ui |
|
3 | from mercurial import ui, util | |
4 |
|
4 | |||
5 | testui = ui.ui() |
|
5 | testui = ui.ui() | |
6 | testui.updateopts(config=[ |
|
6 | testui.updateopts(config=[ | |
@@ -11,10 +11,19 b' testui.updateopts(config=[' | |||||
11 | 'lists.list2=foo bar baz', |
|
11 | 'lists.list2=foo bar baz', | |
12 | 'lists.list3=alice, bob', |
|
12 | 'lists.list3=alice, bob', | |
13 | 'lists.list4=foo bar baz alice, bob', |
|
13 | 'lists.list4=foo bar baz alice, bob', | |
|
14 | 'interpolation.value1=hallo', | |||
|
15 | 'interpolation.value2=%(value1)s world', | |||
|
16 | 'interpolation.value3=%(novalue)s', | |||
|
17 | 'interpolation.value4=%(bad)1', | |||
|
18 | 'interpolation.value5=%bad2', | |||
14 | ]) |
|
19 | ]) | |
15 |
|
20 | |||
16 | print repr(testui.configitems('values')) |
|
21 | print repr(testui.configitems('values')) | |
17 | print repr(testui.configitems('lists')) |
|
22 | print repr(testui.configitems('lists')) | |
|
23 | try: | |||
|
24 | print repr(testui.configitems('interpolation')) | |||
|
25 | except util.Abort, inst: | |||
|
26 | print inst | |||
18 | print "---" |
|
27 | print "---" | |
19 | print repr(testui.config('values', 'string')) |
|
28 | print repr(testui.config('values', 'string')) | |
20 | print repr(testui.config('values', 'bool1')) |
|
29 | print repr(testui.config('values', 'bool1')) | |
@@ -45,3 +54,18 b" print repr(testui.configlist('lists', 'u" | |||||
45 | print repr(testui.configlist('lists', 'unknown', ['foo bar'])) |
|
54 | print repr(testui.configlist('lists', 'unknown', ['foo bar'])) | |
46 | print repr(testui.configlist('lists', 'unknown', ['foo', 'bar'])) |
|
55 | print repr(testui.configlist('lists', 'unknown', ['foo', 'bar'])) | |
47 | print "---" |
|
56 | print "---" | |
|
57 | print repr(testui.config('interpolation', 'value1')) | |||
|
58 | print repr(testui.config('interpolation', 'value2')) | |||
|
59 | try: | |||
|
60 | print repr(testui.config('interpolation', 'value3')) | |||
|
61 | except util.Abort, inst: | |||
|
62 | print inst | |||
|
63 | try: | |||
|
64 | print repr(testui.config('interpolation', 'value4')) | |||
|
65 | except util.Abort, inst: | |||
|
66 | print inst | |||
|
67 | try: | |||
|
68 | print repr(testui.config('interpolation', 'value5')) | |||
|
69 | except util.Abort, inst: | |||
|
70 | print inst | |||
|
71 | print "---" |
@@ -1,5 +1,7 b'' | |||||
1 | [('bool1', 'true'), ('bool2', 'false'), ('string', 'string value')] |
|
1 | [('bool1', 'true'), ('bool2', 'false'), ('string', 'string value')] | |
2 | [('list1', 'foo'), ('list2', 'foo bar baz'), ('list3', 'alice, bob'), ('list4', 'foo bar baz alice, bob')] |
|
2 | [('list1', 'foo'), ('list2', 'foo bar baz'), ('list3', 'alice, bob'), ('list4', 'foo bar baz alice, bob')] | |
|
3 | Error in configuration section [interpolation]: | |||
|
4 | '%' must be followed by '%' or '(', found: '%bad2' | |||
3 | --- |
|
5 | --- | |
4 | 'string value' |
|
6 | 'string value' | |
5 | 'true' |
|
7 | 'true' | |
@@ -27,3 +29,17 b' True' | |||||
27 | ['foo bar'] |
|
29 | ['foo bar'] | |
28 | ['foo', 'bar'] |
|
30 | ['foo', 'bar'] | |
29 | --- |
|
31 | --- | |
|
32 | 'hallo' | |||
|
33 | 'hallo world' | |||
|
34 | Error in configuration section [interpolation] parameter 'value3': | |||
|
35 | Bad value substitution: | |||
|
36 | section: [interpolation] | |||
|
37 | option : value3 | |||
|
38 | key : novalue | |||
|
39 | rawval : | |||
|
40 | ||||
|
41 | Error in configuration section [interpolation] parameter 'value4': | |||
|
42 | bad interpolation variable reference '%(bad)1' | |||
|
43 | Error in configuration section [interpolation] parameter 'value5': | |||
|
44 | '%' must be followed by '%' or '(', found: '%bad2' | |||
|
45 | --- |
@@ -16,7 +16,7 b' summary: 1' | |||||
16 |
|
16 | |||
17 | resolving manifests |
|
17 | resolving manifests | |
18 | overwrite False branchmerge False partial False linear True |
|
18 | overwrite False branchmerge False partial False linear True | |
19 | ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e |
|
19 | ancestor 33aaa84a386b local 802f095af299 remote 33aaa84a386b | |
20 | a versions differ, resolve |
|
20 | a versions differ, resolve | |
21 | remote created b |
|
21 | remote created b | |
22 | merging a |
|
22 | merging a | |
@@ -32,7 +32,7 b' summary: 2' | |||||
32 |
|
32 | |||
33 | resolving manifests |
|
33 | resolving manifests | |
34 | overwrite False branchmerge False partial False linear True |
|
34 | overwrite False branchmerge False partial False linear True | |
35 | ancestor a0c8bcbbb45c local 1165e8bd193e remote a0c8bcbbb45c |
|
35 | ancestor 802f095af299 local 33aaa84a386b remote 33aaa84a386b | |
36 | remote deleted b |
|
36 | remote deleted b | |
37 | removing b |
|
37 | removing b | |
38 | 0 files updated, 0 files merged, 1 files removed, 0 files unresolved |
|
38 | 0 files updated, 0 files merged, 1 files removed, 0 files unresolved | |
@@ -50,7 +50,7 b' summary: 1' | |||||
50 |
|
50 | |||
51 | resolving manifests |
|
51 | resolving manifests | |
52 | overwrite False branchmerge False partial False linear True |
|
52 | overwrite False branchmerge False partial False linear True | |
53 | ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e |
|
53 | ancestor 33aaa84a386b local 802f095af299 remote 33aaa84a386b | |
54 | a versions differ, resolve |
|
54 | a versions differ, resolve | |
55 | remote created b |
|
55 | remote created b | |
56 | merging a |
|
56 | merging a | |
@@ -101,7 +101,7 b' abort: outstanding uncommitted changes' | |||||
101 | failed |
|
101 | failed | |
102 | resolving manifests |
|
102 | resolving manifests | |
103 | overwrite False branchmerge True partial False linear False |
|
103 | overwrite False branchmerge True partial False linear False | |
104 | ancestor a0c8bcbbb45c local 1165e8bd193e remote 4096f2872392 |
|
104 | ancestor 802f095af299 local 030602aee63d remote 33aaa84a386b | |
105 | a versions differ, resolve |
|
105 | a versions differ, resolve | |
106 | b versions differ, resolve |
|
106 | b versions differ, resolve | |
107 | merging a |
|
107 | merging a |
@@ -41,7 +41,7 b' side1' | |||||
41 | side2 |
|
41 | side2 | |
42 | resolving manifests |
|
42 | resolving manifests | |
43 | overwrite True branchmerge False partial False linear False |
|
43 | overwrite True branchmerge False partial False linear False | |
44 | ancestor 8515d4bfda76 local 1c0f48f8ece6 remote 0594b9004bae |
|
44 | ancestor ded32b0db104 local 221226fb2bd8 remote 537353581d3d | |
45 | remote deleted side2, clobbering |
|
45 | remote deleted side2, clobbering | |
46 | remote deleted side1, clobbering |
|
46 | remote deleted side1, clobbering | |
47 | remote created main |
|
47 | remote created main |
General Comments 0
You need to be logged in to leave comments.
Login now