##// END OF EJS Templates
Merge with crew
Benoit Boissinot -
r1680:c21b54f7 merge default
parent child Browse files
Show More
@@ -0,0 +1,104 b''
1 #!/usr/bin/env python
2
3 import os, sys, struct, stat
4 import difflib
5 import re
6 from optparse import OptionParser
7 from mercurial.bdiff import bdiff, blocks
8 from mercurial.mdiff import bunidiff
9
10 VERSION="0.2"
11 usage = "usage: %prog [options] file1 file2"
12 parser = OptionParser(usage=usage)
13
14 parser.add_option("-d", "--difflib", action="store_true", default=False)
15 parser.add_option('-x', '--count', default=1)
16 parser.add_option('-c', '--context', type="int", default=3)
17 parser.add_option('-p', '--show-c-function', action="store_true", default=False)
18 parser.add_option('-w', '--ignore-all-space', action="store_true",
19 default=False)
20
21 (options, args) = parser.parse_args()
22
23 if not args:
24 parser.print_help()
25 sys.exit(1)
26
27 # simple utility function to put all the
28 # files from a directory tree into a dict
29 def buildlist(names, top):
30 tlen = len(top)
31 for root, dirs, files in os.walk(top):
32 l = root[tlen + 1:]
33 for x in files:
34 p = os.path.join(root, x)
35 st = os.lstat(p)
36 if stat.S_ISREG(st.st_mode):
37 names[os.path.join(l, x)] = (st.st_dev, st.st_ino)
38
39 def diff_files(file1, file2):
40 if file1 == None:
41 b = file(file2).read().splitlines(1)
42 l1 = "--- %s\n" % (file2)
43 l2 = "+++ %s\n" % (file2)
44 l3 = "@@ -0,0 +1,%d @@\n" % len(b)
45 l = [l1, l2, l3] + ["+" + e for e in b]
46 elif file2 == None:
47 a = file(file1).read().splitlines(1)
48 l1 = "--- %s\n" % (file1)
49 l2 = "+++ %s\n" % (file1)
50 l3 = "@@ -1,%d +0,0 @@\n" % len(a)
51 l = [l1, l2, l3] + ["-" + e for e in a]
52 else:
53 t1 = file(file1).read()
54 t2 = file(file2).read()
55 l1 = t1.splitlines(1)
56 l2 = t2.splitlines(1)
57 if options.difflib:
58 l = difflib.unified_diff(l1, l2, file1, file2)
59 else:
60 l = bunidiff(t1, t2, l1, l2, file1, file2, context=options.context,
61 showfunc=options.show_c_function,
62 ignorews=options.ignore_all_space)
63 for x in l:
64 if x[-1] != '\n':
65 x += "\n\ No newline at end of file\n"
66 print x,
67
68 file1 = args[0]
69 file2 = args[1]
70
71 if os.path.isfile(file1) and os.path.isfile(file2):
72 diff_files(file1, file2)
73 elif os.path.isdir(file1):
74 if not os.path.isdir(file2):
75 sys.stderr.write("file types don't match\n")
76 sys.exit(1)
77
78 d1 = {}
79 d2 = {}
80
81 buildlist(d1, file1)
82 buildlist(d2, file2)
83 keys = d1.keys()
84 keys.sort()
85 for x in keys:
86 if x not in d2:
87 f2 = None
88 else:
89 f2 = os.path.join(file2, x)
90 st1 = d1[x]
91 st2 = d2[x]
92 del d2[x]
93 if st1[0] == st2[0] and st1[1] == st2[1]:
94 sys.stderr.write("%s is a hard link\n" % x)
95 continue
96 x = os.path.join(file1, x)
97 diff_files(x, f2)
98 keys = d2.keys()
99 keys.sort()
100 for x in keys:
101 f1 = None
102 x = os.path.join(file2, x)
103 diff_files(f1, x)
104
@@ -0,0 +1,206 b''
1 import os, tempfile, binascii, errno
2 from mercurial import util
3 from mercurial import node as hgnode
4
5 class gpg:
6 def __init__(self, path, key=None):
7 self.path = path
8 self.key = (key and " --local-user \"%s\"" % key) or ""
9
10 def sign(self, data):
11 gpgcmd = "%s --sign --detach-sign%s" % (self.path, self.key)
12 return util.filter(data, gpgcmd)
13
14 def verify(self, data, sig):
15 """ returns of the good and bad signatures"""
16 try:
17 fd, sigfile = tempfile.mkstemp(prefix="hggpgsig")
18 fp = os.fdopen(fd, 'wb')
19 fp.write(sig)
20 fp.close()
21 fd, datafile = tempfile.mkstemp(prefix="hggpgdata")
22 fp = os.fdopen(fd, 'wb')
23 fp.write(data)
24 fp.close()
25 gpgcmd = "%s --logger-fd 1 --status-fd 1 --verify \"%s\" \"%s\"" % (self.path, sigfile, datafile)
26 #gpgcmd = "%s --status-fd 1 --verify \"%s\" \"%s\"" % (self.path, sigfile, datafile)
27 ret = util.filter("", gpgcmd)
28 except:
29 for f in (sigfile, datafile):
30 try:
31 if f: os.unlink(f)
32 except: pass
33 raise
34 keys = []
35 key, fingerprint = None, None
36 err = ""
37 for l in ret.splitlines():
38 # see DETAILS in the gnupg documentation
39 # filter the logger output
40 if not l.startswith("[GNUPG:]"):
41 continue
42 l = l[9:]
43 if l.startswith("ERRSIG"):
44 err = "error while verifying signature"
45 break
46 elif l.startswith("VALIDSIG"):
47 # fingerprint of the primary key
48 fingerprint = l.split()[10]
49 elif (l.startswith("GOODSIG") or
50 l.startswith("EXPSIG") or
51 l.startswith("EXPKEYSIG") or
52 l.startswith("BADSIG")):
53 if key is not None:
54 keys.append(key + [fingerprint])
55 key = l.split(" ", 2)
56 fingerprint = None
57 if err:
58 return err, []
59 if key is not None:
60 keys.append(key + [fingerprint])
61 return err, keys
62
63 def newgpg(ui, **opts):
64 gpgpath = ui.config("gpg", "cmd", "gpg")
65 gpgkey = opts.get('key')
66 if not gpgkey:
67 gpgkey = ui.config("gpg", "key", None)
68 return gpg(gpgpath, gpgkey)
69
70 def check(ui, repo, rev):
71 """verify all the signatures there may be for a particular revision"""
72 mygpg = newgpg(ui)
73 rev = repo.lookup(rev)
74 hexrev = hgnode.hex(rev)
75 keys = []
76
77 def addsig(fn, ln, l):
78 if not l: return
79 n, v, sig = l.split(" ", 2)
80 if n == hexrev:
81 data = node2txt(repo, rev, v)
82 sig = binascii.a2b_base64(sig)
83 err, k = mygpg.verify(data, sig)
84 if not err:
85 keys.append((k, fn, ln))
86 else:
87 ui.warn("%s:%d %s\n" % (fn, ln , err))
88
89 fl = repo.file(".hgsigs")
90 h = fl.heads()
91 h.reverse()
92 # read the heads
93 for r in h:
94 ln = 1
95 for l in fl.read(r).splitlines():
96 addsig(".hgsigs|%s" % hgnode.short(r), ln, l)
97 ln +=1
98 try:
99 # read local signatures
100 ln = 1
101 f = repo.opener("localsigs")
102 for l in f:
103 addsig("localsigs", ln, l)
104 ln +=1
105 except IOError:
106 pass
107
108 if not keys:
109 ui.write("%s not signed\n" % hgnode.short(rev))
110 return
111 valid = []
112 # warn for expired key and/or sigs
113 for k, fn, ln in keys:
114 prefix = "%s:%d" % (fn, ln)
115 for key in k:
116 if key[0] == "BADSIG":
117 ui.write("%s Bad signature from \"%s\"\n" % (prefix, key[2]))
118 continue
119 if key[0] == "EXPSIG":
120 ui.write("%s Note: Signature has expired"
121 " (signed by: \"%s\")\n" % (prefix, key[2]))
122 elif key[0] == "EXPKEYSIG":
123 ui.write("%s Note: This key has expired"
124 " (signed by: \"%s\")\n" % (prefix, key[2]))
125 valid.append((key[1], key[2], key[3]))
126 # print summary
127 ui.write("%s is signed by:\n" % hgnode.short(rev))
128 for keyid, user, fingerprint in valid:
129 role = getrole(ui, fingerprint)
130 ui.write(" %s (%s)\n" % (user, role))
131
132 def getrole(ui, fingerprint):
133 return ui.config("gpg", fingerprint, "no role defined")
134
135 def sign(ui, repo, *revs, **opts):
136 """add a signature for the current tip or a given revision"""
137 mygpg = newgpg(ui, **opts)
138 sigver = "0"
139 sigmessage = ""
140 if revs:
141 nodes = [repo.lookup(n) for n in revs]
142 else:
143 nodes = [repo.changelog.tip()]
144
145 for n in nodes:
146 hexnode = hgnode.hex(n)
147 ui.write("Signing %d:%s\n" % (repo.changelog.rev(n),
148 hgnode.short(n)))
149 # build data
150 data = node2txt(repo, n, sigver)
151 sig = mygpg.sign(data)
152 if not sig:
153 raise util.Abort("Error while signing")
154 sig = binascii.b2a_base64(sig)
155 sig = sig.replace("\n", "")
156 sigmessage += "%s %s %s\n" % (hexnode, sigver, sig)
157
158 # write it
159 if opts['local']:
160 repo.opener("localsigs", "ab").write(sigmessage)
161 return
162
163 for x in repo.changes():
164 if ".hgsigs" in x and not opts["force"]:
165 raise util.Abort("working copy of .hgsigs is changed "
166 "(please commit .hgsigs manually "
167 "or use --force)")
168
169 repo.wfile(".hgsigs", "ab").write(sigmessage)
170
171 if repo.dirstate.state(".hgsigs") == '?':
172 repo.add([".hgsigs"])
173
174 if opts["no_commit"]:
175 return
176
177 message = opts['message']
178 if not message:
179 message = "\n".join(["Added signature for changeset %s" % hgnode.hex(n)
180 for n in nodes])
181 try:
182 repo.commit([".hgsigs"], message, opts['user'], opts['date'])
183 except ValueError, inst:
184 raise util.Abort(str(inst))
185
186 def node2txt(repo, node, ver):
187 """map a manifest into some text"""
188 if ver == "0":
189 return "%s\n" % hgnode.hex(node)
190 else:
191 util.Abort("unknown signature version")
192
193 cmdtable = {
194 "sign":
195 (sign,
196 [('l', 'local', None, "make the signature local"),
197 ('f', 'force', None, "sign even if the sigfile is modified"),
198 ('', 'no-commit', None, "do not commit the sigfile after signing"),
199 ('m', 'message', "", "commit message"),
200 ('d', 'date', "", "date code"),
201 ('u', 'user', "", "user"),
202 ('k', 'key', "", "the key id to sign with")],
203 "hg sign [OPTION]... REVISIONS"),
204 "sigcheck": (check, [], 'hg sigcheck REVISION')
205 }
206
@@ -0,0 +1,12 b''
1 #!/bin/sh
2
3 hg init rep
4 cd rep
5 mkdir dir
6 touch foo dir/bar
7 hg -v addremove
8 hg -v commit -m "add 1" -d "0 0"
9 cd dir/
10 touch ../foo_2 bar_2
11 hg -v addremove
12 hg -v commit -m "add 2" -d "0 0"
@@ -0,0 +1,8 b''
1 adding dir/bar
2 adding foo
3 dir/bar
4 foo
5 adding dir/bar_2
6 adding foo_2
7 dir/bar_2
8 foo_2
@@ -0,0 +1,20 b''
1 #!/bin/sh
2 #
3 mkdir t
4 cd t
5 hg init
6 echo 0 > a
7 echo 0 > b
8 hg ci -A -m m -d "0 0"
9 touch nottracked
10 hg locate a
11 hg locate NONEXISTENT
12 hg locate
13 hg rm a
14 hg ci -m m -d "0 0"
15 hg locate a
16 hg locate NONEXISTENT
17 hg locate
18 hg locate -r 0 a
19 hg locate -r 0 NONEXISTENT
20 hg locate -r 0
@@ -0,0 +1,13 b''
1 adding a
2 adding b
3 a
4 NONEXISTENT: No such file or directory
5 a
6 b
7 a: No such file or directory
8 NONEXISTENT: No such file or directory
9 b
10 a
11 NONEXISTENT: No such file in rev 9e1684505872
12 a
13 b
@@ -0,0 +1,34 b''
1 #!/bin/sh
2
3 hg init repo1
4 cd repo1
5 mkdir a b a/1 b/1 b/2
6 touch in_root a/in_a b/in_b a/1/in_a_1 b/1/in_b_1 b/2/in_b_2
7 echo "hg status in repo root:"
8 hg status
9 echo "hg status . in repo root:"
10 hg status .
11 for dir in a b a/1 b/1 b/2; do
12 echo "hg status in $dir:"
13 hg status --cwd "$dir"
14 echo "hg status . in $dir:"
15 hg status --cwd "$dir" .
16 echo "hg status .. in $dir:"
17 hg status --cwd "$dir" ..
18 done
19 cd ..
20
21 hg init repo2
22 cd repo2
23 touch modified removed deleted ignored
24 echo "ignored" > .hgignore
25 hg ci -A -m 'initial checkin' -d "0 0"
26 sleep 1 # make sure mtime is changed
27 touch modified added unknown ignored
28 hg add added
29 hg remove removed
30 rm deleted
31 echo "hg status:"
32 hg status
33 echo "hg status modified added removed deleted unknown never-existed ignored:"
34 hg status modified added removed deleted unknown never-existed ignored
@@ -0,0 +1,103 b''
1 hg status in repo root:
2 ? a/1/in_a_1
3 ? a/in_a
4 ? b/1/in_b_1
5 ? b/2/in_b_2
6 ? b/in_b
7 ? in_root
8 hg status . in repo root:
9 ? a/1/in_a_1
10 ? a/in_a
11 ? b/1/in_b_1
12 ? b/2/in_b_2
13 ? b/in_b
14 ? in_root
15 hg status in a:
16 ? a/1/in_a_1
17 ? a/in_a
18 ? b/1/in_b_1
19 ? b/2/in_b_2
20 ? b/in_b
21 ? in_root
22 hg status . in a:
23 ? 1/in_a_1
24 ? in_a
25 hg status .. in a:
26 ? 1/in_a_1
27 ? in_a
28 ? ../b/1/in_b_1
29 ? ../b/2/in_b_2
30 ? ../b/in_b
31 ? ../in_root
32 hg status in b:
33 ? a/1/in_a_1
34 ? a/in_a
35 ? b/1/in_b_1
36 ? b/2/in_b_2
37 ? b/in_b
38 ? in_root
39 hg status . in b:
40 ? 1/in_b_1
41 ? 2/in_b_2
42 ? in_b
43 hg status .. in b:
44 ? ../a/1/in_a_1
45 ? ../a/in_a
46 ? 1/in_b_1
47 ? 2/in_b_2
48 ? in_b
49 ? ../in_root
50 hg status in a/1:
51 ? a/1/in_a_1
52 ? a/in_a
53 ? b/1/in_b_1
54 ? b/2/in_b_2
55 ? b/in_b
56 ? in_root
57 hg status . in a/1:
58 ? in_a_1
59 hg status .. in a/1:
60 ? in_a_1
61 ? ../in_a
62 hg status in b/1:
63 ? a/1/in_a_1
64 ? a/in_a
65 ? b/1/in_b_1
66 ? b/2/in_b_2
67 ? b/in_b
68 ? in_root
69 hg status . in b/1:
70 ? in_b_1
71 hg status .. in b/1:
72 ? in_b_1
73 ? ../2/in_b_2
74 ? ../in_b
75 hg status in b/2:
76 ? a/1/in_a_1
77 ? a/in_a
78 ? b/1/in_b_1
79 ? b/2/in_b_2
80 ? b/in_b
81 ? in_root
82 hg status . in b/2:
83 ? in_b_2
84 hg status .. in b/2:
85 ? ../1/in_b_1
86 ? in_b_2
87 ? ../in_b
88 adding .hgignore
89 adding deleted
90 adding modified
91 adding removed
92 hg status:
93 A added
94 R removed
95 ! deleted
96 ? unknown
97 hg status modified added removed deleted unknown never-existed ignored:
98 never-existed: No such file or directory
99 A added
100 R removed
101 ! deleted
102 ? ignored
103 ? unknown
@@ -8,3 +8,4 b' 12e0fdbc57a0be78f0e817fd1d170a3615cd35da'
8 4ccf3de52989b14c3d84e1097f59e39a992e00bd 0.6b
8 4ccf3de52989b14c3d84e1097f59e39a992e00bd 0.6b
9 eac9c8efcd9bd8244e72fb6821f769f450457a32 0.6c
9 eac9c8efcd9bd8244e72fb6821f769f450457a32 0.6c
10 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7
10 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7
11 3a56574f329a368d645853e0f9e09472aee62349 0.8
@@ -1,23 +1,54 b''
1 shopt -s extglob
1 shopt -s extglob
2
2
3 _hg_command_list()
4 {
5 hg --debug help 2>/dev/null | \
6 awk 'function command_line(line) {
7 gsub(/,/, "", line)
8 gsub(/:.*/, "", line)
9 split(line, aliases)
10 command = aliases[1]
11 delete aliases[1]
12 print command
13 for (i in aliases)
14 if (index(command, aliases[i]) != 1)
15 print aliases[i]
16 }
17 /^list of commands:/ {commands=1}
18 commands && /^ debug/ {a[i++] = $0; next;}
19 commands && /^ [^ ]/ {command_line($0)}
20 /^global options:/ {exit 0}
21 END {for (i in a) command_line(a[i])}'
22
23 }
24
25 _hg_option_list()
26 {
27 hg -v help $1 2> /dev/null | \
28 awk '/^ *-/ {
29 for (i = 1; i <= NF; i ++) {
30 if (index($i, "-") != 1)
31 break;
32 print $i;
33 }
34 }'
35 }
36
37
3 _hg_commands()
38 _hg_commands()
4 {
39 {
5 local all commands result
40 local all commands result
6
41
7 all=($(hg --debug help | sed -e '1,/^list of commands:/d' \
42 all=$(_hg_command_list)
8 -e '/^global options:/,$d' \
43 commands=${all%%$'\n'debug*}
9 -e '/^ [^ ]/!d; s/^ //; s/[,:]//g;'))
44 result=$(compgen -W '$commands' -- "$cur")
10
11 commands="${all[*]##debug*}"
12 result=$(compgen -W "${commands[*]}" -- "$cur")
13
45
14 # hide debug commands from users, but complete them if
46 # hide debug commands from users, but complete them if
15 # there is no other possible command
47 # there is no other possible command
16 if [ "$result" = "" ]; then
48 if [ "$result" = "" ]; then
17 local debug
49 local debug
18 debug=(${all[*]##!(debug*)})
50 debug=debug${all#*$'\n'debug}
19 debug="${debug[*]/g/debug}"
51 result=$(compgen -W '$debug' -- "$cur")
20 result=$(compgen -W "$debug" -- "$cur")
21 fi
52 fi
22
53
23 COMPREPLY=(${COMPREPLY[@]:-} $result)
54 COMPREPLY=(${COMPREPLY[@]:-} $result)
@@ -25,8 +56,8 b' shopt -s extglob'
25
56
26 _hg_paths()
57 _hg_paths()
27 {
58 {
28 local paths="$(hg paths | sed -e 's/ = .*$//')"
59 local paths="$(hg paths 2> /dev/null | sed -e 's/ = .*$//')"
29 COMPREPLY=(${COMPREPLY[@]:-} $( compgen -W "$paths" -- "$cur" ))
60 COMPREPLY=(${COMPREPLY[@]:-} $( compgen -W '$paths' -- "$cur" ))
30 }
61 }
31
62
32 _hg_repos()
63 _hg_repos()
@@ -39,14 +70,15 b' shopt -s extglob'
39
70
40 _hg_status()
71 _hg_status()
41 {
72 {
42 local files="$( hg status -$1 | cut -b 3- )"
73 local files="$( hg status -n$1 . 2> /dev/null)"
43 COMPREPLY=(${COMPREPLY[@]:-} $( compgen -W "$files" -- "$cur" ))
74 COMPREPLY=(${COMPREPLY[@]:-} $( compgen -W '$files' -- "$cur" ))
44 }
75 }
45
76
46 _hg_tags()
77 _hg_tags()
47 {
78 {
48 local tags="$(hg tags | sed -e 's/[0-9]*:[a-f0-9]\{40\}$//; s/ *$//')"
79 local tags="$(hg tags 2> /dev/null |
49 COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "$tags" -- "$cur") )
80 sed -e 's/[0-9]*:[a-f0-9]\{40\}$//; s/ *$//')"
81 COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W '$tags' -- "$cur") )
50 }
82 }
51
83
52 # this is "kind of" ugly...
84 # this is "kind of" ugly...
@@ -90,10 +122,9 b' shopt -s extglob'
90 done
122 done
91
123
92 if [[ "$cur" == -* ]]; then
124 if [[ "$cur" == -* ]]; then
93 # this assumes that there are no commands with spaces in the name
125 opts=$(_hg_option_list $cmd)
94 opts=$(hg -v help $cmd | sed -e '/^ *-/!d; s/ [^- ].*//')
95
126
96 COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "$opts" -- "$cur") )
127 COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur") )
97 return
128 return
98 fi
129 fi
99
130
@@ -115,7 +146,7 b' shopt -s extglob'
115 fi
146 fi
116
147
117 # canonicalize command name
148 # canonicalize command name
118 cmd=$(hg -q help "$cmd" | sed -e 's/^hg //; s/ .*//; 1q')
149 cmd=$(hg -q help "$cmd" 2> /dev/null | sed -e 's/^hg //; s/ .*//; 1q')
119
150
120 if [ "$cmd" != status ] && [ "$prev" = -r ] || [ "$prev" = --rev ]; then
151 if [ "$cmd" != status ] && [ "$prev" = -r ] || [ "$prev" = --rev ]; then
121 _hg_tags
152 _hg_tags
@@ -140,19 +171,19 b' shopt -s extglob'
140 _hg_status "u"
171 _hg_status "u"
141 ;;
172 ;;
142 commit)
173 commit)
143 _hg_status "mra"
174 _hg_status "mar"
144 ;;
175 ;;
145 remove)
176 remove)
146 _hg_status "r"
177 _hg_status "d"
147 ;;
178 ;;
148 forget)
179 forget)
149 _hg_status "a"
180 _hg_status "a"
150 ;;
181 ;;
151 diff)
182 diff)
152 _hg_status "mra"
183 _hg_status "mar"
153 ;;
184 ;;
154 revert)
185 revert)
155 _hg_status "mra"
186 _hg_status "mard"
156 ;;
187 ;;
157 clone)
188 clone)
158 local count=$(_hg_count_non_option)
189 local count=$(_hg_count_non_option)
@@ -167,17 +198,6 b' shopt -s extglob'
167 debugdata)
198 debugdata)
168 COMPREPLY=(${COMPREPLY[@]:-} $( compgen -f -X "!*.d" -- "$cur" ))
199 COMPREPLY=(${COMPREPLY[@]:-} $( compgen -f -X "!*.d" -- "$cur" ))
169 ;;
200 ;;
170 cat)
171 local count=$(_hg_count_non_option '-o|--output')
172 if [ $count = 2 ]; then
173 _hg_tags
174 else
175 COMPREPLY=(${COMPREPLY[@]:-} $( compgen -f -- "$cur" ))
176 fi
177 ;;
178 *)
179 COMPREPLY=(${COMPREPLY[@]:-} $( compgen -f -- "$cur" ))
180 ;;
181 esac
201 esac
182
202
183 }
203 }
@@ -21,7 +21,7 b''
21 # interrupted and can be run repeatedly to copy new commits.
21 # interrupted and can be run repeatedly to copy new commits.
22
22
23 import sys, os, zlib, sha, time
23 import sys, os, zlib, sha, time
24 from mercurial import hg, ui, util
24 from mercurial import hg, ui, util, commands
25
25
26 class convert_git:
26 class convert_git:
27 def __init__(self, path):
27 def __init__(self, path):
@@ -113,7 +113,7 b' class convert_mercurial:'
113 except:
113 except:
114 pass
114 pass
115
115
116 def putcommit(self, files, parents, author, dest, text):
116 def putcommit(self, files, parents, author, date, text):
117 seen = {}
117 seen = {}
118 pl = []
118 pl = []
119 for p in parents:
119 for p in parents:
@@ -129,8 +129,13 b' class convert_mercurial:'
129 while parents:
129 while parents:
130 p1 = p2
130 p1 = p2
131 p2 = parents.pop(0)
131 p2 = parents.pop(0)
132 self.repo.rawcommit(files, text, author, dest,
132 self.repo.dirstate.setparents(hg.bin(p1), hg.bin(p2))
133 hg.bin(p1), hg.bin(p2))
133 if len(files) > 0:
134 olddir = os.getcwd()
135 os.chdir(self.path)
136 commands.addremove(self.repo.ui, self.repo, *files)
137 os.chdir(olddir)
138 self.repo.commit(files, text, author, date)
134 text = "(octopus merge fixup)\n"
139 text = "(octopus merge fixup)\n"
135 p2 = hg.hex(self.repo.changelog.tip())
140 p2 = hg.hex(self.repo.changelog.tip())
136
141
@@ -171,9 +176,12 b' class convert:'
171 self.commitcache = {}
176 self.commitcache = {}
172
177
173 self.map = {}
178 self.map = {}
174 for l in file(self.mapfile):
179 try:
175 sv, dv = l[:-1].split()
180 for l in file(self.mapfile):
176 self.map[sv] = dv
181 sv, dv = l[:-1].split()
182 self.map[sv] = dv
183 except IOError:
184 pass
177
185
178 def walktree(self, heads):
186 def walktree(self, heads):
179 visit = heads
187 visit = heads
@@ -21,8 +21,8 b' def lookup_rev(ui, repo, rev=None):'
21 return parents.pop()
21 return parents.pop()
22
22
23 def check_clean(ui, repo):
23 def check_clean(ui, repo):
24 c, a, d, u = repo.changes()
24 modified, added, removed, deleted, unknown = repo.changes()
25 if c or a or d:
25 if modified or added or removed:
26 ui.warn("Repository is not clean, please commit or revert\n")
26 ui.warn("Repository is not clean, please commit or revert\n")
27 sys.exit(1)
27 sys.exit(1)
28
28
@@ -1,6 +1,6 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # Copyright 2005 by Intevation GmbH <intevation@intevation.de>
3 # Copyright 2005, 2006 by Intevation GmbH <intevation@intevation.de>
4 # Author(s):
4 # Author(s):
5 # Thomas Arendsen Hein <thomas@intevation.de>
5 # Thomas Arendsen Hein <thomas@intevation.de>
6 #
6 #
@@ -20,6 +20,9 b' This allows pull/push over ssh to to the'
20 If all your repositories are subdirectories of a common directory, you can
20 If all your repositories are subdirectories of a common directory, you can
21 allow shorter paths with:
21 allow shorter paths with:
22 command="cd path/to/my/repositories && hg-ssh repo1 subdir/repo2"
22 command="cd path/to/my/repositories && hg-ssh repo1 subdir/repo2"
23
24 You can use pattern matching of your normal shell, e.g.:
25 command="cd repos && hg-ssh user/thomas/* projects/{mercurial,foo}"
23 """
26 """
24
27
25 from mercurial import commands
28 from mercurial import commands
@@ -1,5 +1,3 b''
1 #!/usr/bin/env python
2 #
3 # Minimal support for git commands on an hg repository
1 # Minimal support for git commands on an hg repository
4 #
2 #
5 # Copyright 2005 Chris Mason <mason@suse.com>
3 # Copyright 2005 Chris Mason <mason@suse.com>
@@ -16,13 +14,13 b' def dodiff(fp, ui, repo, node1, node2, f'
16 return time.asctime(time.gmtime(c[2][0]))
14 return time.asctime(time.gmtime(c[2][0]))
17
15
18 if not changes:
16 if not changes:
19 (c, a, d, u) = repo.changes(node1, node2, files, match=match)
17 changes = repo.changes(node1, node2, files, match=match)
20 else:
18 modified, added, removed, deleted, unknown = changes
21 (c, a, d, u) = changes
22 if files:
19 if files:
23 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
20 modified, added, removed = map(lambda x: filterfiles(files, x),
21 (modified, added, removed))
24
22
25 if not c and not a and not d:
23 if not modified and not added and not removed:
26 return
24 return
27
25
28 if node2:
26 if node2:
@@ -42,19 +40,19 b' def dodiff(fp, ui, repo, node1, node2, f'
42 mmap = repo.manifest.read(change[0])
40 mmap = repo.manifest.read(change[0])
43 date1 = date(change)
41 date1 = date(change)
44
42
45 for f in c:
43 for f in modified:
46 to = None
44 to = None
47 if f in mmap:
45 if f in mmap:
48 to = repo.file(f).read(mmap[f])
46 to = repo.file(f).read(mmap[f])
49 tn = read(f)
47 tn = read(f)
50 fp.write("diff --git a/%s b/%s\n" % (f, f))
48 fp.write("diff --git a/%s b/%s\n" % (f, f))
51 fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, text=text))
49 fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, text=text))
52 for f in a:
50 for f in added:
53 to = None
51 to = None
54 tn = read(f)
52 tn = read(f)
55 fp.write("diff --git /dev/null b/%s\n" % (f))
53 fp.write("diff --git /dev/null b/%s\n" % (f))
56 fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, text=text))
54 fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, text=text))
57 for f in d:
55 for f in removed:
58 to = repo.file(f).read(mmap[f])
56 to = repo.file(f).read(mmap[f])
59 tn = None
57 tn = None
60 fp.write("diff --git a/%s /dev/null\n" % (f))
58 fp.write("diff --git a/%s /dev/null\n" % (f))
@@ -69,12 +67,12 b' def difftree(ui, repo, node1=None, node2'
69 if node2:
67 if node2:
70 change = repo.changelog.read(node2)
68 change = repo.changelog.read(node2)
71 mmap2 = repo.manifest.read(change[0])
69 mmap2 = repo.manifest.read(change[0])
72 (c, a, d, u) = repo.changes(node1, node2)
70 modified, added, removed, deleted, unknown = repo.changes(node1, node2)
73 def read(f): return repo.file(f).read(mmap2[f])
71 def read(f): return repo.file(f).read(mmap2[f])
74 date2 = date(change)
72 date2 = date(change)
75 else:
73 else:
76 date2 = time.asctime()
74 date2 = time.asctime()
77 (c, a, d, u) = repo.changes(node1, None)
75 modified, added, removed, deleted, unknown = repo.changes(node1)
78 if not node1:
76 if not node1:
79 node1 = repo.dirstate.parents()[0]
77 node1 = repo.dirstate.parents()[0]
80 def read(f): return file(os.path.join(repo.root, f)).read()
78 def read(f): return file(os.path.join(repo.root, f)).read()
@@ -84,13 +82,13 b' def difftree(ui, repo, node1=None, node2'
84 date1 = date(change)
82 date1 = date(change)
85 empty = "0" * 40;
83 empty = "0" * 40;
86
84
87 for f in c:
85 for f in modified:
88 # TODO get file permissions
86 # TODO get file permissions
89 print ":100664 100664 %s %s M\t%s\t%s" % (hg.hex(mmap[f]),
87 print ":100664 100664 %s %s M\t%s\t%s" % (hg.hex(mmap[f]),
90 hg.hex(mmap2[f]), f, f)
88 hg.hex(mmap2[f]), f, f)
91 for f in a:
89 for f in added:
92 print ":000000 100664 %s %s N\t%s\t%s" % (empty, hg.hex(mmap2[f]), f, f)
90 print ":000000 100664 %s %s N\t%s\t%s" % (empty, hg.hex(mmap2[f]), f, f)
93 for f in d:
91 for f in removed:
94 print ":100664 000000 %s %s D\t%s\t%s" % (hg.hex(mmap[f]), empty, f, f)
92 print ":100664 000000 %s %s D\t%s\t%s" % (hg.hex(mmap[f]), empty, f, f)
95 ##
93 ##
96
94
@@ -155,6 +155,8 b' clone [options] <source> [dest]::'
155 errors. In these cases, use the --pull option to avoid
155 errors. In these cases, use the --pull option to avoid
156 hardlinking.
156 hardlinking.
157
157
158 See pull for valid source format details.
159
158 options:
160 options:
159 -U, --noupdate do not update the new working directory
161 -U, --noupdate do not update the new working directory
160 --pull use pull protocol to copy metadata
162 --pull use pull protocol to copy metadata
@@ -388,6 +390,8 b' outgoing [-p] [dest]::'
388 default push repo. These are the changesets that would be pushed
390 default push repo. These are the changesets that would be pushed
389 if a push was requested.
391 if a push was requested.
390
392
393 See pull for valid source format details.
394
391 options:
395 options:
392 -p, --patch show patch
396 -p, --patch show patch
393
397
@@ -454,11 +458,14 b' push <destination>::'
454 --remotecmd specify hg command to run on the remote side
458 --remotecmd specify hg command to run on the remote side
455
459
456 rawcommit [-p -d -u -F -m -l]::
460 rawcommit [-p -d -u -F -m -l]::
457 Lowlevel commit, for use in helper scripts.
461 Lowlevel commit, for use in helper scripts. (DEPRECATED)
458
462
459 This command is not intended to be used by normal users, as it is
463 This command is not intended to be used by normal users, as it is
460 primarily useful for importing from other SCMs.
464 primarily useful for importing from other SCMs.
461
465
466 This command is now deprecated and will be removed in a future
467 release, please use debugsetparents and commit instead.
468
462 recover::
469 recover::
463 Recover from an interrupted commit or pull.
470 Recover from an interrupted commit or pull.
464
471
@@ -497,9 +504,18 b' rename <source ...> <dest>::'
497 aliases: mv
504 aliases: mv
498
505
499 revert [names ...]::
506 revert [names ...]::
500 Revert any uncommitted modifications made to the named files or
507 The revert command has two modes of operation.
501 directories. This restores the contents of the affected files to
508
502 an unmodified state.
509 In its default mode, it reverts any uncommitted modifications made
510 to the named files or directories. This restores the contents of
511 the affected files to an unmodified state.
512
513 Using the -r option, it reverts the given files or directories to
514 their state as of an earlier revision. This can be helpful to "roll
515 back" some or all of a change that should not have been committed.
516
517 Revert modifies the working directory. It does not commit any
518 changes, or change the parent of the current working directory.
503
519
504 If a file has been deleted, it is recreated. If the executable
520 If a file has been deleted, it is recreated. If the executable
505 mode of a file was changed, it is reset.
521 mode of a file was changed, it is reset.
@@ -1,10 +1,7 b''
1 #!/bin/sh
1 #!/bin/sh
2 #
2 #
3 # This is an example of using HGEDITOR to automate the signing of
3 # This is an example of using HGEDITOR to create of diff to review the
4 # commits and so on.
4 # changes while commiting.
5
6 # change this to one to turn on GPG support
7 SIGN=0
8
5
9 # If you want to pass your favourite editor some other parameters
6 # If you want to pass your favourite editor some other parameters
10 # only for Mercurial, modify this:
7 # only for Mercurial, modify this:
@@ -43,12 +40,7 b' HGTMP="${TMPDIR-/tmp}/hgeditor.$RANDOM.$'
43 done
40 done
44 )
41 )
45
42
46 echo > "$HGTMP/msg"
43 cat "$1" > "$HGTMP/msg"
47 if [ "$SIGN" == "1" ]; then
48 MANIFEST=`grep '^HG: manifest hash' "$1" | cut -b 19-`
49 echo -e "\nmanifest hash: $MANIFEST" >> "$HGTMP/msg"
50 fi
51 grep -vE '^(HG: manifest hash .*)?$' "$1" >> "$HGTMP/msg"
52
44
53 CHECKSUM=`md5sum "$HGTMP/msg"`
45 CHECKSUM=`md5sum "$HGTMP/msg"`
54 if [ -s "$HGTMP/diff" ]; then
46 if [ -s "$HGTMP/diff" ]; then
@@ -58,14 +50,6 b' else'
58 fi
50 fi
59 echo "$CHECKSUM" | md5sum -c >/dev/null 2>&1 && exit 13
51 echo "$CHECKSUM" | md5sum -c >/dev/null 2>&1 && exit 13
60
52
61 if [ "$SIGN" == "1" ]; then
53 mv "$HGTMP/msg" "$1"
62 {
63 head -n 1 "$HGTMP/msg"
64 echo
65 grep -v "^HG:" "$HGTMP/msg" | gpg -t -a -u "${HGUSER}" --clearsign
66 } > "$HGTMP/msg.gpg" && mv "$HGTMP/msg.gpg" "$1"
67 else
68 mv "$HGTMP/msg" "$1"
69 fi
70
54
71 exit $?
55 exit $?
@@ -1,7 +1,5 b''
1 #!/usr/bin/python
1 # Command for sending a collection of Mercurial changesets as a series
2 #
2 # of patch emails.
3 # Interactive script for sending a collection of Mercurial changesets
4 # as a series of patch emails.
5 #
3 #
6 # The series is started off with a "[PATCH 0 of N]" introduction,
4 # The series is started off with a "[PATCH 0 of N]" introduction,
7 # which describes the series as a whole.
5 # which describes the series as a whole.
@@ -50,9 +48,9 b''
50 from email.MIMEMultipart import MIMEMultipart
48 from email.MIMEMultipart import MIMEMultipart
51 from email.MIMEText import MIMEText
49 from email.MIMEText import MIMEText
52 from mercurial import commands
50 from mercurial import commands
53 from mercurial import fancyopts
54 from mercurial import hg
51 from mercurial import hg
55 from mercurial import ui
52 from mercurial import ui
53 from mercurial.i18n import gettext as _
56 import os
54 import os
57 import popen2
55 import popen2
58 import smtplib
56 import smtplib
@@ -89,6 +87,17 b' def diffstat(patch):'
89 except: pass
87 except: pass
90
88
91 def patchbomb(ui, repo, *revs, **opts):
89 def patchbomb(ui, repo, *revs, **opts):
90 '''send changesets as a series of patch emails
91
92 The series starts with a "[PATCH 0 of N]" introduction, which
93 describes the series as a whole.
94
95 Each patch email has a Subject line of "[PATCH M of N] ...", using
96 the first line of the changeset description as the subject text.
97 The message contains two or three body parts. First, the rest of
98 the changeset description. Next, (optionally) if the diffstat
99 program is installed, the result of running diffstat on the patch.
100 Finally, the patch itself, as generated by "hg export".'''
92 def prompt(prompt, default = None, rest = ': ', empty_ok = False):
101 def prompt(prompt, default = None, rest = ': ', empty_ok = False):
93 if default: prompt += ' [%s]' % default
102 if default: prompt += ' [%s]' % default
94 prompt += rest
103 prompt += rest
@@ -97,7 +106,7 b' def patchbomb(ui, repo, *revs, **opts):'
97 if r: return r
106 if r: return r
98 if default is not None: return default
107 if default is not None: return default
99 if empty_ok: return r
108 if empty_ok: return r
100 ui.warn('Please enter a valid value.\n')
109 ui.warn(_('Please enter a valid value.\n'))
101
110
102 def confirm(s):
111 def confirm(s):
103 if not prompt(s, default = 'y', rest = '? ').lower().startswith('y'):
112 if not prompt(s, default = 'y', rest = '? ').lower().startswith('y'):
@@ -109,7 +118,7 b' def patchbomb(ui, repo, *revs, **opts):'
109 if summary:
118 if summary:
110 ui.write(summary, '\n')
119 ui.write(summary, '\n')
111 ui.write(s, '\n')
120 ui.write(s, '\n')
112 confirm('Does the diffstat above look okay')
121 confirm(_('Does the diffstat above look okay'))
113 return s
122 return s
114
123
115 def makepatch(patch, idx, total):
124 def makepatch(patch, idx, total):
@@ -128,6 +137,10 b' def patchbomb(ui, repo, *revs, **opts):'
128 # 'Patch subject is complete summary.')
137 # 'Patch subject is complete summary.')
129 #body += '\n\n\n'
138 #body += '\n\n\n'
130
139
140 if opts['plain']:
141 while patch and patch[0].startswith('# '): patch.pop(0)
142 if patch: patch.pop(0)
143 while patch and not patch[0].strip(): patch.pop(0)
131 if opts['diffstat']:
144 if opts['diffstat']:
132 body += cdiffstat('\n'.join(desc), patch) + '\n\n'
145 body += cdiffstat('\n'.join(desc), patch) + '\n\n'
133 body += '\n'.join(patch)
146 body += '\n'.join(patch)
@@ -158,19 +171,20 b' def patchbomb(ui, repo, *revs, **opts):'
158 self.container.append(''.join(self.lines).split('\n'))
171 self.container.append(''.join(self.lines).split('\n'))
159 self.lines = []
172 self.lines = []
160
173
161 commands.export(ui, repo, *args, **{'output': exportee(patches),
174 commands.export(ui, repo, *revs, **{'output': exportee(patches),
175 'switch_parent': False,
162 'text': None})
176 'text': None})
163
177
164 jumbo = []
178 jumbo = []
165 msgs = []
179 msgs = []
166
180
167 ui.write('This patch series consists of %d patches.\n\n' % len(patches))
181 ui.write(_('This patch series consists of %d patches.\n\n') % len(patches))
168
182
169 for p, i in zip(patches, range(len(patches))):
183 for p, i in zip(patches, range(len(patches))):
170 jumbo.extend(p)
184 jumbo.extend(p)
171 msgs.append(makepatch(p, i + 1, len(patches)))
185 msgs.append(makepatch(p, i + 1, len(patches)))
172
186
173 ui.write('\nWrite the introductory message for the patch series.\n\n')
187 ui.write(_('\nWrite the introductory message for the patch series.\n\n'))
174
188
175 sender = (opts['from'] or ui.config('patchbomb', 'from') or
189 sender = (opts['from'] or ui.config('patchbomb', 'from') or
176 prompt('From', ui.username()))
190 prompt('From', ui.username()))
@@ -188,7 +202,7 b' def patchbomb(ui, repo, *revs, **opts):'
188 to = getaddrs('to', 'To')
202 to = getaddrs('to', 'To')
189 cc = getaddrs('cc', 'Cc', '')
203 cc = getaddrs('cc', 'Cc', '')
190
204
191 ui.write('Finish with ^D or a dot on a line by itself.\n\n')
205 ui.write(_('Finish with ^D or a dot on a line by itself.\n\n'))
192
206
193 body = []
207 body = []
194
208
@@ -203,7 +217,7 b' def patchbomb(ui, repo, *revs, **opts):'
203 ui.write('\n')
217 ui.write('\n')
204
218
205 if opts['diffstat']:
219 if opts['diffstat']:
206 d = cdiffstat('Final summary:\n', jumbo)
220 d = cdiffstat(_('Final summary:\n'), jumbo)
207 if d: msg.attach(MIMEText(d))
221 if d: msg.attach(MIMEText(d))
208
222
209 msgs.insert(0, msg)
223 msgs.insert(0, msg)
@@ -247,24 +261,15 b' def patchbomb(ui, repo, *revs, **opts):'
247 if not opts['test']:
261 if not opts['test']:
248 s.close()
262 s.close()
249
263
250 if __name__ == '__main__':
264 cmdtable = {
251 optspec = [('c', 'cc', [], 'email addresses of copy recipients'),
265 'email':
252 ('d', 'diffstat', None, 'add diffstat output to messages'),
266 (patchbomb,
253 ('f', 'from', '', 'email address of sender'),
267 [('c', 'cc', [], 'email addresses of copy recipients'),
254 ('n', 'test', None, 'print messages that would be sent'),
268 ('d', 'diffstat', None, 'add diffstat output to messages'),
255 ('s', 'subject', '', 'subject of introductory message'),
269 ('f', 'from', '', 'email address of sender'),
256 ('t', 'to', [], 'email addresses of recipients')]
270 ('', 'plain', None, 'omit hg patch header'),
257 options = {}
271 ('n', 'test', None, 'print messages that would be sent'),
258 try:
272 ('s', 'subject', '', 'subject of introductory message'),
259 args = fancyopts.fancyopts(sys.argv[1:], commands.globalopts + optspec,
273 ('t', 'to', [], 'email addresses of recipients')],
260 options)
274 "hg email [OPTION]... [REV]...")
261 except fancyopts.getopt.GetoptError, inst:
275 }
262 u = ui.ui()
263 u.warn('error: %s' % inst)
264 sys.exit(1)
265
266 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
267 not options["noninteractive"])
268 repo = hg.repository(ui = u)
269
270 patchbomb(u, repo, *args, **options)
@@ -44,6 +44,39 b' elif [ -n "$DIFF3" ]; then'
44 cp "$LOCAL.orig" "$LOCAL"
44 cp "$LOCAL.orig" "$LOCAL"
45 fi
45 fi
46
46
47 # on MacOS X try FileMerge.app, shipped with Apple's developer tools
48 # TODO: make proper temp files. foo.orig and foo.link are dangerous
49 FILEMERGE='/Developer/Applications/Utilities/FileMerge.app/Contents/MacOS/FileMerge'
50 if type "$FILEMERGE" > /dev/null 2>&1; then
51 cp "$LOCAL.orig" "$LOCAL"
52 ln "$LOCAL" "$LOCAL.link"
53 # filemerge prefers the right by default
54 if ! "$FILEMERGE" -left "$OTHER" -right "$LOCAL" -ancestor "$BASE" -merge "$LOCAL"
55 then
56 echo "FileMerge failed to launch"
57 exit 1
58 fi
59 if ! test "$LOCAL" -ef "$LOCAL.link"
60 then
61 rm "$LOCAL.orig" "$LOCAL.link"
62 exit 0
63 else
64 rm "$LOCAL.link"
65 echo "$LOCAL is unchanged. Was the merge successful?"
66 select answer in yes no
67 do
68 if test "$answer" == "yes"
69 then
70 rm "$LOCAL.orig"
71 exit 0
72 else
73 exit 1
74 fi
75 done
76 exit 1
77 fi
78 fi
79
47 if [ -n "$DISPLAY" ]; then
80 if [ -n "$DISPLAY" ]; then
48 # try using kdiff3, which is fairly nice
81 # try using kdiff3, which is fairly nice
49 if type kdiff3 > /dev/null 2>&1; then
82 if type kdiff3 > /dev/null 2>&1; then
This diff has been collapsed as it changes many lines, (504 lines changed) Show them Hide them
@@ -40,14 +40,14 b' def matchpats(repo, pats=[], opts={}, he'
40 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
40 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
41 cwd = ''
41 cwd = ''
42 return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
42 return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
43 opts.get('exclude'), head) + (cwd,)
43 opts.get('exclude'), head)
44
44
45 def makewalk(repo, pats, opts, node=None, head=''):
45 def makewalk(repo, pats, opts, node=None, head=''):
46 files, matchfn, anypats, cwd = matchpats(repo, pats, opts, head)
46 files, matchfn, anypats = matchpats(repo, pats, opts, head)
47 exact = dict(zip(files, files))
47 exact = dict(zip(files, files))
48 def walk():
48 def walk():
49 for src, fn in repo.walk(node=node, files=files, match=matchfn):
49 for src, fn in repo.walk(node=node, files=files, match=matchfn):
50 yield src, fn, util.pathto(cwd, fn), fn in exact
50 yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact
51 return files, matchfn, walk()
51 return files, matchfn, walk()
52
52
53 def walk(repo, pats, opts, node=None, head=''):
53 def walk(repo, pats, opts, node=None, head=''):
@@ -82,7 +82,7 b' def walkchangerevs(ui, repo, pats, opts)'
82 "iter", rev, None: in-order traversal of the revs earlier iterated
82 "iter", rev, None: in-order traversal of the revs earlier iterated
83 over with "add" - use to display data'''
83 over with "add" - use to display data'''
84
84
85 files, matchfn, anypats, cwd = matchpats(repo, pats, opts)
85 files, matchfn, anypats = matchpats(repo, pats, opts)
86
86
87 if repo.changelog.count() == 0:
87 if repo.changelog.count() == 0:
88 return [], False, matchfn
88 return [], False, matchfn
@@ -170,8 +170,10 b' def revrange(ui, repo, revs, revlog=None'
170 num = int(val)
170 num = int(val)
171 if str(num) != val:
171 if str(num) != val:
172 raise ValueError
172 raise ValueError
173 if num < 0: num += revcount
173 if num < 0:
174 if num < 0: num = 0
174 num += revcount
175 if num < 0:
176 num = 0
175 elif num >= revcount:
177 elif num >= revcount:
176 raise ValueError
178 raise ValueError
177 except ValueError:
179 except ValueError:
@@ -191,12 +193,14 b' def revrange(ui, repo, revs, revlog=None'
191 end = fix(end, revcount - 1)
193 end = fix(end, revcount - 1)
192 step = start > end and -1 or 1
194 step = start > end and -1 or 1
193 for rev in xrange(start, end+step, step):
195 for rev in xrange(start, end+step, step):
194 if rev in seen: continue
196 if rev in seen:
197 continue
195 seen[rev] = 1
198 seen[rev] = 1
196 yield str(rev)
199 yield str(rev)
197 else:
200 else:
198 rev = fix(spec, None)
201 rev = fix(spec, None)
199 if rev in seen: continue
202 if rev in seen:
203 continue
200 seen[rev] = 1
204 seen[rev] = 1
201 yield str(rev)
205 yield str(rev)
202
206
@@ -259,13 +263,13 b' def make_file(repo, r, pat, node=None,'
259 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always,
263 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always,
260 changes=None, text=False):
264 changes=None, text=False):
261 if not changes:
265 if not changes:
262 (c, a, d, u) = repo.changes(node1, node2, files, match=match)
266 changes = repo.changes(node1, node2, files, match=match)
263 else:
267 modified, added, removed, deleted, unknown = changes
264 (c, a, d, u) = changes
265 if files:
268 if files:
266 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
269 modified, added, removed = map(lambda x: filterfiles(files, x),
267
270 (modified, added, removed))
268 if not c and not a and not d:
271
272 if not modified and not added and not removed:
269 return
273 return
270
274
271 if node2:
275 if node2:
@@ -279,7 +283,7 b' def dodiff(fp, ui, repo, node1, node2, f'
279 if not node1:
283 if not node1:
280 node1 = repo.dirstate.parents()[0]
284 node1 = repo.dirstate.parents()[0]
281 def read(f):
285 def read(f):
282 return repo.wfile(f).read()
286 return repo.wread(f)
283
287
284 if ui.quiet:
288 if ui.quiet:
285 r = None
289 r = None
@@ -291,20 +295,26 b' def dodiff(fp, ui, repo, node1, node2, f'
291 mmap = repo.manifest.read(change[0])
295 mmap = repo.manifest.read(change[0])
292 date1 = util.datestr(change[2])
296 date1 = util.datestr(change[2])
293
297
294 for f in c:
298 diffopts = ui.diffopts()
299 showfunc = diffopts['showfunc']
300 ignorews = diffopts['ignorews']
301 for f in modified:
295 to = None
302 to = None
296 if f in mmap:
303 if f in mmap:
297 to = repo.file(f).read(mmap[f])
304 to = repo.file(f).read(mmap[f])
298 tn = read(f)
305 tn = read(f)
299 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
306 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text,
300 for f in a:
307 showfunc=showfunc, ignorews=ignorews))
308 for f in added:
301 to = None
309 to = None
302 tn = read(f)
310 tn = read(f)
303 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
311 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text,
304 for f in d:
312 showfunc=showfunc, ignorews=ignorews))
313 for f in removed:
305 to = repo.file(f).read(mmap[f])
314 to = repo.file(f).read(mmap[f])
306 tn = None
315 tn = None
307 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
316 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text,
317 showfunc=showfunc, ignorews=ignorews))
308
318
309 def trimuser(ui, name, rev, revcache):
319 def trimuser(ui, name, rev, revcache):
310 """trim the name of the user who committed a change"""
320 """trim the name of the user who committed a change"""
@@ -439,7 +449,7 b' def help_(ui, cmd=None, with_version=Fal'
439 if e[0].__doc__:
449 if e[0].__doc__:
440 d = e[0].__doc__.splitlines(0)[0].rstrip()
450 d = e[0].__doc__.splitlines(0)[0].rstrip()
441 h[f] = d
451 h[f] = d
442 cmds[f]=c.lstrip("^")
452 cmds[f] = c.lstrip("^")
443
453
444 fns = h.keys()
454 fns = h.keys()
445 fns.sort()
455 fns.sort()
@@ -447,7 +457,7 b' def help_(ui, cmd=None, with_version=Fal'
447 for f in fns:
457 for f in fns:
448 if ui.verbose:
458 if ui.verbose:
449 commands = cmds[f].replace("|",", ")
459 commands = cmds[f].replace("|",", ")
450 ui.write(" %s:\n %s\n"%(commands,h[f]))
460 ui.write(" %s:\n %s\n"%(commands, h[f]))
451 else:
461 else:
452 ui.write(' %-*s %s\n' % (m, f, h[f]))
462 ui.write(' %-*s %s\n' % (m, f, h[f]))
453
463
@@ -463,7 +473,8 b' def help_(ui, cmd=None, with_version=Fal'
463 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
473 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
464 longopt and " --%s" % longopt),
474 longopt and " --%s" % longopt),
465 "%s%s" % (desc,
475 "%s%s" % (desc,
466 default and _(" (default: %s)") % default
476 default
477 and _(" (default: %s)") % default
467 or "")))
478 or "")))
468
479
469 if opt_output:
480 if opt_output:
@@ -489,7 +500,8 b' def add(ui, repo, *pats, **opts):'
489 names = []
500 names = []
490 for src, abs, rel, exact in walk(repo, pats, opts):
501 for src, abs, rel, exact in walk(repo, pats, opts):
491 if exact:
502 if exact:
492 if ui.verbose: ui.status(_('adding %s\n') % rel)
503 if ui.verbose:
504 ui.status(_('adding %s\n') % rel)
493 names.append(abs)
505 names.append(abs)
494 elif repo.dirstate.state(abs) == '?':
506 elif repo.dirstate.state(abs) == '?':
495 ui.status(_('adding %s\n') % rel)
507 ui.status(_('adding %s\n') % rel)
@@ -509,11 +521,11 b' def addremove(ui, repo, *pats, **opts):'
509 if src == 'f' and repo.dirstate.state(abs) == '?':
521 if src == 'f' and repo.dirstate.state(abs) == '?':
510 add.append(abs)
522 add.append(abs)
511 if ui.verbose or not exact:
523 if ui.verbose or not exact:
512 ui.status(_('adding %s\n') % rel)
524 ui.status(_('adding %s\n') % ((pats and rel) or abs))
513 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
525 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
514 remove.append(abs)
526 remove.append(abs)
515 if ui.verbose or not exact:
527 if ui.verbose or not exact:
516 ui.status(_('removing %s\n') % rel)
528 ui.status(_('removing %s\n') % ((pats and rel) or abs))
517 repo.add(add)
529 repo.add(add)
518 repo.remove(remove)
530 repo.remove(remove)
519
531
@@ -539,11 +551,11 b' def annotate(ui, repo, *pats, **opts):'
539
551
540 dcache = {}
552 dcache = {}
541 def getdate(rev):
553 def getdate(rev):
542 datestr = dcache.get(rev)
554 datestr = dcache.get(rev)
543 if datestr is None:
555 if datestr is None:
544 cl = repo.changelog.read(repo.changelog.node(rev))
556 cl = repo.changelog.read(repo.changelog.node(rev))
545 datestr = dcache[rev] = util.datestr(cl[2])
557 datestr = dcache[rev] = util.datestr(cl[2])
546 return datestr
558 return datestr
547
559
548 if not pats:
560 if not pats:
549 raise util.Abort(_('at least one file name or pattern required'))
561 raise util.Abort(_('at least one file name or pattern required'))
@@ -562,12 +574,13 b' def annotate(ui, repo, *pats, **opts):'
562
574
563 for src, abs, rel, exact in walk(repo, pats, opts):
575 for src, abs, rel, exact in walk(repo, pats, opts):
564 if abs not in mmap:
576 if abs not in mmap:
565 ui.warn(_("warning: %s is not in the repository!\n") % rel)
577 ui.warn(_("warning: %s is not in the repository!\n") %
578 ((pats and rel) or abs))
566 continue
579 continue
567
580
568 f = repo.file(abs)
581 f = repo.file(abs)
569 if not opts['text'] and util.binary(f.read(mmap[abs])):
582 if not opts['text'] and util.binary(f.read(mmap[abs])):
570 ui.write(_("%s: binary file\n") % rel)
583 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
571 continue
584 continue
572
585
573 lines = f.annotate(mmap[abs])
586 lines = f.annotate(mmap[abs])
@@ -722,7 +735,8 b' def clone(ui, source, dest=None, **opts)'
722 try:
735 try:
723 util.copyfiles(src, dst)
736 util.copyfiles(src, dst)
724 except OSError, inst:
737 except OSError, inst:
725 if inst.errno != errno.ENOENT: raise
738 if inst.errno != errno.ENOENT:
739 raise
726
740
727 repo = hg.repository(ui, dest)
741 repo = hg.repository(ui, dest)
728
742
@@ -730,7 +744,8 b' def clone(ui, source, dest=None, **opts)'
730 revs = None
744 revs = None
731 if opts['rev']:
745 if opts['rev']:
732 if not other.local():
746 if not other.local():
733 raise util.Abort("clone -r not supported yet for remote repositories.")
747 error = _("clone -r not supported yet for remote repositories.")
748 raise util.Abort(error)
734 else:
749 else:
735 revs = [other.lookup(rev) for rev in opts['rev']]
750 revs = [other.lookup(rev) for rev in opts['rev']]
736 repo = hg.repository(ui, dest, create=1)
751 repo = hg.repository(ui, dest, create=1)
@@ -775,10 +790,11 b' def commit(ui, repo, *pats, **opts):'
775
790
776 if opts['addremove']:
791 if opts['addremove']:
777 addremove(ui, repo, *pats, **opts)
792 addremove(ui, repo, *pats, **opts)
778 fns, match, anypats, cwd = matchpats(repo, pats, opts)
793 fns, match, anypats = matchpats(repo, pats, opts)
779 if pats:
794 if pats:
780 c, a, d, u = repo.changes(files=fns, match=match)
795 modified, added, removed, deleted, unknown = (
781 files = c + a + [fn for fn in d if repo.dirstate.state(fn) == 'r']
796 repo.changes(files=fns, match=match))
797 files = modified + added + removed
782 else:
798 else:
783 files = []
799 files = []
784 try:
800 try:
@@ -794,10 +810,12 b' def docopy(ui, repo, pats, opts):'
794
810
795 def okaytocopy(abs, rel, exact):
811 def okaytocopy(abs, rel, exact):
796 reasons = {'?': _('is not managed'),
812 reasons = {'?': _('is not managed'),
797 'a': _('has been marked for add')}
813 'a': _('has been marked for add'),
814 'r': _('has been marked for remove')}
798 reason = reasons.get(repo.dirstate.state(abs))
815 reason = reasons.get(repo.dirstate.state(abs))
799 if reason:
816 if reason:
800 if exact: ui.warn(_('%s: not copying - file %s\n') % (rel, reason))
817 if exact:
818 ui.warn(_('%s: not copying - file %s\n') % (rel, reason))
801 else:
819 else:
802 return True
820 return True
803
821
@@ -845,12 +863,11 b' def docopy(ui, repo, pats, opts):'
845
863
846 def targetpathfn(pat, dest, srcs):
864 def targetpathfn(pat, dest, srcs):
847 if os.path.isdir(pat):
865 if os.path.isdir(pat):
848 if pat.endswith(os.sep):
866 abspfx = util.canonpath(repo.root, cwd, pat)
849 pat = pat[:-len(os.sep)]
850 if destdirexists:
867 if destdirexists:
851 striplen = len(os.path.split(pat)[0])
868 striplen = len(os.path.split(abspfx)[0])
852 else:
869 else:
853 striplen = len(pat)
870 striplen = len(abspfx)
854 if striplen:
871 if striplen:
855 striplen += len(os.sep)
872 striplen += len(os.sep)
856 res = lambda p: os.path.join(dest, p[striplen:])
873 res = lambda p: os.path.join(dest, p[striplen:])
@@ -864,34 +881,36 b' def docopy(ui, repo, pats, opts):'
864 if util.patkind(pat, None)[0]:
881 if util.patkind(pat, None)[0]:
865 # a mercurial pattern
882 # a mercurial pattern
866 res = lambda p: os.path.join(dest, os.path.basename(p))
883 res = lambda p: os.path.join(dest, os.path.basename(p))
867 elif len(util.canonpath(repo.root, cwd, pat)) < len(srcs[0][0]):
868 # A directory. Either the target path contains the last
869 # component of the source path or it does not.
870 def evalpath(striplen):
871 score = 0
872 for s in srcs:
873 t = os.path.join(dest, s[1][striplen:])
874 if os.path.exists(t):
875 score += 1
876 return score
877
878 if pat.endswith(os.sep):
879 pat = pat[:-len(os.sep)]
880 striplen = len(pat) + len(os.sep)
881 if os.path.isdir(os.path.join(dest, os.path.split(pat)[1])):
882 score = evalpath(striplen)
883 striplen1 = len(os.path.split(pat)[0])
884 if striplen1:
885 striplen1 += len(os.sep)
886 if evalpath(striplen1) > score:
887 striplen = striplen1
888 res = lambda p: os.path.join(dest, p[striplen:])
889 else:
884 else:
890 # a file
885 abspfx = util.canonpath(repo.root, cwd, pat)
891 if destdirexists:
886 if len(abspfx) < len(srcs[0][0]):
892 res = lambda p: os.path.join(dest, os.path.basename(p))
887 # A directory. Either the target path contains the last
888 # component of the source path or it does not.
889 def evalpath(striplen):
890 score = 0
891 for s in srcs:
892 t = os.path.join(dest, s[0][striplen:])
893 if os.path.exists(t):
894 score += 1
895 return score
896
897 striplen = len(abspfx)
898 if striplen:
899 striplen += len(os.sep)
900 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
901 score = evalpath(striplen)
902 striplen1 = len(os.path.split(abspfx)[0])
903 if striplen1:
904 striplen1 += len(os.sep)
905 if evalpath(striplen1) > score:
906 striplen = striplen1
907 res = lambda p: os.path.join(dest, p[striplen:])
893 else:
908 else:
894 res = lambda p: dest
909 # a file
910 if destdirexists:
911 res = lambda p: os.path.join(dest, os.path.basename(p))
912 else:
913 res = lambda p: dest
895 return res
914 return res
896
915
897
916
@@ -923,7 +942,7 b' def docopy(ui, repo, pats, opts):'
923
942
924 for targetpath, srcs in copylist:
943 for targetpath, srcs in copylist:
925 for abssrc, relsrc, exact in srcs:
944 for abssrc, relsrc, exact in srcs:
926 copy(abssrc, relsrc, targetpath(relsrc), exact)
945 copy(abssrc, relsrc, targetpath(abssrc), exact)
927
946
928 if errors:
947 if errors:
929 ui.warn(_('(consider using --after)\n'))
948 ui.warn(_('(consider using --after)\n'))
@@ -985,7 +1004,8 b' def debugcheckstate(ui, repo):'
985 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1004 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
986 errors += 1
1005 errors += 1
987 if errors:
1006 if errors:
988 raise util.Abort(_(".hg/dirstate inconsistent with current parent's manifest"))
1007 error = _(".hg/dirstate inconsistent with current parent's manifest")
1008 raise util.Abort(error)
989
1009
990 def debugconfig(ui):
1010 def debugconfig(ui):
991 """show combined config settings from all hgrc files"""
1011 """show combined config settings from all hgrc files"""
@@ -1111,7 +1131,7 b' def diff(ui, repo, *pats, **opts):'
1111 if len(revs) > 2:
1131 if len(revs) > 2:
1112 raise util.Abort(_("too many revisions to diff"))
1132 raise util.Abort(_("too many revisions to diff"))
1113
1133
1114 fns, matchfn, anypats, cwd = matchpats(repo, pats, opts)
1134 fns, matchfn, anypats = matchpats(repo, pats, opts)
1115
1135
1116 dodiff(sys.stdout, ui, repo, node1, node2, fns, match=matchfn,
1136 dodiff(sys.stdout, ui, repo, node1, node2, fns, match=matchfn,
1117 text=opts['text'])
1137 text=opts['text'])
@@ -1119,11 +1139,11 b' def diff(ui, repo, *pats, **opts):'
1119 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
1139 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
1120 node = repo.lookup(changeset)
1140 node = repo.lookup(changeset)
1121 parents = [p for p in repo.changelog.parents(node) if p != nullid]
1141 parents = [p for p in repo.changelog.parents(node) if p != nullid]
1142 if opts['switch_parent']:
1143 parents.reverse()
1122 prev = (parents and parents[0]) or nullid
1144 prev = (parents and parents[0]) or nullid
1123 change = repo.changelog.read(node)
1145 change = repo.changelog.read(node)
1124
1146
1125 if opts['switch_parent']:
1126 parents.reverse()
1127 fp = make_file(repo, repo.changelog, opts['output'],
1147 fp = make_file(repo, repo.changelog, opts['output'],
1128 node=node, total=total, seqno=seqno,
1148 node=node, total=total, seqno=seqno,
1129 revwidth=revwidth)
1149 revwidth=revwidth)
@@ -1176,7 +1196,8 b' def export(ui, repo, *changesets, **opts'
1176 revs = list(revrange(ui, repo, changesets))
1196 revs = list(revrange(ui, repo, changesets))
1177 total = len(revs)
1197 total = len(revs)
1178 revwidth = max(map(len, revs))
1198 revwidth = max(map(len, revs))
1179 ui.note(len(revs) > 1 and _("Exporting patches:\n") or _("Exporting patch:\n"))
1199 msg = len(revs) > 1 and _("Exporting patches:\n") or _("Exporting patch:\n")
1200 ui.note(msg)
1180 for cset in revs:
1201 for cset in revs:
1181 seqno += 1
1202 seqno += 1
1182 doexport(ui, repo, cset, seqno, total, revwidth, opts)
1203 doexport(ui, repo, cset, seqno, total, revwidth, opts)
@@ -1191,7 +1212,7 b' def forget(ui, repo, *pats, **opts):'
1191 if repo.dirstate.state(abs) == 'a':
1212 if repo.dirstate.state(abs) == 'a':
1192 forget.append(abs)
1213 forget.append(abs)
1193 if ui.verbose or not exact:
1214 if ui.verbose or not exact:
1194 ui.status(_('forgetting %s\n') % rel)
1215 ui.status(_('forgetting %s\n') % ((pats and rel) or abs))
1195 repo.forget(forget)
1216 repo.forget(forget)
1196
1217
1197 def grep(ui, repo, pattern, *pats, **opts):
1218 def grep(ui, repo, pattern, *pats, **opts):
@@ -1272,13 +1293,17 b' def grep(ui, repo, pattern, *pats, **opt'
1272 change = ((l in states) and '-') or '+'
1293 change = ((l in states) and '-') or '+'
1273 r = prev[fn]
1294 r = prev[fn]
1274 cols = [fn, str(rev)]
1295 cols = [fn, str(rev)]
1275 if opts['line_number']: cols.append(str(l.linenum))
1296 if opts['line_number']:
1276 if opts['all']: cols.append(change)
1297 cols.append(str(l.linenum))
1277 if opts['user']: cols.append(trimuser(ui, getchange(rev)[1], rev,
1298 if opts['all']:
1299 cols.append(change)
1300 if opts['user']:
1301 cols.append(trimuser(ui, getchange(rev)[1], rev,
1278 ucache))
1302 ucache))
1279 if opts['files_with_matches']:
1303 if opts['files_with_matches']:
1280 c = (fn, rev)
1304 c = (fn, rev)
1281 if c in filerevmatches: continue
1305 if c in filerevmatches:
1306 continue
1282 filerevmatches[c] = 1
1307 filerevmatches[c] = 1
1283 else:
1308 else:
1284 cols.append(l.line)
1309 cols.append(l.line)
@@ -1300,7 +1325,8 b' def grep(ui, repo, pattern, *pats, **opt'
1300 mf = repo.manifest.read(change[0])
1325 mf = repo.manifest.read(change[0])
1301 matches[rev] = {}
1326 matches[rev] = {}
1302 for fn in fns:
1327 for fn in fns:
1303 if fn in skip: continue
1328 if fn in skip:
1329 continue
1304 fstate.setdefault(fn, {})
1330 fstate.setdefault(fn, {})
1305 try:
1331 try:
1306 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1332 grepbody(fn, rev, getfile(fn).read(mf[fn]))
@@ -1310,7 +1336,8 b' def grep(ui, repo, pattern, *pats, **opt'
1310 states = matches[rev].items()
1336 states = matches[rev].items()
1311 states.sort()
1337 states.sort()
1312 for fn, m in states:
1338 for fn, m in states:
1313 if fn in skip: continue
1339 if fn in skip:
1340 continue
1314 if incrementing or not opts['all'] or fstate[fn]:
1341 if incrementing or not opts['all'] or fstate[fn]:
1315 pos, neg = display(fn, rev, m, fstate[fn])
1342 pos, neg = display(fn, rev, m, fstate[fn])
1316 count += pos + neg
1343 count += pos + neg
@@ -1323,7 +1350,8 b' def grep(ui, repo, pattern, *pats, **opt'
1323 fstate = fstate.items()
1350 fstate = fstate.items()
1324 fstate.sort()
1351 fstate.sort()
1325 for fn, state in fstate:
1352 for fn, state in fstate:
1326 if fn in skip: continue
1353 if fn in skip:
1354 continue
1327 display(fn, rev, {}, state)
1355 display(fn, rev, {}, state)
1328 return (count == 0 and 1) or 0
1356 return (count == 0 and 1) or 0
1329
1357
@@ -1361,9 +1389,10 b' def identify(ui, repo):'
1361 return
1389 return
1362
1390
1363 hexfunc = ui.verbose and hex or short
1391 hexfunc = ui.verbose and hex or short
1364 (c, a, d, u) = repo.changes()
1392 modified, added, removed, deleted, unknown = repo.changes()
1365 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
1393 output = ["%s%s" %
1366 (c or a or d) and "+" or "")]
1394 ('+'.join([hexfunc(parent) for parent in parents]),
1395 (modified or added or removed or deleted) and "+" or "")]
1367
1396
1368 if not ui.quiet:
1397 if not ui.quiet:
1369 # multiple tags for a single parent separated by '/'
1398 # multiple tags for a single parent separated by '/'
@@ -1392,8 +1421,8 b' def import_(ui, repo, patch1, *patches, '
1392 patches = (patch1,) + patches
1421 patches = (patch1,) + patches
1393
1422
1394 if not opts['force']:
1423 if not opts['force']:
1395 (c, a, d, u) = repo.changes()
1424 modified, added, removed, deleted, unknown = repo.changes()
1396 if c or a or d:
1425 if modified or added or removed or deleted:
1397 raise util.Abort(_("outstanding uncommitted changes"))
1426 raise util.Abort(_("outstanding uncommitted changes"))
1398
1427
1399 d = opts["base"]
1428 d = opts["base"]
@@ -1418,7 +1447,8 b' def import_(ui, repo, patch1, *patches, '
1418 line = line.rstrip()
1447 line = line.rstrip()
1419 if (not message and not hgpatch and
1448 if (not message and not hgpatch and
1420 mailre.match(line) and not opts['force']):
1449 mailre.match(line) and not opts['force']):
1421 if len(line) > 35: line = line[:32] + '...'
1450 if len(line) > 35:
1451 line = line[:32] + '...'
1422 raise util.Abort(_('first line looks like a '
1452 raise util.Abort(_('first line looks like a '
1423 'mail header: ') + line)
1453 'mail header: ') + line)
1424 if diffre.match(line):
1454 if diffre.match(line):
@@ -1510,14 +1540,20 b' def locate(ui, repo, *pats, **opts):'
1510 that contain white space as multiple filenames.
1540 that contain white space as multiple filenames.
1511 """
1541 """
1512 end = opts['print0'] and '\0' or '\n'
1542 end = opts['print0'] and '\0' or '\n'
1513
1543 rev = opts['rev']
1514 for src, abs, rel, exact in walk(repo, pats, opts, '(?:.*/|)'):
1544 if rev:
1515 if repo.dirstate.state(abs) == '?':
1545 node = repo.lookup(rev)
1546 else:
1547 node = None
1548
1549 for src, abs, rel, exact in walk(repo, pats, opts, node=node,
1550 head='(?:.*/|)'):
1551 if not node and repo.dirstate.state(abs) == '?':
1516 continue
1552 continue
1517 if opts['fullpath']:
1553 if opts['fullpath']:
1518 ui.write(os.path.join(repo.root, abs), end)
1554 ui.write(os.path.join(repo.root, abs), end)
1519 else:
1555 else:
1520 ui.write(rel, end)
1556 ui.write(((pats and rel) or abs), end)
1521
1557
1522 def log(ui, repo, *pats, **opts):
1558 def log(ui, repo, *pats, **opts):
1523 """show revision history of entire repository or files
1559 """show revision history of entire repository or files
@@ -1561,9 +1597,9 b' def log(ui, repo, *pats, **opts):'
1561 parents = [p for p in repo.changelog.parents(changenode)
1597 parents = [p for p in repo.changelog.parents(changenode)
1562 if p != nullid]
1598 if p != nullid]
1563 if opts['no_merges'] and len(parents) == 2:
1599 if opts['no_merges'] and len(parents) == 2:
1564 continue
1600 continue
1565 if opts['only_merges'] and len(parents) != 2:
1601 if opts['only_merges'] and len(parents) != 2:
1566 continue
1602 continue
1567
1603
1568 br = None
1604 br = None
1569 if opts['keyword']:
1605 if opts['keyword']:
@@ -1710,7 +1746,7 b' def pull(ui, repo, source="default", **o'
1710 other = hg.repository(ui, source)
1746 other = hg.repository(ui, source)
1711 revs = None
1747 revs = None
1712 if opts['rev'] and not other.local():
1748 if opts['rev'] and not other.local():
1713 raise util.Abort("pull -r doesn't work for remote repositories yet")
1749 raise util.Abort(_("pull -r doesn't work for remote repositories yet"))
1714 elif opts['rev']:
1750 elif opts['rev']:
1715 revs = [other.lookup(rev) for rev in opts['rev']]
1751 revs = [other.lookup(rev) for rev in opts['rev']]
1716 r = repo.pull(other, heads=revs)
1752 r = repo.pull(other, heads=revs)
@@ -1757,13 +1793,19 b' def push(ui, repo, dest="default-push", '
1757 return r
1793 return r
1758
1794
1759 def rawcommit(ui, repo, *flist, **rc):
1795 def rawcommit(ui, repo, *flist, **rc):
1760 """raw commit interface
1796 """raw commit interface (DEPRECATED)
1761
1797
1762 Lowlevel commit, for use in helper scripts.
1798 Lowlevel commit, for use in helper scripts.
1763
1799
1764 This command is not intended to be used by normal users, as it is
1800 This command is not intended to be used by normal users, as it is
1765 primarily useful for importing from other SCMs.
1801 primarily useful for importing from other SCMs.
1802
1803 This command is now deprecated and will be removed in a future
1804 release, please use debugsetparents and commit instead.
1766 """
1805 """
1806
1807 ui.warn(_("(the rawcommit command is deprecated)\n"))
1808
1767 message = rc['message']
1809 message = rc['message']
1768 if not message and rc['logfile']:
1810 if not message and rc['logfile']:
1769 try:
1811 try:
@@ -1808,18 +1850,23 b' def remove(ui, repo, pat, *pats, **opts)'
1808 """
1850 """
1809 names = []
1851 names = []
1810 def okaytoremove(abs, rel, exact):
1852 def okaytoremove(abs, rel, exact):
1811 c, a, d, u = repo.changes(files = [abs])
1853 modified, added, removed, deleted, unknown = repo.changes(files=[abs])
1812 reason = None
1854 reason = None
1813 if c: reason = _('is modified')
1855 if modified:
1814 elif a: reason = _('has been marked for add')
1856 reason = _('is modified')
1815 elif u: reason = _('is not managed')
1857 elif added:
1858 reason = _('has been marked for add')
1859 elif unknown:
1860 reason = _('is not managed')
1816 if reason:
1861 if reason:
1817 if exact: ui.warn(_('not removing %s: file %s\n') % (rel, reason))
1862 if exact:
1863 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
1818 else:
1864 else:
1819 return True
1865 return True
1820 for src, abs, rel, exact in walk(repo, (pat,) + pats, opts):
1866 for src, abs, rel, exact in walk(repo, (pat,) + pats, opts):
1821 if okaytoremove(abs, rel, exact):
1867 if okaytoremove(abs, rel, exact):
1822 if ui.verbose or not exact: ui.status(_('removing %s\n') % rel)
1868 if ui.verbose or not exact:
1869 ui.status(_('removing %s\n') % rel)
1823 names.append(abs)
1870 names.append(abs)
1824 repo.remove(names, unlink=True)
1871 repo.remove(names, unlink=True)
1825
1872
@@ -1843,7 +1890,8 b' def rename(ui, repo, *pats, **opts):'
1843 errs, copied = docopy(ui, repo, pats, opts)
1890 errs, copied = docopy(ui, repo, pats, opts)
1844 names = []
1891 names = []
1845 for abs, rel, exact in copied:
1892 for abs, rel, exact in copied:
1846 if ui.verbose or not exact: ui.status(_('removing %s\n') % rel)
1893 if ui.verbose or not exact:
1894 ui.status(_('removing %s\n') % rel)
1847 names.append(abs)
1895 names.append(abs)
1848 repo.remove(names, unlink=True)
1896 repo.remove(names, unlink=True)
1849 return errs
1897 return errs
@@ -1865,10 +1913,10 b' def revert(ui, repo, *pats, **opts):'
1865 node = opts['rev'] and repo.lookup(opts['rev']) or \
1913 node = opts['rev'] and repo.lookup(opts['rev']) or \
1866 repo.dirstate.parents()[0]
1914 repo.dirstate.parents()[0]
1867
1915
1868 files, choose, anypats, cwd = matchpats(repo, pats, opts)
1916 files, choose, anypats = matchpats(repo, pats, opts)
1869 (c, a, d, u) = repo.changes(match=choose)
1917 modified, added, removed, deleted, unknown = repo.changes(match=choose)
1870 repo.forget(a)
1918 repo.forget(added)
1871 repo.undelete(d)
1919 repo.undelete(removed + deleted)
1872
1920
1873 return repo.update(node, False, True, choose, False)
1921 return repo.update(node, False, True, choose, False)
1874
1922
@@ -1968,7 +2016,7 b' def serve(ui, repo, **opts):'
1968 try:
2016 try:
1969 httpd = hgweb.create_server(repo)
2017 httpd = hgweb.create_server(repo)
1970 except socket.error, inst:
2018 except socket.error, inst:
1971 raise util.Abort('cannot start server: ' + inst.args[1])
2019 raise util.Abort(_('cannot start server: ') + inst.args[1])
1972
2020
1973 if ui.verbose:
2021 if ui.verbose:
1974 addr, port = httpd.socket.getsockname()
2022 addr, port = httpd.socket.getsockname()
@@ -1995,17 +2043,21 b' def status(ui, repo, *pats, **opts):'
1995 M = modified
2043 M = modified
1996 A = added
2044 A = added
1997 R = removed
2045 R = removed
2046 ! = deleted, but still tracked
1998 ? = not tracked
2047 ? = not tracked
1999 """
2048 """
2000
2049
2001 files, matchfn, anypats, cwd = matchpats(repo, pats, opts)
2050 files, matchfn, anypats = matchpats(repo, pats, opts)
2002 (c, a, d, u) = [[util.pathto(cwd, x) for x in n]
2051 cwd = (pats and repo.getcwd()) or ''
2003 for n in repo.changes(files=files, match=matchfn)]
2052 modified, added, removed, deleted, unknown = [
2004
2053 [util.pathto(cwd, x) for x in n]
2005 changetypes = [(_('modified'), 'M', c),
2054 for n in repo.changes(files=files, match=matchfn)]
2006 (_('added'), 'A', a),
2055
2007 (_('removed'), 'R', d),
2056 changetypes = [(_('modified'), 'M', modified),
2008 (_('unknown'), '?', u)]
2057 (_('added'), 'A', added),
2058 (_('removed'), 'R', removed),
2059 (_('deleted'), '!', deleted),
2060 (_('unknown'), '?', unknown)]
2009
2061
2010 end = opts['print0'] and '\0' or '\n'
2062 end = opts['print0'] and '\0' or '\n'
2011
2063
@@ -2019,7 +2071,7 b' def status(ui, repo, *pats, **opts):'
2019 for f in changes:
2071 for f in changes:
2020 ui.write(format % f)
2072 ui.write(format % f)
2021
2073
2022 def tag(ui, repo, name, rev=None, **opts):
2074 def tag(ui, repo, name, rev_=None, **opts):
2023 """add a tag for the current tip or a given revision
2075 """add a tag for the current tip or a given revision
2024
2076
2025 Name a particular revision using <name>.
2077 Name a particular revision using <name>.
@@ -2033,14 +2085,20 b' def tag(ui, repo, name, rev=None, **opts'
2033 To facilitate version control, distribution, and merging of tags,
2085 To facilitate version control, distribution, and merging of tags,
2034 they are stored as a file named ".hgtags" which is managed
2086 they are stored as a file named ".hgtags" which is managed
2035 similarly to other project files and can be hand-edited if
2087 similarly to other project files and can be hand-edited if
2036 necessary.
2088 necessary. The file '.hg/localtags' is used for local tags (not
2089 shared among repositories).
2037 """
2090 """
2038 if name == "tip":
2091 if name == "tip":
2039 raise util.Abort(_("the name 'tip' is reserved"))
2092 raise util.Abort(_("the name 'tip' is reserved"))
2040 if 'rev' in opts:
2093 if rev_ is not None:
2041 rev = opts['rev']
2094 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2042 if rev:
2095 "please use 'hg tag [-r REV] NAME' instead\n"))
2043 r = hex(repo.lookup(rev))
2096 if opts['rev']:
2097 raise util.Abort(_("use only one form to specify the revision"))
2098 if opts['rev']:
2099 rev_ = opts['rev']
2100 if rev_:
2101 r = hex(repo.lookup(rev_))
2044 else:
2102 else:
2045 r = hex(repo.changelog.tip())
2103 r = hex(repo.changelog.tip())
2046
2104
@@ -2053,8 +2111,7 b' def tag(ui, repo, name, rev=None, **opts'
2053 repo.opener("localtags", "a").write("%s %s\n" % (r, name))
2111 repo.opener("localtags", "a").write("%s %s\n" % (r, name))
2054 return
2112 return
2055
2113
2056 (c, a, d, u) = repo.changes()
2114 for x in repo.changes():
2057 for x in (c, a, d, u):
2058 if ".hgtags" in x:
2115 if ".hgtags" in x:
2059 raise util.Abort(_("working copy of .hgtags is changed "
2116 raise util.Abort(_("working copy of .hgtags is changed "
2060 "(please commit .hgtags manually)"))
2117 "(please commit .hgtags manually)"))
@@ -2095,7 +2152,7 b' def tip(ui, repo):'
2095 n = repo.changelog.tip()
2152 n = repo.changelog.tip()
2096 show_changeset(ui, repo, changenode=n)
2153 show_changeset(ui, repo, changenode=n)
2097
2154
2098 def unbundle(ui, repo, fname):
2155 def unbundle(ui, repo, fname, **opts):
2099 """apply a changegroup file
2156 """apply a changegroup file
2100
2157
2101 Apply a compressed changegroup file generated by the bundle
2158 Apply a compressed changegroup file generated by the bundle
@@ -2112,7 +2169,13 b' def unbundle(ui, repo, fname):'
2112 yield zd.decompress(chunk)
2169 yield zd.decompress(chunk)
2113
2170
2114 bzgen = bzgenerator(util.filechunkiter(f, 4096))
2171 bzgen = bzgenerator(util.filechunkiter(f, 4096))
2115 repo.addchangegroup(util.chunkbuffer(bzgen))
2172 if repo.addchangegroup(util.chunkbuffer(bzgen)):
2173 return 1
2174
2175 if opts['update']:
2176 return update(ui, repo)
2177 else:
2178 ui.status(_("(run 'hg update' to get a working copy)\n"))
2116
2179
2117 def undo(ui, repo):
2180 def undo(ui, repo):
2118 """undo the last commit or pull
2181 """undo the last commit or pull
@@ -2188,12 +2251,12 b' table = {'
2188 (add,
2251 (add,
2189 [('I', 'include', [], _('include names matching the given patterns')),
2252 [('I', 'include', [], _('include names matching the given patterns')),
2190 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2253 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2191 "hg add [OPTION]... [FILE]..."),
2254 _('hg add [OPTION]... [FILE]...')),
2192 "addremove":
2255 "addremove":
2193 (addremove,
2256 (addremove,
2194 [('I', 'include', [], _('include names matching the given patterns')),
2257 [('I', 'include', [], _('include names matching the given patterns')),
2195 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2258 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2196 "hg addremove [OPTION]... [FILE]..."),
2259 _('hg addremove [OPTION]... [FILE]...')),
2197 "^annotate":
2260 "^annotate":
2198 (annotate,
2261 (annotate,
2199 [('r', 'rev', '', _('annotate the specified revision')),
2262 [('r', 'rev', '', _('annotate the specified revision')),
@@ -2213,33 +2276,37 b' table = {'
2213 (cat,
2276 (cat,
2214 [('I', 'include', [], _('include names matching the given patterns')),
2277 [('I', 'include', [], _('include names matching the given patterns')),
2215 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2278 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2216 ('o', 'output', "", _('print output to file with formatted name')),
2279 ('o', 'output', '', _('print output to file with formatted name')),
2217 ('r', 'rev', '', _('print the given revision'))],
2280 ('r', 'rev', '', _('print the given revision'))],
2218 _('hg cat [OPTION]... FILE...')),
2281 _('hg cat [OPTION]... FILE...')),
2219 "^clone":
2282 "^clone":
2220 (clone,
2283 (clone,
2221 [('U', 'noupdate', None, _('do not update the new working directory')),
2284 [('U', 'noupdate', None, _('do not update the new working directory')),
2222 ('e', 'ssh', "", _('specify ssh command to use')),
2285 ('e', 'ssh', '', _('specify ssh command to use')),
2223 ('', 'pull', None, _('use pull protocol to copy metadata')),
2286 ('', 'pull', None, _('use pull protocol to copy metadata')),
2224 ('r', 'rev', [], _('a changeset you would like to have after cloning')),
2287 ('r', 'rev', [],
2225 ('', 'remotecmd', "", _('specify hg command to run on the remote side'))],
2288 _('a changeset you would like to have after cloning')),
2289 ('', 'remotecmd', '',
2290 _('specify hg command to run on the remote side'))],
2226 _('hg clone [OPTION]... SOURCE [DEST]')),
2291 _('hg clone [OPTION]... SOURCE [DEST]')),
2227 "^commit|ci":
2292 "^commit|ci":
2228 (commit,
2293 (commit,
2229 [('A', 'addremove', None, _('run addremove during commit')),
2294 [('A', 'addremove', None, _('run addremove during commit')),
2230 ('I', 'include', [], _('include names matching the given patterns')),
2295 ('I', 'include', [], _('include names matching the given patterns')),
2231 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2296 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2232 ('m', 'message', "", _('use <text> as commit message')),
2297 ('m', 'message', '', _('use <text> as commit message')),
2233 ('l', 'logfile', "", _('read the commit message from <file>')),
2298 ('l', 'logfile', '', _('read the commit message from <file>')),
2234 ('d', 'date', "", _('record datecode as commit date')),
2299 ('d', 'date', '', _('record datecode as commit date')),
2235 ('u', 'user', "", _('record user as commiter'))],
2300 ('u', 'user', '', _('record user as commiter'))],
2236 _('hg commit [OPTION]... [FILE]...')),
2301 _('hg commit [OPTION]... [FILE]...')),
2237 "copy|cp": (copy,
2302 "copy|cp":
2238 [('I', 'include', [], _('include names matching the given patterns')),
2303 (copy,
2239 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2304 [('I', 'include', [], _('include names matching the given patterns')),
2240 ('A', 'after', None, _('record a copy that has already occurred')),
2305 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2241 ('f', 'force', None, _('forcibly copy over an existing managed file'))],
2306 ('A', 'after', None, _('record a copy that has already occurred')),
2242 _('hg copy [OPTION]... [SOURCE]... DEST')),
2307 ('f', 'force', None,
2308 _('forcibly copy over an existing managed file'))],
2309 _('hg copy [OPTION]... [SOURCE]... DEST')),
2243 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
2310 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
2244 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
2311 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
2245 "debugconfig": (debugconfig, [], _('debugconfig')),
2312 "debugconfig": (debugconfig, [], _('debugconfig')),
@@ -2263,15 +2330,15 b' table = {'
2263 _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')),
2330 _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')),
2264 "^export":
2331 "^export":
2265 (export,
2332 (export,
2266 [('o', 'output', "", _('print output to file with formatted name')),
2333 [('o', 'output', '', _('print output to file with formatted name')),
2267 ('a', 'text', None, _('treat all files as text')),
2334 ('a', 'text', None, _('treat all files as text')),
2268 ('', 'switch-parent', None, _('diff against the second parent'))],
2335 ('', 'switch-parent', None, _('diff against the second parent'))],
2269 "hg export [-a] [-o OUTFILE] REV..."),
2336 _('hg export [-a] [-o OUTFILE] REV...')),
2270 "forget":
2337 "forget":
2271 (forget,
2338 (forget,
2272 [('I', 'include', [], _('include names matching the given patterns')),
2339 [('I', 'include', [], _('include names matching the given patterns')),
2273 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2340 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2274 "hg forget [OPTION]... FILE..."),
2341 _('hg forget [OPTION]... FILE...')),
2275 "grep":
2342 "grep":
2276 (grep,
2343 (grep,
2277 [('0', 'print0', None, _('end fields with NUL')),
2344 [('0', 'print0', None, _('end fields with NUL')),
@@ -2279,27 +2346,30 b' table = {'
2279 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2346 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2280 ('', 'all', None, _('print all revisions that match')),
2347 ('', 'all', None, _('print all revisions that match')),
2281 ('i', 'ignore-case', None, _('ignore case when matching')),
2348 ('i', 'ignore-case', None, _('ignore case when matching')),
2282 ('l', 'files-with-matches', None, _('print only filenames and revs that match')),
2349 ('l', 'files-with-matches', None,
2350 _('print only filenames and revs that match')),
2283 ('n', 'line-number', None, _('print matching line numbers')),
2351 ('n', 'line-number', None, _('print matching line numbers')),
2284 ('r', 'rev', [], _('search in given revision range')),
2352 ('r', 'rev', [], _('search in given revision range')),
2285 ('u', 'user', None, _('print user who committed change'))],
2353 ('u', 'user', None, _('print user who committed change'))],
2286 "hg grep [OPTION]... PATTERN [FILE]..."),
2354 _('hg grep [OPTION]... PATTERN [FILE]...')),
2287 "heads":
2355 "heads":
2288 (heads,
2356 (heads,
2289 [('b', 'branches', None, _('find branch info')),
2357 [('b', 'branches', None, _('find branch info')),
2290 ('r', 'rev', "", _('show only heads which are descendants of rev'))],
2358 ('r', 'rev', '', _('show only heads which are descendants of rev'))],
2291 _('hg heads [-b] [-r <rev>]')),
2359 _('hg heads [-b] [-r <rev>]')),
2292 "help": (help_, [], _('hg help [COMMAND]')),
2360 "help": (help_, [], _('hg help [COMMAND]')),
2293 "identify|id": (identify, [], _('hg identify')),
2361 "identify|id": (identify, [], _('hg identify')),
2294 "import|patch":
2362 "import|patch":
2295 (import_,
2363 (import_,
2296 [('p', 'strip', 1, _('directory strip option for patch. This has the same\n') +
2364 [('p', 'strip', 1,
2297 _('meaning as the corresponding patch option')),
2365 _('directory strip option for patch. This has the same\n') +
2298 ('f', 'force', None, _('skip check for outstanding uncommitted changes')),
2366 _('meaning as the corresponding patch option')),
2299 ('b', 'base', "", _('base path'))],
2367 ('f', 'force', None,
2300 "hg import [-f] [-p NUM] [-b BASE] PATCH..."),
2368 _('skip check for outstanding uncommitted changes')),
2369 ('b', 'base', '', _('base path'))],
2370 _('hg import [-f] [-p NUM] [-b BASE] PATCH...')),
2301 "incoming|in": (incoming,
2371 "incoming|in": (incoming,
2302 [('M', 'no-merges', None, _("do not show merges")),
2372 [('M', 'no-merges', None, _('do not show merges')),
2303 ('p', 'patch', None, _('show patch')),
2373 ('p', 'patch', None, _('show patch')),
2304 ('n', 'newest-first', None, _('show newest record first'))],
2374 ('n', 'newest-first', None, _('show newest record first'))],
2305 _('hg incoming [-p] [-n] [-M] [SOURCE]')),
2375 _('hg incoming [-p] [-n] [-M] [SOURCE]')),
@@ -2307,8 +2377,10 b' table = {'
2307 "locate":
2377 "locate":
2308 (locate,
2378 (locate,
2309 [('r', 'rev', '', _('search the repository as it stood at rev')),
2379 [('r', 'rev', '', _('search the repository as it stood at rev')),
2310 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2380 ('0', 'print0', None,
2311 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
2381 _('end filenames with NUL, for use with xargs')),
2382 ('f', 'fullpath', None,
2383 _('print complete paths from the filesystem root')),
2312 ('I', 'include', [], _('include names matching the given patterns')),
2384 ('I', 'include', [], _('include names matching the given patterns')),
2313 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2385 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2314 _('hg locate [OPTION]... [PATTERN]...')),
2386 _('hg locate [OPTION]... [PATTERN]...')),
@@ -2319,13 +2391,13 b' table = {'
2319 ('b', 'branch', None, _('show branches')),
2391 ('b', 'branch', None, _('show branches')),
2320 ('k', 'keyword', [], _('search for a keyword')),
2392 ('k', 'keyword', [], _('search for a keyword')),
2321 ('r', 'rev', [], _('show the specified revision or range')),
2393 ('r', 'rev', [], _('show the specified revision or range')),
2322 ('M', 'no-merges', None, _("do not show merges")),
2394 ('M', 'no-merges', None, _('do not show merges')),
2323 ('m', 'only-merges', None, _("show only merges")),
2395 ('m', 'only-merges', None, _('show only merges')),
2324 ('p', 'patch', None, _('show patch'))],
2396 ('p', 'patch', None, _('show patch'))],
2325 _('hg log [-I] [-X] [-r REV]... [-p] [FILE]')),
2397 _('hg log [-I] [-X] [-r REV]... [-p] [FILE]')),
2326 "manifest": (manifest, [], _('hg manifest [REV]')),
2398 "manifest": (manifest, [], _('hg manifest [REV]')),
2327 "outgoing|out": (outgoing,
2399 "outgoing|out": (outgoing,
2328 [('M', 'no-merges', None, _("do not show merges")),
2400 [('M', 'no-merges', None, _('do not show merges')),
2329 ('p', 'patch', None, _('show patch')),
2401 ('p', 'patch', None, _('show patch')),
2330 ('n', 'newest-first', None, _('show newest record first'))],
2402 ('n', 'newest-first', None, _('show newest record first'))],
2331 _('hg outgoing [-p] [-n] [-M] [DEST]')),
2403 _('hg outgoing [-p] [-n] [-M] [DEST]')),
@@ -2333,85 +2405,95 b' table = {'
2333 "paths": (paths, [], _('hg paths [NAME]')),
2405 "paths": (paths, [], _('hg paths [NAME]')),
2334 "^pull":
2406 "^pull":
2335 (pull,
2407 (pull,
2336 [('u', 'update', None, _('update the working directory to tip after pull')),
2408 [('u', 'update', None,
2337 ('e', 'ssh', "", _('specify ssh command to use')),
2409 _('update the working directory to tip after pull')),
2410 ('e', 'ssh', '', _('specify ssh command to use')),
2338 ('r', 'rev', [], _('a specific revision you would like to pull')),
2411 ('r', 'rev', [], _('a specific revision you would like to pull')),
2339 ('', 'remotecmd', "", _('specify hg command to run on the remote side'))],
2412 ('', 'remotecmd', '',
2413 _('specify hg command to run on the remote side'))],
2340 _('hg pull [-u] [-e FILE] [-r rev] [--remotecmd FILE] [SOURCE]')),
2414 _('hg pull [-u] [-e FILE] [-r rev] [--remotecmd FILE] [SOURCE]')),
2341 "^push":
2415 "^push":
2342 (push,
2416 (push,
2343 [('f', 'force', None, _('force push')),
2417 [('f', 'force', None, _('force push')),
2344 ('e', 'ssh', "", _('specify ssh command to use')),
2418 ('e', 'ssh', '', _('specify ssh command to use')),
2345 ('', 'remotecmd', "", _('specify hg command to run on the remote side'))],
2419 ('', 'remotecmd', '',
2420 _('specify hg command to run on the remote side'))],
2346 _('hg push [-f] [-e FILE] [--remotecmd FILE] [DEST]')),
2421 _('hg push [-f] [-e FILE] [--remotecmd FILE] [DEST]')),
2347 "rawcommit":
2422 "rawcommit":
2348 (rawcommit,
2423 (rawcommit,
2349 [('p', 'parent', [], _('parent')),
2424 [('p', 'parent', [], _('parent')),
2350 ('d', 'date', "", _('date code')),
2425 ('d', 'date', '', _('date code')),
2351 ('u', 'user', "", _('user')),
2426 ('u', 'user', '', _('user')),
2352 ('F', 'files', "", _('file list')),
2427 ('F', 'files', '', _('file list')),
2353 ('m', 'message', "", _('commit message')),
2428 ('m', 'message', '', _('commit message')),
2354 ('l', 'logfile', "", _('commit message file'))],
2429 ('l', 'logfile', '', _('commit message file'))],
2355 _('hg rawcommit [OPTION]... [FILE]...')),
2430 _('hg rawcommit [OPTION]... [FILE]...')),
2356 "recover": (recover, [], _("hg recover")),
2431 "recover": (recover, [], _('hg recover')),
2357 "^remove|rm": (remove,
2432 "^remove|rm":
2358 [('I', 'include', [], _('include names matching the given patterns')),
2433 (remove,
2359 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2434 [('I', 'include', [], _('include names matching the given patterns')),
2360 _("hg remove [OPTION]... FILE...")),
2435 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2361 "rename|mv": (rename,
2436 _('hg remove [OPTION]... FILE...')),
2362 [('I', 'include', [], _('include names matching the given patterns')),
2437 "rename|mv":
2363 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2438 (rename,
2364 ('A', 'after', None, _('record a rename that has already occurred')),
2439 [('I', 'include', [], _('include names matching the given patterns')),
2365 ('f', 'force', None, _('forcibly copy over an existing managed file'))],
2440 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2366 _('hg rename [OPTION]... [SOURCE]... DEST')),
2441 ('A', 'after', None, _('record a rename that has already occurred')),
2442 ('f', 'force', None,
2443 _('forcibly copy over an existing managed file'))],
2444 _('hg rename [OPTION]... [SOURCE]... DEST')),
2367 "^revert":
2445 "^revert":
2368 (revert,
2446 (revert,
2369 [('I', 'include', [], _('include names matching the given patterns')),
2447 [('I', 'include', [], _('include names matching the given patterns')),
2370 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2448 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2371 ("r", "rev", "", _("revision to revert to"))],
2449 ('r', 'rev', '', _('revision to revert to'))],
2372 _("hg revert [-n] [-r REV] [NAME]...")),
2450 _('hg revert [-n] [-r REV] [NAME]...')),
2373 "root": (root, [], _("hg root")),
2451 "root": (root, [], _('hg root')),
2374 "^serve":
2452 "^serve":
2375 (serve,
2453 (serve,
2376 [('A', 'accesslog', '', _('name of access log file to write to')),
2454 [('A', 'accesslog', '', _('name of access log file to write to')),
2377 ('E', 'errorlog', '', _('name of error log file to write to')),
2455 ('E', 'errorlog', '', _('name of error log file to write to')),
2378 ('p', 'port', 0, _('port to use (default: 8000)')),
2456 ('p', 'port', 0, _('port to use (default: 8000)')),
2379 ('a', 'address', '', _('address to use')),
2457 ('a', 'address', '', _('address to use')),
2380 ('n', 'name', "", _('name to show in web pages (default: working dir)')),
2458 ('n', 'name', '',
2459 _('name to show in web pages (default: working dir)')),
2381 ('', 'stdio', None, _('for remote clients')),
2460 ('', 'stdio', None, _('for remote clients')),
2382 ('t', 'templates', "", _('web templates to use')),
2461 ('t', 'templates', '', _('web templates to use')),
2383 ('', 'style', "", _('template style to use')),
2462 ('', 'style', '', _('template style to use')),
2384 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))],
2463 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))],
2385 _("hg serve [OPTION]...")),
2464 _('hg serve [OPTION]...')),
2386 "^status|st":
2465 "^status|st":
2387 (status,
2466 (status,
2388 [('m', 'modified', None, _('show only modified files')),
2467 [('m', 'modified', None, _('show only modified files')),
2389 ('a', 'added', None, _('show only added files')),
2468 ('a', 'added', None, _('show only added files')),
2390 ('r', 'removed', None, _('show only removed files')),
2469 ('r', 'removed', None, _('show only removed files')),
2470 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
2391 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
2471 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
2392 ('n', 'no-status', None, _('hide status prefix')),
2472 ('n', 'no-status', None, _('hide status prefix')),
2393 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2473 ('0', 'print0', None,
2474 _('end filenames with NUL, for use with xargs')),
2394 ('I', 'include', [], _('include names matching the given patterns')),
2475 ('I', 'include', [], _('include names matching the given patterns')),
2395 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2476 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2396 _("hg status [OPTION]... [FILE]...")),
2477 _('hg status [OPTION]... [FILE]...')),
2397 "tag":
2478 "tag":
2398 (tag,
2479 (tag,
2399 [('l', 'local', None, _('make the tag local')),
2480 [('l', 'local', None, _('make the tag local')),
2400 ('m', 'message', "", _('message for tag commit log entry')),
2481 ('m', 'message', '', _('message for tag commit log entry')),
2401 ('d', 'date', "", _('record datecode as commit date')),
2482 ('d', 'date', '', _('record datecode as commit date')),
2402 ('u', 'user', "", _('record user as commiter')),
2483 ('u', 'user', '', _('record user as commiter')),
2403 ('r', 'rev', "", _('revision to tag'))],
2484 ('r', 'rev', '', _('revision to tag'))],
2404 _('hg tag [OPTION]... NAME [REV]')),
2485 _('hg tag [-r REV] [OPTION]... NAME')),
2405 "tags": (tags, [], _('hg tags')),
2486 "tags": (tags, [], _('hg tags')),
2406 "tip": (tip, [], _('hg tip')),
2487 "tip": (tip, [], _('hg tip')),
2407 "unbundle":
2488 "unbundle":
2408 (unbundle,
2489 (unbundle,
2409 [],
2490 [('u', 'update', None,
2410 _('hg unbundle FILE')),
2491 _('update the working directory to tip after unbundle'))],
2492 _('hg unbundle [-u] FILE')),
2411 "undo": (undo, [], _('hg undo')),
2493 "undo": (undo, [], _('hg undo')),
2412 "^update|up|checkout|co":
2494 "^update|up|checkout|co":
2413 (update,
2495 (update,
2414 [('b', 'branch', "", _('checkout the head of a specific branch')),
2496 [('b', 'branch', '', _('checkout the head of a specific branch')),
2415 ('m', 'merge', None, _('allow merging of branches')),
2497 ('m', 'merge', None, _('allow merging of branches')),
2416 ('C', 'clean', None, _('overwrite locally modified files')),
2498 ('C', 'clean', None, _('overwrite locally modified files')),
2417 ('f', 'force', None, _('force a merge with outstanding changes'))],
2499 ('f', 'force', None, _('force a merge with outstanding changes'))],
@@ -2421,18 +2503,19 b' table = {'
2421 }
2503 }
2422
2504
2423 globalopts = [
2505 globalopts = [
2424 ('R', 'repository', "", _("repository root directory")),
2506 ('R', 'repository', '', _('repository root directory')),
2425 ('', 'cwd', '', _("change working directory")),
2507 ('', 'cwd', '', _('change working directory')),
2426 ('y', 'noninteractive', None, _("do not prompt, assume 'yes' for any required answers")),
2508 ('y', 'noninteractive', None,
2427 ('q', 'quiet', None, _("suppress output")),
2509 _('do not prompt, assume \'yes\' for any required answers')),
2428 ('v', 'verbose', None, _("enable additional output")),
2510 ('q', 'quiet', None, _('suppress output')),
2429 ('', 'debug', None, _("enable debugging output")),
2511 ('v', 'verbose', None, _('enable additional output')),
2430 ('', 'debugger', None, _("start debugger")),
2512 ('', 'debug', None, _('enable debugging output')),
2431 ('', 'traceback', None, _("print traceback on exception")),
2513 ('', 'debugger', None, _('start debugger')),
2432 ('', 'time', None, _("time how long the command takes")),
2514 ('', 'traceback', None, _('print traceback on exception')),
2433 ('', 'profile', None, _("print command execution profile")),
2515 ('', 'time', None, _('time how long the command takes')),
2434 ('', 'version', None, _("output version information and exit")),
2516 ('', 'profile', None, _('print command execution profile')),
2435 ('h', 'help', None, _("display help and exit")),
2517 ('', 'version', None, _('output version information and exit')),
2518 ('h', 'help', None, _('display help and exit')),
2436 ]
2519 ]
2437
2520
2438 norepo = ("clone init version help debugancestor debugconfig debugdata"
2521 norepo = ("clone init version help debugancestor debugconfig debugdata"
@@ -2615,7 +2698,8 b' def dispatch(args):'
2615 path = options["repository"] or ""
2698 path = options["repository"] or ""
2616 repo = hg.repository(ui=u, path=path)
2699 repo = hg.repository(ui=u, path=path)
2617 for x in external:
2700 for x in external:
2618 if hasattr(x, 'reposetup'): x.reposetup(u, repo)
2701 if hasattr(x, 'reposetup'):
2702 x.reposetup(u, repo)
2619 d = lambda: func(u, repo, *args, **cmdoptions)
2703 d = lambda: func(u, repo, *args, **cmdoptions)
2620 else:
2704 else:
2621 d = lambda: func(u, *args, **cmdoptions)
2705 d = lambda: func(u, *args, **cmdoptions)
@@ -68,7 +68,8 b' class dirstate(object):'
68 try:
68 try:
69 syntax = syntaxes[s]
69 syntax = syntaxes[s]
70 except KeyError:
70 except KeyError:
71 self.ui.warn(_("ignoring invalid syntax '%s'\n") % s)
71 self.ui.warn(_(".hgignore: ignoring invalid "
72 "syntax '%s'\n") % s)
72 continue
73 continue
73 pat = syntax + line
74 pat = syntax + line
74 for s in syntaxes.values():
75 for s in syntaxes.values():
@@ -88,7 +89,8 b' class dirstate(object):'
88 ignore = self.hgignore()
89 ignore = self.hgignore()
89 if ignore:
90 if ignore:
90 files, self.ignorefunc, anypats = util.matcher(self.root,
91 files, self.ignorefunc, anypats = util.matcher(self.root,
91 inc=ignore)
92 inc=ignore,
93 src='.hgignore')
92 else:
94 else:
93 self.ignorefunc = util.never
95 self.ignorefunc = util.never
94 return self.ignorefunc(fn)
96 return self.ignorefunc(fn)
@@ -415,4 +417,4 b' class dirstate(object):'
415 elif type == 'r':
417 elif type == 'r':
416 removed.append(fn)
418 removed.append(fn)
417
419
418 return (lookup, modified, added, removed + deleted, unknown)
420 return (lookup, modified, added, removed, deleted, unknown)
@@ -58,7 +58,7 b' class filelog(revlog):'
58 return self.addrevision(text, transaction, link, p1, p2)
58 return self.addrevision(text, transaction, link, p1, p2)
59
59
60 def renamed(self, node):
60 def renamed(self, node):
61 if 0 and self.parents(node)[0] != nullid: # XXX
61 if self.parents(node)[0] != nullid:
62 return False
62 return False
63 m = self.readmeta(node)
63 m = self.readmeta(node)
64 if m and m.has_key("copy"):
64 if m and m.has_key("copy"):
@@ -6,7 +6,7 b''
6 # This software may be used and distributed according to the terms
6 # This software may be used and distributed according to the terms
7 # of the GNU General Public License, incorporated herein by reference.
7 # of the GNU General Public License, incorporated herein by reference.
8
8
9 import os, cgi, sys
9 import os, cgi, sys, urllib
10 from demandload import demandload
10 from demandload import demandload
11 demandload(globals(), "mdiff time re socket zlib errno ui hg ConfigParser")
11 demandload(globals(), "mdiff time re socket zlib errno ui hg ConfigParser")
12 demandload(globals(), "zipfile tempfile StringIO tarfile BaseHTTPServer util")
12 demandload(globals(), "zipfile tempfile StringIO tarfile BaseHTTPServer util")
@@ -163,7 +163,8 b' class templater(object):'
163 return
163 return
164
164
165 common_filters = {
165 common_filters = {
166 "escape": cgi.escape,
166 "escape": lambda x: cgi.escape(x, True),
167 "urlescape": urllib.quote,
167 "strip": lambda x: x.strip(),
168 "strip": lambda x: x.strip(),
168 "age": age,
169 "age": age,
169 "date": lambda x: util.datestr(x),
170 "date": lambda x: util.datestr(x),
@@ -212,27 +213,33 b' class hgweb(object):'
212 if len(files) > self.maxfiles:
213 if len(files) > self.maxfiles:
213 yield self.t("fileellipses")
214 yield self.t("fileellipses")
214
215
215 def parents(self, node, parents=[], rev=None, hide=False, **args):
216 def siblings(self, siblings=[], rev=None, hiderev=None, **args):
216 if not rev:
217 if not rev:
217 rev = lambda x: ""
218 rev = lambda x: ""
218 parents = [p for p in parents if p != nullid]
219 siblings = [s for s in siblings if s != nullid]
219 if hide and len(parents) == 1 and rev(parents[0]) == rev(node) - 1:
220 if len(siblings) == 1 and rev(siblings[0]) == hiderev:
220 return
221 return
221 for p in parents:
222 for s in siblings:
222 yield dict(node=hex(p), rev=rev(p), **args)
223 yield dict(node=hex(s), rev=rev(s), **args)
224
225 def renamelink(self, fl, node):
226 r = fl.renamed(node)
227 if r:
228 return [dict(file=r[0], node=hex(r[1]))]
229 return []
223
230
224 def showtag(self, t1, node=nullid, **args):
231 def showtag(self, t1, node=nullid, **args):
225 for t in self.repo.nodetags(node):
232 for t in self.repo.nodetags(node):
226 yield self.t(t1, tag=t, **args)
233 yield self.t(t1, tag=t, **args)
227
234
228 def diff(self, node1, node2, files):
235 def diff(self, node1, node2, files):
229 def filterfiles(list, files):
236 def filterfiles(filters, files):
230 l = [x for x in list if x in files]
237 l = [x for x in files if x in filters]
231
238
232 for f in files:
239 for t in filters:
233 if f[-1] != os.sep:
240 if t and t[-1] != os.sep:
234 f += os.sep
241 t += os.sep
235 l += [x for x in list if x.startswith(f)]
242 l += [x for x in files if x.startswith(t)]
236 return l
243 return l
237
244
238 parity = [0]
245 parity = [0]
@@ -265,22 +272,29 b' class hgweb(object):'
265 date1 = util.datestr(change1[2])
272 date1 = util.datestr(change1[2])
266 date2 = util.datestr(change2[2])
273 date2 = util.datestr(change2[2])
267
274
268 c, a, d, u = r.changes(node1, node2)
275 modified, added, removed, deleted, unknown = r.changes(node1, node2)
269 if files:
276 if files:
270 c, a, d = map(lambda x: filterfiles(x, files), (c, a, d))
277 modified, added, removed = map(lambda x: filterfiles(files, x),
278 (modified, added, removed))
271
279
272 for f in c:
280 diffopts = self.repo.ui.diffopts()
281 showfunc = diffopts['showfunc']
282 ignorews = diffopts['ignorews']
283 for f in modified:
273 to = r.file(f).read(mmap1[f])
284 to = r.file(f).read(mmap1[f])
274 tn = r.file(f).read(mmap2[f])
285 tn = r.file(f).read(mmap2[f])
275 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f), f, tn)
286 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f,
276 for f in a:
287 showfunc=showfunc, ignorews=ignorews), f, tn)
288 for f in added:
277 to = None
289 to = None
278 tn = r.file(f).read(mmap2[f])
290 tn = r.file(f).read(mmap2[f])
279 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f), f, tn)
291 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f,
280 for f in d:
292 showfunc=showfunc, ignorews=ignorews), f, tn)
293 for f in removed:
281 to = r.file(f).read(mmap1[f])
294 to = r.file(f).read(mmap1[f])
282 tn = None
295 tn = None
283 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f), f, tn)
296 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f,
297 showfunc=showfunc, ignorews=ignorews), f, tn)
284
298
285 def changelog(self, pos):
299 def changelog(self, pos):
286 def changenav(**map):
300 def changenav(**map):
@@ -321,8 +335,10 b' class hgweb(object):'
321
335
322 l.insert(0, {"parity": parity,
336 l.insert(0, {"parity": parity,
323 "author": changes[1],
337 "author": changes[1],
324 "parent": self.parents(n, cl.parents(n), cl.rev,
338 "parent": self.siblings(cl.parents(n), cl.rev,
325 hide=True),
339 cl.rev(n) - 1),
340 "child": self.siblings(cl.children(n), cl.rev,
341 cl.rev(n) + 1),
326 "changelogtag": self.showtag("changelogtag",n),
342 "changelogtag": self.showtag("changelogtag",n),
327 "manifest": hex(changes[0]),
343 "manifest": hex(changes[0]),
328 "desc": changes[4],
344 "desc": changes[4],
@@ -382,7 +398,8 b' class hgweb(object):'
382 yield self.t('searchentry',
398 yield self.t('searchentry',
383 parity=count & 1,
399 parity=count & 1,
384 author=changes[1],
400 author=changes[1],
385 parent=self.parents(n, cl.parents(n), cl.rev),
401 parent=self.siblings(cl.parents(n), cl.rev),
402 child=self.siblings(cl.children(n), cl.rev),
386 changelogtag=self.showtag("changelogtag",n),
403 changelogtag=self.showtag("changelogtag",n),
387 manifest=hex(changes[0]),
404 manifest=hex(changes[0]),
388 desc=changes[4],
405 desc=changes[4],
@@ -422,7 +439,8 b' class hgweb(object):'
422 diff=diff,
439 diff=diff,
423 rev=cl.rev(n),
440 rev=cl.rev(n),
424 node=nodeid,
441 node=nodeid,
425 parent=self.parents(n, cl.parents(n), cl.rev),
442 parent=self.siblings(cl.parents(n), cl.rev),
443 child=self.siblings(cl.children(n), cl.rev),
426 changesettag=self.showtag("changesettag",n),
444 changesettag=self.showtag("changesettag",n),
427 manifest=hex(changes[0]),
445 manifest=hex(changes[0]),
428 author=changes[1],
446 author=changes[1],
@@ -454,7 +472,10 b' class hgweb(object):'
454 "node": hex(cn),
472 "node": hex(cn),
455 "author": cs[1],
473 "author": cs[1],
456 "date": cs[2],
474 "date": cs[2],
457 "parent": self.parents(n, fl.parents(n),
475 "rename": self.renamelink(fl, n),
476 "parent": self.siblings(fl.parents(n),
477 fl.rev, file=f),
478 "child": self.siblings(fl.children(n),
458 fl.rev, file=f),
479 fl.rev, file=f),
459 "desc": cs[4]})
480 "desc": cs[4]})
460 parity = 1 - parity
481 parity = 1 - parity
@@ -498,7 +519,9 b' class hgweb(object):'
498 manifest=hex(mfn),
519 manifest=hex(mfn),
499 author=cs[1],
520 author=cs[1],
500 date=cs[2],
521 date=cs[2],
501 parent=self.parents(n, fl.parents(n), fl.rev, file=f),
522 parent=self.siblings(fl.parents(n), fl.rev, file=f),
523 child=self.siblings(fl.children(n), fl.rev, file=f),
524 rename=self.renamelink(fl, n),
502 permissions=self.repo.manifest.readflags(mfn)[f])
525 permissions=self.repo.manifest.readflags(mfn)[f])
503
526
504 def fileannotate(self, f, node):
527 def fileannotate(self, f, node):
@@ -550,7 +573,9 b' class hgweb(object):'
550 manifest=hex(mfn),
573 manifest=hex(mfn),
551 author=cs[1],
574 author=cs[1],
552 date=cs[2],
575 date=cs[2],
553 parent=self.parents(n, fl.parents(n), fl.rev, file=f),
576 rename=self.renamelink(fl, n),
577 parent=self.siblings(fl.parents(n), fl.rev, file=f),
578 child=self.siblings(fl.children(n), fl.rev, file=f),
554 permissions=self.repo.manifest.readflags(mfn)[f])
579 permissions=self.repo.manifest.readflags(mfn)[f])
555
580
556 def manifest(self, mnode, path):
581 def manifest(self, mnode, path):
@@ -565,6 +590,8 b' class hgweb(object):'
565 files = {}
590 files = {}
566
591
567 p = path[1:]
592 p = path[1:]
593 if p and p[-1] != "/":
594 p += "/"
568 l = len(p)
595 l = len(p)
569
596
570 for f,n in mf.items():
597 for f,n in mf.items():
@@ -727,7 +754,8 b' class hgweb(object):'
727 filenode=hex(mf.get(file, nullid)),
754 filenode=hex(mf.get(file, nullid)),
728 node=changeset,
755 node=changeset,
729 rev=self.repo.changelog.rev(n),
756 rev=self.repo.changelog.rev(n),
730 parent=self.parents(n, cl.parents(n), cl.rev),
757 parent=self.siblings(cl.parents(n), cl.rev),
758 child=self.siblings(cl.children(n), cl.rev),
731 diff=diff)
759 diff=diff)
732
760
733 def archive(self, req, cnode, type):
761 def archive(self, req, cnode, type):
@@ -785,6 +813,12 b' class hgweb(object):'
785 # find tag, changeset, file
813 # find tag, changeset, file
786
814
787 def run(self, req=hgrequest()):
815 def run(self, req=hgrequest()):
816 def clean(path):
817 p = os.path.normpath(path)
818 if p[:2] == "..":
819 raise "suspicious path"
820 return p
821
788 def header(**map):
822 def header(**map):
789 yield self.t("header", **map)
823 yield self.t("header", **map)
790
824
@@ -865,7 +899,8 b' class hgweb(object):'
865 req.write(self.changeset(req.form['node'][0]))
899 req.write(self.changeset(req.form['node'][0]))
866
900
867 elif req.form['cmd'][0] == 'manifest':
901 elif req.form['cmd'][0] == 'manifest':
868 req.write(self.manifest(req.form['manifest'][0], req.form['path'][0]))
902 req.write(self.manifest(req.form['manifest'][0],
903 clean(req.form['path'][0])))
869
904
870 elif req.form['cmd'][0] == 'tags':
905 elif req.form['cmd'][0] == 'tags':
871 req.write(self.tags())
906 req.write(self.tags())
@@ -874,16 +909,20 b' class hgweb(object):'
874 req.write(self.summary())
909 req.write(self.summary())
875
910
876 elif req.form['cmd'][0] == 'filediff':
911 elif req.form['cmd'][0] == 'filediff':
877 req.write(self.filediff(req.form['file'][0], req.form['node'][0]))
912 req.write(self.filediff(clean(req.form['file'][0]),
913 req.form['node'][0]))
878
914
879 elif req.form['cmd'][0] == 'file':
915 elif req.form['cmd'][0] == 'file':
880 req.write(self.filerevision(req.form['file'][0], req.form['filenode'][0]))
916 req.write(self.filerevision(clean(req.form['file'][0]),
917 req.form['filenode'][0]))
881
918
882 elif req.form['cmd'][0] == 'annotate':
919 elif req.form['cmd'][0] == 'annotate':
883 req.write(self.fileannotate(req.form['file'][0], req.form['filenode'][0]))
920 req.write(self.fileannotate(clean(req.form['file'][0]),
921 req.form['filenode'][0]))
884
922
885 elif req.form['cmd'][0] == 'filelog':
923 elif req.form['cmd'][0] == 'filelog':
886 req.write(self.filelog(req.form['file'][0], req.form['filenode'][0]))
924 req.write(self.filelog(clean(req.form['file'][0]),
925 req.form['filenode'][0]))
887
926
888 elif req.form['cmd'][0] == 'heads':
927 elif req.form['cmd'][0] == 'heads':
889 req.httphdr("application/mercurial-0.1")
928 req.httphdr("application/mercurial-0.1")
@@ -19,7 +19,8 b' class localrepository(object):'
19 while not os.path.isdir(os.path.join(p, ".hg")):
19 while not os.path.isdir(os.path.join(p, ".hg")):
20 oldp = p
20 oldp = p
21 p = os.path.dirname(p)
21 p = os.path.dirname(p)
22 if p == oldp: raise repo.RepoError(_("no repo found"))
22 if p == oldp:
23 raise repo.RepoError(_("no repo found"))
23 path = p
24 path = p
24 self.path = os.path.join(path, ".hg")
25 self.path = os.path.join(path, ".hg")
25
26
@@ -44,7 +45,8 b' class localrepository(object):'
44 self.dirstate = dirstate.dirstate(self.opener, ui, self.root)
45 self.dirstate = dirstate.dirstate(self.opener, ui, self.root)
45 try:
46 try:
46 self.ui.readconfig(self.join("hgrc"))
47 self.ui.readconfig(self.join("hgrc"))
47 except IOError: pass
48 except IOError:
49 pass
48
50
49 def hook(self, name, **args):
51 def hook(self, name, **args):
50 def runhook(name, cmd):
52 def runhook(name, cmd):
@@ -126,16 +128,16 b' class localrepository(object):'
126 r = self.changelog.rev(n)
128 r = self.changelog.rev(n)
127 except:
129 except:
128 r = -2 # sort to the beginning of the list if unknown
130 r = -2 # sort to the beginning of the list if unknown
129 l.append((r,t,n))
131 l.append((r, t, n))
130 l.sort()
132 l.sort()
131 return [(t,n) for r,t,n in l]
133 return [(t, n) for r, t, n in l]
132
134
133 def nodetags(self, node):
135 def nodetags(self, node):
134 '''return the tags associated with a node'''
136 '''return the tags associated with a node'''
135 if not self.nodetagscache:
137 if not self.nodetagscache:
136 self.nodetagscache = {}
138 self.nodetagscache = {}
137 for t,n in self.tags().items():
139 for t, n in self.tags().items():
138 self.nodetagscache.setdefault(n,[]).append(t)
140 self.nodetagscache.setdefault(n, []).append(t)
139 return self.nodetagscache.get(node, [])
141 return self.nodetagscache.get(node, [])
140
142
141 def lookup(self, key):
143 def lookup(self, key):
@@ -160,7 +162,8 b' class localrepository(object):'
160 return os.path.join(self.root, f)
162 return os.path.join(self.root, f)
161
163
162 def file(self, f):
164 def file(self, f):
163 if f[0] == '/': f = f[1:]
165 if f[0] == '/':
166 f = f[1:]
164 return filelog.filelog(self.opener, f)
167 return filelog.filelog(self.opener, f)
165
168
166 def getcwd(self):
169 def getcwd(self):
@@ -226,6 +229,8 b' class localrepository(object):'
226 if os.path.exists(self.join("journal")):
229 if os.path.exists(self.join("journal")):
227 self.ui.status(_("rolling back interrupted transaction\n"))
230 self.ui.status(_("rolling back interrupted transaction\n"))
228 transaction.rollback(self.opener, self.join("journal"))
231 transaction.rollback(self.opener, self.join("journal"))
232 self.manifest = manifest.manifest(self.opener)
233 self.changelog = changelog.changelog(self.opener)
229 return True
234 return True
230 else:
235 else:
231 self.ui.warn(_("no interrupted transaction available\n"))
236 self.ui.warn(_("no interrupted transaction available\n"))
@@ -334,8 +339,8 b' class localrepository(object):'
334 if update_dirstate:
339 if update_dirstate:
335 self.dirstate.setparents(n, nullid)
340 self.dirstate.setparents(n, nullid)
336
341
337 def commit(self, files = None, text = "", user = None, date = None,
342 def commit(self, files=None, text="", user=None, date=None,
338 match = util.always, force=False):
343 match=util.always, force=False):
339 commit = []
344 commit = []
340 remove = []
345 remove = []
341 changed = []
346 changed = []
@@ -350,9 +355,9 b' class localrepository(object):'
350 else:
355 else:
351 self.ui.warn(_("%s not tracked!\n") % f)
356 self.ui.warn(_("%s not tracked!\n") % f)
352 else:
357 else:
353 (c, a, d, u) = self.changes(match=match)
358 modified, added, removed, deleted, unknown = self.changes(match=match)
354 commit = c + a
359 commit = modified + added
355 remove = d
360 remove = removed
356
361
357 p1, p2 = self.dirstate.parents()
362 p1, p2 = self.dirstate.parents()
358 c1 = self.changelog.read(p1)
363 c1 = self.changelog.read(p1)
@@ -398,10 +403,6 b' class localrepository(object):'
398 fp1 = m1.get(f, nullid)
403 fp1 = m1.get(f, nullid)
399 fp2 = m2.get(f, nullid)
404 fp2 = m2.get(f, nullid)
400
405
401 # is the same revision on two branches of a merge?
402 if fp2 == fp1:
403 fp2 = nullid
404
405 if fp2 != nullid:
406 if fp2 != nullid:
406 # is one parent an ancestor of the other?
407 # is one parent an ancestor of the other?
407 fpa = r.ancestor(fp1, fp2)
408 fpa = r.ancestor(fp1, fp2)
@@ -411,7 +412,7 b' class localrepository(object):'
411 fp2 = nullid
412 fp2 = nullid
412
413
413 # is the file unmodified from the parent?
414 # is the file unmodified from the parent?
414 if not meta and t == r.read(fp1):
415 if not meta and t == r.read(fp1) and fp2 == nullid:
415 # record the proper existing parent in manifest
416 # record the proper existing parent in manifest
416 # no need to add a revision
417 # no need to add a revision
417 new[f] = fp1
418 new[f] = fp1
@@ -423,6 +424,7 b' class localrepository(object):'
423 changed.append(f)
424 changed.append(f)
424
425
425 # update manifest
426 # update manifest
427 m1 = m1.copy()
426 m1.update(new)
428 m1.update(new)
427 for f in remove:
429 for f in remove:
428 if f in m1:
430 if f in m1:
@@ -449,7 +451,7 b' class localrepository(object):'
449 text = edittext
451 text = edittext
450
452
451 user = user or self.ui.username()
453 user = user or self.ui.username()
452 n = self.changelog.add(mn, changed, text, tr, p1, p2, user, date)
454 n = self.changelog.add(mn, changed + remove, text, tr, p1, p2, user, date)
453 tr.close()
455 tr.close()
454
456
455 self.dirstate.setparents(n)
457 self.dirstate.setparents(n)
@@ -474,9 +476,12 b' class localrepository(object):'
474 for src, fn in self.dirstate.walk(files, match):
476 for src, fn in self.dirstate.walk(files, match):
475 yield src, fn
477 yield src, fn
476
478
477 def changes(self, node1 = None, node2 = None, files = [],
479 def changes(self, node1=None, node2=None, files=[], match=util.always):
478 match = util.always):
480 """return changes between two nodes or node and working directory
479 mf2, u = None, []
481
482 If node1 is None, use the first dirstate parent instead.
483 If node2 is None, compare node1 with working directory.
484 """
480
485
481 def fcmp(fn, mf):
486 def fcmp(fn, mf):
482 t1 = self.wread(fn)
487 t1 = self.wread(fn)
@@ -484,7 +489,8 b' class localrepository(object):'
484 return cmp(t1, t2)
489 return cmp(t1, t2)
485
490
486 def mfmatches(node):
491 def mfmatches(node):
487 mf = dict(self.manifest.read(node))
492 change = self.changelog.read(node)
493 mf = dict(self.manifest.read(change[0]))
488 for fn in mf.keys():
494 for fn in mf.keys():
489 if not match(fn):
495 if not match(fn):
490 del mf[fn]
496 del mf[fn]
@@ -496,60 +502,53 b' class localrepository(object):'
496 wlock = self.wlock(wait=0)
502 wlock = self.wlock(wait=0)
497 except lock.LockHeld:
503 except lock.LockHeld:
498 wlock = None
504 wlock = None
499 l, c, a, d, u = self.dirstate.changes(files, match)
505 lookup, modified, added, removed, deleted, unknown = (
506 self.dirstate.changes(files, match))
500
507
501 # are we comparing working dir against its parent?
508 # are we comparing working dir against its parent?
502 if not node1:
509 if not node1:
503 if l:
510 if lookup:
504 # do a full compare of any files that might have changed
511 # do a full compare of any files that might have changed
505 change = self.changelog.read(self.dirstate.parents()[0])
512 mf2 = mfmatches(self.dirstate.parents()[0])
506 mf2 = mfmatches(change[0])
513 for f in lookup:
507 for f in l:
508 if fcmp(f, mf2):
514 if fcmp(f, mf2):
509 c.append(f)
515 modified.append(f)
510 elif wlock is not None:
516 elif wlock is not None:
511 self.dirstate.update([f], "n")
517 self.dirstate.update([f], "n")
512
518 else:
513 for l in c, a, d, u:
519 # we are comparing working dir against non-parent
514 l.sort()
520 # generate a pseudo-manifest for the working dir
515
521 mf2 = mfmatches(self.dirstate.parents()[0])
516 return (c, a, d, u)
522 for f in lookup + modified + added:
517
523 mf2[f] = ""
518 # are we comparing working dir against non-tip?
524 for f in removed:
519 # generate a pseudo-manifest for the working dir
525 if f in mf2:
520 if not node2:
526 del mf2[f]
521 if not mf2:
522 change = self.changelog.read(self.dirstate.parents()[0])
523 mf2 = mfmatches(change[0])
524 for f in a + c + l:
525 mf2[f] = ""
526 for f in d:
527 if f in mf2: del mf2[f]
528 else:
527 else:
529 change = self.changelog.read(node2)
528 # we are comparing two revisions
530 mf2 = mfmatches(change[0])
529 deleted, unknown = [], []
530 mf2 = mfmatches(node2)
531
531
532 # flush lists from dirstate before comparing manifests
532 if node1:
533 c, a = [], []
533 # flush lists from dirstate before comparing manifests
534 modified, added = [], []
534
535
535 change = self.changelog.read(node1)
536 mf1 = mfmatches(node1)
536 mf1 = mfmatches(change[0])
537
537
538 for fn in mf2:
538 for fn in mf2:
539 if mf1.has_key(fn):
539 if mf1.has_key(fn):
540 if mf1[fn] != mf2[fn]:
540 if mf1[fn] != mf2[fn] and (mf2[fn] != "" or fcmp(fn, mf1)):
541 if mf2[fn] != "" or fcmp(fn, mf1):
541 modified.append(fn)
542 c.append(fn)
542 del mf1[fn]
543 del mf1[fn]
543 else:
544 else:
544 added.append(fn)
545 a.append(fn)
546
545
547 d = mf1.keys()
546 removed = mf1.keys()
548
547
549 for l in c, a, d, u:
548 # sort and return results:
549 for l in modified, added, removed, deleted, unknown:
550 l.sort()
550 l.sort()
551
551 return (modified, added, removed, deleted, unknown)
552 return (c, a, d, u)
553
552
554 def add(self, list):
553 def add(self, list):
555 wlock = self.wlock()
554 wlock = self.wlock()
@@ -558,7 +557,8 b' class localrepository(object):'
558 if not os.path.exists(p):
557 if not os.path.exists(p):
559 self.ui.warn(_("%s does not exist!\n") % f)
558 self.ui.warn(_("%s does not exist!\n") % f)
560 elif not os.path.isfile(p):
559 elif not os.path.isfile(p):
561 self.ui.warn(_("%s not added: only files supported currently\n") % f)
560 self.ui.warn(_("%s not added: only files supported currently\n")
561 % f)
562 elif self.dirstate.state(f) in 'an':
562 elif self.dirstate.state(f) in 'an':
563 self.ui.warn(_("%s already tracked!\n") % f)
563 self.ui.warn(_("%s already tracked!\n") % f)
564 else:
564 else:
@@ -578,7 +578,8 b' class localrepository(object):'
578 try:
578 try:
579 util.unlink(self.wjoin(f))
579 util.unlink(self.wjoin(f))
580 except OSError, inst:
580 except OSError, inst:
581 if inst.errno != errno.ENOENT: raise
581 if inst.errno != errno.ENOENT:
582 raise
582 wlock = self.wlock()
583 wlock = self.wlock()
583 for f in list:
584 for f in list:
584 p = self.wjoin(f)
585 p = self.wjoin(f)
@@ -733,7 +734,8 b' class localrepository(object):'
733 return out
734 return out
734
735
735 def branches(self, nodes):
736 def branches(self, nodes):
736 if not nodes: nodes = [self.changelog.tip()]
737 if not nodes:
738 nodes = [self.changelog.tip()]
737 b = []
739 b = []
738 for n in nodes:
740 for n in nodes:
739 t = n
741 t = n
@@ -805,7 +807,8 b' class localrepository(object):'
805 if n[0] in seen:
807 if n[0] in seen:
806 continue
808 continue
807
809
808 self.ui.debug(_("examining %s:%s\n") % (short(n[0]), short(n[1])))
810 self.ui.debug(_("examining %s:%s\n")
811 % (short(n[0]), short(n[1])))
809 if n[0] == nullid:
812 if n[0] == nullid:
810 break
813 break
811 if n in seenbranch:
814 if n in seenbranch:
@@ -841,7 +844,8 b' class localrepository(object):'
841 self.ui.debug(_("received %s:%s\n") %
844 self.ui.debug(_("received %s:%s\n") %
842 (short(b[0]), short(b[1])))
845 (short(b[0]), short(b[1])))
843 if b[0] in m:
846 if b[0] in m:
844 self.ui.debug(_("found base node %s\n") % short(b[0]))
847 self.ui.debug(_("found base node %s\n")
848 % short(b[0]))
845 base[b[0]] = 1
849 base[b[0]] = 1
846 elif b[0] not in seen:
850 elif b[0] not in seen:
847 unknown.append(b)
851 unknown.append(b)
@@ -914,7 +918,7 b' class localrepository(object):'
914 # this is the set of all roots we have to push
918 # this is the set of all roots we have to push
915 return subset
919 return subset
916
920
917 def pull(self, remote, heads = None):
921 def pull(self, remote, heads=None):
918 lock = self.lock()
922 lock = self.lock()
919
923
920 # if we have an empty repo, fetch everything
924 # if we have an empty repo, fetch everything
@@ -1199,8 +1203,11 b' class localrepository(object):'
1199 filerevlog = self.file(fname)
1203 filerevlog = self.file(fname)
1200 # Toss out the filenodes that the recipient isn't really
1204 # Toss out the filenodes that the recipient isn't really
1201 # missing.
1205 # missing.
1202 prune_filenodes(fname, filerevlog)
1206 if msng_filenode_set.has_key(fname):
1203 msng_filenode_lst = msng_filenode_set[fname].keys()
1207 prune_filenodes(fname, filerevlog)
1208 msng_filenode_lst = msng_filenode_set[fname].keys()
1209 else:
1210 msng_filenode_lst = []
1204 # If any filenodes are left, generate the group for them,
1211 # If any filenodes are left, generate the group for them,
1205 # otherwise don't bother.
1212 # otherwise don't bother.
1206 if len(msng_filenode_lst) > 0:
1213 if len(msng_filenode_lst) > 0:
@@ -1214,8 +1221,9 b' class localrepository(object):'
1214 lookup_filenode_link_func(fname))
1221 lookup_filenode_link_func(fname))
1215 for chnk in group:
1222 for chnk in group:
1216 yield chnk
1223 yield chnk
1217 # Don't need this anymore, toss it to free memory.
1224 if msng_filenode_set.has_key(fname):
1218 del msng_filenode_set[fname]
1225 # Don't need this anymore, toss it to free memory.
1226 del msng_filenode_set[fname]
1219 # Signal that no more groups are left.
1227 # Signal that no more groups are left.
1220 yield struct.pack(">l", 0)
1228 yield struct.pack(">l", 0)
1221
1229
@@ -1285,9 +1293,11 b' class localrepository(object):'
1285
1293
1286 def getchunk():
1294 def getchunk():
1287 d = source.read(4)
1295 d = source.read(4)
1288 if not d: return ""
1296 if not d:
1297 return ""
1289 l = struct.unpack(">l", d)[0]
1298 l = struct.unpack(">l", d)[0]
1290 if l <= 4: return ""
1299 if l <= 4:
1300 return ""
1291 d = source.read(l - 4)
1301 d = source.read(l - 4)
1292 if len(d) < l - 4:
1302 if len(d) < l - 4:
1293 raise repo.RepoError(_("premature EOF reading chunk"
1303 raise repo.RepoError(_("premature EOF reading chunk"
@@ -1298,7 +1308,8 b' class localrepository(object):'
1298 def getgroup():
1308 def getgroup():
1299 while 1:
1309 while 1:
1300 c = getchunk()
1310 c = getchunk()
1301 if not c: break
1311 if not c:
1312 break
1302 yield c
1313 yield c
1303
1314
1304 def csmap(x):
1315 def csmap(x):
@@ -1308,7 +1319,8 b' class localrepository(object):'
1308 def revmap(x):
1319 def revmap(x):
1309 return self.changelog.rev(x)
1320 return self.changelog.rev(x)
1310
1321
1311 if not source: return
1322 if not source:
1323 return
1312 changesets = files = revisions = 0
1324 changesets = files = revisions = 0
1313
1325
1314 tr = self.transaction()
1326 tr = self.transaction()
@@ -1333,7 +1345,8 b' class localrepository(object):'
1333 self.ui.status(_("adding file changes\n"))
1345 self.ui.status(_("adding file changes\n"))
1334 while 1:
1346 while 1:
1335 f = getchunk()
1347 f = getchunk()
1336 if not f: break
1348 if not f:
1349 break
1337 self.ui.debug(_("adding %s revisions\n") % f)
1350 self.ui.debug(_("adding %s revisions\n") % f)
1338 fl = self.file(f)
1351 fl = self.file(f)
1339 o = fl.count()
1352 o = fl.count()
@@ -1354,7 +1367,7 b' class localrepository(object):'
1354
1367
1355 if changesets > 0:
1368 if changesets > 0:
1356 if not self.hook("changegroup",
1369 if not self.hook("changegroup",
1357 node=hex(self.changelog.node(cor+1))):
1370 node=hex(self.changelog.node(cor+1))):
1358 self.ui.warn(_("abort: changegroup hook returned failure!\n"))
1371 self.ui.warn(_("abort: changegroup hook returned failure!\n"))
1359 return 1
1372 return 1
1360
1373
@@ -1370,6 +1383,8 b' class localrepository(object):'
1370 self.ui.warn(_("aborting: outstanding uncommitted merges\n"))
1383 self.ui.warn(_("aborting: outstanding uncommitted merges\n"))
1371 return 1
1384 return 1
1372
1385
1386 err = False
1387
1373 p1, p2 = pl[0], node
1388 p1, p2 = pl[0], node
1374 pa = self.changelog.ancestor(p1, p2)
1389 pa = self.changelog.ancestor(p1, p2)
1375 m1n = self.changelog.read(p1)[0]
1390 m1n = self.changelog.read(p1)[0]
@@ -1377,29 +1392,32 b' class localrepository(object):'
1377 man = self.manifest.ancestor(m1n, m2n)
1392 man = self.manifest.ancestor(m1n, m2n)
1378 m1 = self.manifest.read(m1n)
1393 m1 = self.manifest.read(m1n)
1379 mf1 = self.manifest.readflags(m1n)
1394 mf1 = self.manifest.readflags(m1n)
1380 m2 = self.manifest.read(m2n)
1395 m2 = self.manifest.read(m2n).copy()
1381 mf2 = self.manifest.readflags(m2n)
1396 mf2 = self.manifest.readflags(m2n)
1382 ma = self.manifest.read(man)
1397 ma = self.manifest.read(man)
1383 mfa = self.manifest.readflags(man)
1398 mfa = self.manifest.readflags(man)
1384
1399
1385 (c, a, d, u) = self.changes()
1400 modified, added, removed, deleted, unknown = self.changes()
1386
1387 if allow and not forcemerge:
1388 if c or a or d:
1389 raise util.Abort(_("outstanding uncommited changes"))
1390 if not forcemerge and not force:
1391 for f in u:
1392 if f in m2:
1393 t1 = self.wread(f)
1394 t2 = self.file(f).read(m2[f])
1395 if cmp(t1, t2) != 0:
1396 raise util.Abort(_("'%s' already exists in the working"
1397 " dir and differs from remote") % f)
1398
1401
1399 # is this a jump, or a merge? i.e. is there a linear path
1402 # is this a jump, or a merge? i.e. is there a linear path
1400 # from p1 to p2?
1403 # from p1 to p2?
1401 linear_path = (pa == p1 or pa == p2)
1404 linear_path = (pa == p1 or pa == p2)
1402
1405
1406 if allow and linear_path:
1407 raise util.Abort(_("there is nothing to merge, "
1408 "just use 'hg update'"))
1409 if allow and not forcemerge:
1410 if modified or added or removed:
1411 raise util.Abort(_("outstanding uncommited changes"))
1412 if not forcemerge and not force:
1413 for f in unknown:
1414 if f in m2:
1415 t1 = self.wread(f)
1416 t2 = self.file(f).read(m2[f])
1417 if cmp(t1, t2) != 0:
1418 raise util.Abort(_("'%s' already exists in the working"
1419 " dir and differs from remote") % f)
1420
1403 # resolve the manifest to determine which files
1421 # resolve the manifest to determine which files
1404 # we care about merging
1422 # we care about merging
1405 self.ui.note(_("resolving manifests\n"))
1423 self.ui.note(_("resolving manifests\n"))
@@ -1415,17 +1433,18 b' class localrepository(object):'
1415 # construct a working dir manifest
1433 # construct a working dir manifest
1416 mw = m1.copy()
1434 mw = m1.copy()
1417 mfw = mf1.copy()
1435 mfw = mf1.copy()
1418 umap = dict.fromkeys(u)
1436 umap = dict.fromkeys(unknown)
1419
1437
1420 for f in a + c + u:
1438 for f in added + modified + unknown:
1421 mw[f] = ""
1439 mw[f] = ""
1422 mfw[f] = util.is_exec(self.wjoin(f), mfw.get(f, False))
1440 mfw[f] = util.is_exec(self.wjoin(f), mfw.get(f, False))
1423
1441
1424 if moddirstate:
1442 if moddirstate:
1425 wlock = self.wlock()
1443 wlock = self.wlock()
1426
1444
1427 for f in d:
1445 for f in deleted + removed:
1428 if f in mw: del mw[f]
1446 if f in mw:
1447 del mw[f]
1429
1448
1430 # If we're jumping between revisions (as opposed to merging),
1449 # If we're jumping between revisions (as opposed to merging),
1431 # and if neither the working directory nor the target rev has
1450 # and if neither the working directory nor the target rev has
@@ -1437,7 +1456,8 b' class localrepository(object):'
1437
1456
1438 # Compare manifests
1457 # Compare manifests
1439 for f, n in mw.iteritems():
1458 for f, n in mw.iteritems():
1440 if choose and not choose(f): continue
1459 if choose and not choose(f):
1460 continue
1441 if f in m2:
1461 if f in m2:
1442 s = 0
1462 s = 0
1443
1463
@@ -1480,7 +1500,8 b' class localrepository(object):'
1480 a, b, c = mfa.get(f, 0), mfw[f], mf2[f]
1500 a, b, c = mfa.get(f, 0), mfw[f], mf2[f]
1481 mode = ((a^b) | (a^c)) ^ a
1501 mode = ((a^b) | (a^c)) ^ a
1482 if mode != b:
1502 if mode != b:
1483 self.ui.debug(_(" updating permissions for %s\n") % f)
1503 self.ui.debug(_(" updating permissions for %s\n")
1504 % f)
1484 util.set_exec(self.wjoin(f), mode)
1505 util.set_exec(self.wjoin(f), mode)
1485 del m2[f]
1506 del m2[f]
1486 elif f in ma:
1507 elif f in ma:
@@ -1510,15 +1531,18 b' class localrepository(object):'
1510 self.ui.debug(_("working dir created %s, keeping\n") % f)
1531 self.ui.debug(_("working dir created %s, keeping\n") % f)
1511
1532
1512 for f, n in m2.iteritems():
1533 for f, n in m2.iteritems():
1513 if choose and not choose(f): continue
1534 if choose and not choose(f):
1514 if f[0] == "/": continue
1535 continue
1536 if f[0] == "/":
1537 continue
1515 if f in ma and n != ma[f]:
1538 if f in ma and n != ma[f]:
1516 r = _("k")
1539 r = _("k")
1517 if not force and (linear_path or allow):
1540 if not force and (linear_path or allow):
1518 r = self.ui.prompt(
1541 r = self.ui.prompt(
1519 (_("remote changed %s which local deleted\n") % f) +
1542 (_("remote changed %s which local deleted\n") % f) +
1520 _("(k)eep or (d)elete?"), _("[kd]"), _("k"))
1543 _("(k)eep or (d)elete?"), _("[kd]"), _("k"))
1521 if r == _("k"): get[f] = n
1544 if r == _("k"):
1545 get[f] = n
1522 elif f not in ma:
1546 elif f not in ma:
1523 self.ui.debug(_("remote created %s\n") % f)
1547 self.ui.debug(_("remote created %s\n") % f)
1524 get[f] = n
1548 get[f] = n
@@ -1548,7 +1572,8 b' class localrepository(object):'
1548 fl.sort()
1572 fl.sort()
1549 for f in fl:
1573 for f in fl:
1550 cf = ""
1574 cf = ""
1551 if f in merge: cf = _(" (resolve)")
1575 if f in merge:
1576 cf = _(" (resolve)")
1552 self.ui.status(" %s%s\n" % (f, cf))
1577 self.ui.status(" %s%s\n" % (f, cf))
1553 self.ui.warn(_("aborting update spanning branches!\n"))
1578 self.ui.warn(_("aborting update spanning branches!\n"))
1554 self.ui.status(_("(use update -m to merge across branches"
1579 self.ui.status(_("(use update -m to merge across branches"
@@ -1560,7 +1585,8 b' class localrepository(object):'
1560 files = get.keys()
1585 files = get.keys()
1561 files.sort()
1586 files.sort()
1562 for f in files:
1587 for f in files:
1563 if f[0] == "/": continue
1588 if f[0] == "/":
1589 continue
1564 self.ui.note(_("getting %s\n") % f)
1590 self.ui.note(_("getting %s\n") % f)
1565 t = self.file(f).read(get[f])
1591 t = self.file(f).read(get[f])
1566 self.wwrite(f, t)
1592 self.wwrite(f, t)
@@ -1577,7 +1603,9 b' class localrepository(object):'
1577 for f in files:
1603 for f in files:
1578 self.ui.status(_("merging %s\n") % f)
1604 self.ui.status(_("merging %s\n") % f)
1579 my, other, flag = merge[f]
1605 my, other, flag = merge[f]
1580 self.merge3(f, my, other)
1606 ret = self.merge3(f, my, other)
1607 if ret:
1608 err = True
1581 util.set_exec(self.wjoin(f), flag)
1609 util.set_exec(self.wjoin(f), flag)
1582 if moddirstate:
1610 if moddirstate:
1583 if branch_merge:
1611 if branch_merge:
@@ -1610,6 +1638,7 b' class localrepository(object):'
1610
1638
1611 if moddirstate:
1639 if moddirstate:
1612 self.dirstate.setparents(p1, p2)
1640 self.dirstate.setparents(p1, p2)
1641 return err
1613
1642
1614 def merge3(self, fn, my, other):
1643 def merge3(self, fn, my, other):
1615 """perform a 3-way merge in the working directory"""
1644 """perform a 3-way merge in the working directory"""
@@ -1640,6 +1669,7 b' class localrepository(object):'
1640
1669
1641 os.unlink(b)
1670 os.unlink(b)
1642 os.unlink(c)
1671 os.unlink(c)
1672 return r
1643
1673
1644 def verify(self):
1674 def verify(self):
1645 filelinkrevs = {}
1675 filelinkrevs = {}
@@ -1652,11 +1682,17 b' class localrepository(object):'
1652 self.ui.warn(msg + "\n")
1682 self.ui.warn(msg + "\n")
1653 errors[0] += 1
1683 errors[0] += 1
1654
1684
1685 def checksize(obj, name):
1686 d = obj.checksize()
1687 if d[0]:
1688 err(_("%s data length off by %d bytes") % (name, d[0]))
1689 if d[1]:
1690 err(_("%s index contains %d extra bytes") % (name, d[1]))
1691
1655 seen = {}
1692 seen = {}
1656 self.ui.status(_("checking changesets\n"))
1693 self.ui.status(_("checking changesets\n"))
1657 d = self.changelog.checksize()
1694 checksize(self.changelog, "changelog")
1658 if d:
1695
1659 err(_("changeset data short %d bytes") % d)
1660 for i in range(self.changelog.count()):
1696 for i in range(self.changelog.count()):
1661 changesets += 1
1697 changesets += 1
1662 n = self.changelog.node(i)
1698 n = self.changelog.node(i)
@@ -1686,9 +1722,8 b' class localrepository(object):'
1686
1722
1687 seen = {}
1723 seen = {}
1688 self.ui.status(_("checking manifests\n"))
1724 self.ui.status(_("checking manifests\n"))
1689 d = self.manifest.checksize()
1725 checksize(self.manifest, "manifest")
1690 if d:
1726
1691 err(_("manifest data short %d bytes") % d)
1692 for i in range(self.manifest.count()):
1727 for i in range(self.manifest.count()):
1693 n = self.manifest.node(i)
1728 n = self.manifest.node(i)
1694 l = self.manifest.linkrev(n)
1729 l = self.manifest.linkrev(n)
@@ -1723,7 +1758,7 b' class localrepository(object):'
1723
1758
1724 self.ui.status(_("crosschecking files in changesets and manifests\n"))
1759 self.ui.status(_("crosschecking files in changesets and manifests\n"))
1725
1760
1726 for m,c in neededmanifests.items():
1761 for m, c in neededmanifests.items():
1727 err(_("Changeset %s refers to unknown manifest %s") %
1762 err(_("Changeset %s refers to unknown manifest %s") %
1728 (short(m), short(c)))
1763 (short(m), short(c)))
1729 del neededmanifests
1764 del neededmanifests
@@ -1740,14 +1775,13 b' class localrepository(object):'
1740 ff = filenodes.keys()
1775 ff = filenodes.keys()
1741 ff.sort()
1776 ff.sort()
1742 for f in ff:
1777 for f in ff:
1743 if f == "/dev/null": continue
1778 if f == "/dev/null":
1779 continue
1744 files += 1
1780 files += 1
1745 fl = self.file(f)
1781 fl = self.file(f)
1746 d = fl.checksize()
1782 checksize(fl, f)
1747 if d:
1748 err(_("%s file data short %d bytes") % (f, d))
1749
1783
1750 nodes = { nullid: 1 }
1784 nodes = {nullid: 1}
1751 seen = {}
1785 seen = {}
1752 for i in range(fl.count()):
1786 for i in range(fl.count()):
1753 revisions += 1
1787 revisions += 1
@@ -108,6 +108,8 b' class manifest(revlog):'
108 files = map.keys()
108 files = map.keys()
109 files.sort()
109 files.sort()
110
110
111 # if this is changed to support newlines in filenames,
112 # be sure to check the templates/ dir again (especially *-raw.tmpl)
111 text = ["%s\000%s%s\n" %
113 text = ["%s\000%s%s\n" %
112 (f, hex(map[f]), flags[f] and "x" or '')
114 (f, hex(map[f]), flags[f] and "x" or '')
113 for f in files]
115 for f in files]
@@ -5,9 +5,13 b''
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 import difflib, struct, bdiff, util, mpatch
8 from demandload import demandload
9 import struct, bdiff, util, mpatch
10 demandload(globals(), "re")
9
11
10 def unidiff(a, ad, b, bd, fn, r=None, text=False):
12
13 def unidiff(a, ad, b, bd, fn, r=None, text=False,
14 showfunc=False, ignorews=False):
11
15
12 if not a and not b: return ""
16 if not a and not b: return ""
13 epoch = util.datestr((0, 0))
17 epoch = util.datestr((0, 0))
@@ -27,9 +31,10 b' def unidiff(a, ad, b, bd, fn, r=None, te'
27 l3 = "@@ -1,%d +0,0 @@\n" % len(a)
31 l3 = "@@ -1,%d +0,0 @@\n" % len(a)
28 l = [l1, l2, l3] + ["-" + e for e in a]
32 l = [l1, l2, l3] + ["-" + e for e in a]
29 else:
33 else:
30 a = a.splitlines(1)
34 al = a.splitlines(1)
31 b = b.splitlines(1)
35 bl = b.splitlines(1)
32 l = list(difflib.unified_diff(a, b, "a/" + fn, "b/" + fn))
36 l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn,
37 showfunc=showfunc, ignorews=ignorews))
33 if not l: return ""
38 if not l: return ""
34 # difflib uses a space, rather than a tab
39 # difflib uses a space, rather than a tab
35 l[0] = "%s\t%s\n" % (l[0][:-2], ad)
40 l[0] = "%s\t%s\n" % (l[0][:-2], ad)
@@ -45,6 +50,128 b' def unidiff(a, ad, b, bd, fn, r=None, te'
45
50
46 return "".join(l)
51 return "".join(l)
47
52
53 # somewhat self contained replacement for difflib.unified_diff
54 # t1 and t2 are the text to be diffed
55 # l1 and l2 are the text broken up into lines
56 # header1 and header2 are the filenames for the diff output
57 # context is the number of context lines
58 # showfunc enables diff -p output
59 # ignorews ignores all whitespace changes in the diff
60 def bunidiff(t1, t2, l1, l2, header1, header2, context=3, showfunc=False,
61 ignorews=False):
62 def contextend(l, len):
63 ret = l + context
64 if ret > len:
65 ret = len
66 return ret
67
68 def contextstart(l):
69 ret = l - context
70 if ret < 0:
71 return 0
72 return ret
73
74 def yieldhunk(hunk, header):
75 if header:
76 for x in header:
77 yield x
78 (astart, a2, bstart, b2, delta) = hunk
79 aend = contextend(a2, len(l1))
80 alen = aend - astart
81 blen = b2 - bstart + aend - a2
82
83 func = ""
84 if showfunc:
85 # walk backwards from the start of the context
86 # to find a line starting with an alphanumeric char.
87 for x in xrange(astart, -1, -1):
88 t = l1[x].rstrip()
89 if funcre.match(t):
90 func = ' ' + t[:40]
91 break
92
93 yield "@@ -%d,%d +%d,%d @@%s\n" % (astart + 1, alen,
94 bstart + 1, blen, func)
95 for x in delta:
96 yield x
97 for x in xrange(a2, aend):
98 yield ' ' + l1[x]
99
100 header = [ "--- %s\t\n" % header1, "+++ %s\t\n" % header2 ]
101
102 if showfunc:
103 funcre = re.compile('\w')
104 if ignorews:
105 wsre = re.compile('[ \t]')
106
107 # bdiff.blocks gives us the matching sequences in the files. The loop
108 # below finds the spaces between those matching sequences and translates
109 # them into diff output.
110 #
111 diff = bdiff.blocks(t1, t2)
112 hunk = None
113 for i in xrange(len(diff)):
114 # The first match is special.
115 # we've either found a match starting at line 0 or a match later
116 # in the file. If it starts later, old and new below will both be
117 # empty and we'll continue to the next match.
118 if i > 0:
119 s = diff[i-1]
120 else:
121 s = [0, 0, 0, 0]
122 delta = []
123 s1 = diff[i]
124 a1 = s[1]
125 a2 = s1[0]
126 b1 = s[3]
127 b2 = s1[2]
128
129 old = l1[a1:a2]
130 new = l2[b1:b2]
131
132 # bdiff sometimes gives huge matches past eof, this check eats them,
133 # and deals with the special first match case described above
134 if not old and not new:
135 continue
136
137 if ignorews:
138 wsold = wsre.sub('', "".join(old))
139 wsnew = wsre.sub('', "".join(new))
140 if wsold == wsnew:
141 continue
142
143 astart = contextstart(a1)
144 bstart = contextstart(b1)
145 prev = None
146 if hunk:
147 # join with the previous hunk if it falls inside the context
148 if astart < hunk[1] + context + 1:
149 prev = hunk
150 astart = hunk[1]
151 bstart = hunk[3]
152 else:
153 for x in yieldhunk(hunk, header):
154 yield x
155 # we only want to yield the header if the files differ, and
156 # we only want to yield it once.
157 header = None
158 if prev:
159 # we've joined the previous hunk, record the new ending points.
160 hunk[1] = a2
161 hunk[3] = b2
162 delta = hunk[4]
163 else:
164 # create a new hunk
165 hunk = [ astart, a2, bstart, b2, delta ]
166
167 delta[len(delta):] = [ ' ' + x for x in l1[astart:a1] ]
168 delta[len(delta):] = [ '-' + x for x in old ]
169 delta[len(delta):] = [ '+' + x for x in new ]
170
171 if hunk:
172 for x in yieldhunk(hunk, header):
173 yield x
174
48 def patchtext(bin):
175 def patchtext(bin):
49 pos = 0
176 pos = 0
50 t = []
177 t = []
@@ -188,6 +188,7 b' class revlog(object):'
188 self.datafile = datafile
188 self.datafile = datafile
189 self.opener = opener
189 self.opener = opener
190 self.cache = None
190 self.cache = None
191 self.chunkcache = None
191
192
192 try:
193 try:
193 i = self.opener(self.indexfile).read()
194 i = self.opener(self.indexfile).read()
@@ -196,6 +197,10 b' class revlog(object):'
196 raise
197 raise
197 i = ""
198 i = ""
198
199
200 if i and i[:4] != "\0\0\0\0":
201 raise RevlogError(_("incompatible revlog signature on %s") %
202 self.indexfile)
203
199 if len(i) > 10000:
204 if len(i) > 10000:
200 # big index, let's parse it on demand
205 # big index, let's parse it on demand
201 parser = lazyparser(i, self)
206 parser = lazyparser(i, self)
@@ -208,7 +213,7 b' class revlog(object):'
208 m = [None] * l
213 m = [None] * l
209
214
210 n = 0
215 n = 0
211 for f in xrange(0, len(i), s):
216 for f in xrange(0, l * s, s):
212 # offset, size, base, linkrev, p1, p2, nodeid
217 # offset, size, base, linkrev, p1, p2, nodeid
213 e = struct.unpack(indexformat, i[f:f + s])
218 e = struct.unpack(indexformat, i[f:f + s])
214 m[n] = (e[6], n)
219 m[n] = (e[6], n)
@@ -473,6 +478,35 b' class revlog(object):'
473 """apply a list of patches to a string"""
478 """apply a list of patches to a string"""
474 return mdiff.patches(t, pl)
479 return mdiff.patches(t, pl)
475
480
481 def chunk(self, rev):
482 start, length = self.start(rev), self.length(rev)
483 end = start + length
484
485 def loadcache():
486 cache_length = max(4096 * 1024, length) # 4Mo
487 df = self.opener(self.datafile)
488 df.seek(start)
489 self.chunkcache = (start, df.read(cache_length))
490
491 if not self.chunkcache:
492 loadcache()
493
494 cache_start = self.chunkcache[0]
495 cache_end = cache_start + len(self.chunkcache[1])
496 if start >= cache_start and end <= cache_end:
497 # it is cached
498 offset = start - cache_start
499 else:
500 loadcache()
501 offset = 0
502
503 #def checkchunk():
504 # df = self.opener(self.datafile)
505 # df.seek(start)
506 # return df.read(length)
507 #assert s == checkchunk()
508 return decompress(self.chunkcache[1][offset:offset + length])
509
476 def delta(self, node):
510 def delta(self, node):
477 """return or calculate a delta between a node and its predecessor"""
511 """return or calculate a delta between a node and its predecessor"""
478 r = self.rev(node)
512 r = self.rev(node)
@@ -481,10 +515,7 b' class revlog(object):'
481 return self.diff(self.revision(self.node(r - 1)),
515 return self.diff(self.revision(self.node(r - 1)),
482 self.revision(node))
516 self.revision(node))
483 else:
517 else:
484 f = self.opener(self.datafile)
518 return self.chunk(r)
485 f.seek(self.start(r))
486 data = f.read(self.length(r))
487 return decompress(data)
488
519
489 def revision(self, node):
520 def revision(self, node):
490 """return an uncompressed revision of a given"""
521 """return an uncompressed revision of a given"""
@@ -494,33 +525,22 b' class revlog(object):'
494 # look up what we need to read
525 # look up what we need to read
495 text = None
526 text = None
496 rev = self.rev(node)
527 rev = self.rev(node)
497 start, length, base, link, p1, p2, node = self.index[rev]
528 base = self.base(rev)
498 end = start + length
499 if base != rev: start = self.start(base)
500
529
501 # do we have useful data cached?
530 # do we have useful data cached?
502 if self.cache and self.cache[1] >= base and self.cache[1] < rev:
531 if self.cache and self.cache[1] >= base and self.cache[1] < rev:
503 base = self.cache[1]
532 base = self.cache[1]
504 start = self.start(base + 1)
505 text = self.cache[2]
533 text = self.cache[2]
506 last = 0
534 else:
507
535 text = self.chunk(base)
508 f = self.opener(self.datafile)
509 f.seek(start)
510 data = f.read(end - start)
511
512 if text is None:
513 last = self.length(base)
514 text = decompress(data[:last])
515
536
516 bins = []
537 bins = []
517 for r in xrange(base + 1, rev + 1):
538 for r in xrange(base + 1, rev + 1):
518 s = self.length(r)
539 bins.append(self.chunk(r))
519 bins.append(decompress(data[last:last + s]))
520 last = last + s
521
540
522 text = mdiff.patches(text, bins)
541 text = mdiff.patches(text, bins)
523
542
543 p1, p2 = self.parents(node)
524 if node != hash(text, p1, p2):
544 if node != hash(text, p1, p2):
525 raise RevlogError(_("integrity check failed on %s:%d")
545 raise RevlogError(_("integrity check failed on %s:%d")
526 % (self.datafile, rev))
546 % (self.datafile, rev))
@@ -650,7 +670,7 b' class revlog(object):'
650 #print "next x"
670 #print "next x"
651 gx = x.next()
671 gx = x.next()
652
672
653 def group(self, nodelist, lookup, infocollect = None):
673 def group(self, nodelist, lookup, infocollect=None):
654 """calculate a delta group
674 """calculate a delta group
655
675
656 Given a list of changeset revs, return a set of deltas and
676 Given a list of changeset revs, return a set of deltas and
@@ -660,7 +680,6 b' class revlog(object):'
660 changesets. parent is parent[0]
680 changesets. parent is parent[0]
661 """
681 """
662 revs = [self.rev(n) for n in nodelist]
682 revs = [self.rev(n) for n in nodelist]
663 needed = dict.fromkeys(revs, 1)
664
683
665 # if we don't have any revisions touched by these changesets, bail
684 # if we don't have any revisions touched by these changesets, bail
666 if not revs:
685 if not revs:
@@ -671,88 +690,30 b' class revlog(object):'
671 p = self.parents(self.node(revs[0]))[0]
690 p = self.parents(self.node(revs[0]))[0]
672 revs.insert(0, self.rev(p))
691 revs.insert(0, self.rev(p))
673
692
674 # for each delta that isn't contiguous in the log, we need to
675 # reconstruct the base, reconstruct the result, and then
676 # calculate the delta. We also need to do this where we've
677 # stored a full version and not a delta
678 for i in xrange(0, len(revs) - 1):
679 a, b = revs[i], revs[i + 1]
680 if a + 1 != b or self.base(b) == b:
681 for j in xrange(self.base(a), a + 1):
682 needed[j] = 1
683 for j in xrange(self.base(b), b + 1):
684 needed[j] = 1
685
686 # calculate spans to retrieve from datafile
687 needed = needed.keys()
688 needed.sort()
689 spans = []
690 oo = -1
691 ol = 0
692 for n in needed:
693 if n < 0: continue
694 o = self.start(n)
695 l = self.length(n)
696 if oo + ol == o: # can we merge with the previous?
697 nl = spans[-1][2]
698 nl.append((n, l))
699 ol += l
700 spans[-1] = (oo, ol, nl)
701 else:
702 oo = o
703 ol = l
704 spans.append((oo, ol, [(n, l)]))
705
706 # read spans in, divide up chunks
707 chunks = {}
708 for span in spans:
709 # we reopen the file for each span to make http happy for now
710 f = self.opener(self.datafile)
711 f.seek(span[0])
712 data = f.read(span[1])
713
714 # divide up the span
715 pos = 0
716 for r, l in span[2]:
717 chunks[r] = decompress(data[pos: pos + l])
718 pos += l
719
720 # helper to reconstruct intermediate versions
693 # helper to reconstruct intermediate versions
721 def construct(text, base, rev):
694 def construct(text, base, rev):
722 bins = [chunks[r] for r in xrange(base + 1, rev + 1)]
695 bins = [self.chunk(r) for r in xrange(base + 1, rev + 1)]
723 return mdiff.patches(text, bins)
696 return mdiff.patches(text, bins)
724
697
725 # build deltas
698 # build deltas
726 deltas = []
727 for d in xrange(0, len(revs) - 1):
699 for d in xrange(0, len(revs) - 1):
728 a, b = revs[d], revs[d + 1]
700 a, b = revs[d], revs[d + 1]
729 n = self.node(b)
701 na = self.node(a)
702 nb = self.node(b)
730
703
731 if infocollect is not None:
704 if infocollect is not None:
732 infocollect(n)
705 infocollect(nb)
733
706
734 # do we need to construct a new delta?
707 # do we need to construct a new delta?
735 if a + 1 != b or self.base(b) == b:
708 if a + 1 != b or self.base(b) == b:
736 if a >= 0:
709 ta = self.revision(na)
737 base = self.base(a)
710 tb = self.revision(nb)
738 ta = chunks[self.base(a)]
739 ta = construct(ta, base, a)
740 else:
741 ta = ""
742
743 base = self.base(b)
744 if a > base:
745 base = a
746 tb = ta
747 else:
748 tb = chunks[self.base(b)]
749 tb = construct(tb, base, b)
750 d = self.diff(ta, tb)
711 d = self.diff(ta, tb)
751 else:
712 else:
752 d = chunks[b]
713 d = self.chunk(b)
753
714
754 p = self.parents(n)
715 p = self.parents(nb)
755 meta = n + p[0] + p[1] + lookup(n)
716 meta = nb + p[0] + p[1] + lookup(nb)
756 l = struct.pack(">l", len(meta) + len(d) + 4)
717 l = struct.pack(">l", len(meta) + len(d) + 4)
757 yield l
718 yield l
758 yield meta
719 yield meta
@@ -880,14 +841,29 b' class revlog(object):'
880 expected = 0
841 expected = 0
881 if self.count():
842 if self.count():
882 expected = self.end(self.count() - 1)
843 expected = self.end(self.count() - 1)
844
883 try:
845 try:
884 f = self.opener(self.datafile)
846 f = self.opener(self.datafile)
885 f.seek(0, 2)
847 f.seek(0, 2)
886 actual = f.tell()
848 actual = f.tell()
887 return expected - actual
849 dd = actual - expected
888 except IOError, inst:
850 except IOError, inst:
889 if inst.errno == errno.ENOENT:
851 if inst.errno != errno.ENOENT:
890 return 0
852 raise
891 raise
853 dd = 0
854
855 try:
856 f = self.opener(self.indexfile)
857 f.seek(0, 2)
858 actual = f.tell()
859 s = struct.calcsize(indexformat)
860 i = actual / s
861 di = actual - (i * s)
862 except IOError, inst:
863 if inst.errno != errno.ENOENT:
864 raise
865 di = 0
866
867 return (dd, di)
892
868
893
869
@@ -35,6 +35,8 b' class statichttprepository(localrepo.loc'
35 self.changelog = changelog.changelog(self.opener)
35 self.changelog = changelog.changelog(self.opener)
36 self.tagscache = None
36 self.tagscache = None
37 self.nodetagscache = None
37 self.nodetagscache = None
38 self.encodepats = None
39 self.decodepats = None
38
40
39 def dev(self):
41 def dev(self):
40 return -1
42 return -1
@@ -23,6 +23,7 b' class ui(object):'
23 self.interactive = self.configbool("ui", "interactive", True)
23 self.interactive = self.configbool("ui", "interactive", True)
24
24
25 self.updateopts(verbose, debug, quiet, interactive)
25 self.updateopts(verbose, debug, quiet, interactive)
26 self.diffcache = None
26
27
27 def updateopts(self, verbose=False, debug=False, quiet=False,
28 def updateopts(self, verbose=False, debug=False, quiet=False,
28 interactive=True):
29 interactive=True):
@@ -76,6 +77,23 b' class ui(object):'
76 def extensions(self):
77 def extensions(self):
77 return self.configitems("extensions")
78 return self.configitems("extensions")
78
79
80 def diffopts(self):
81 if self.diffcache:
82 return self.diffcache
83 ret = { 'showfunc' : True, 'ignorews' : False}
84 for x in self.configitems("diff"):
85 k = x[0].lower()
86 v = x[1]
87 if v:
88 v = v.lower()
89 if v == 'true':
90 value = True
91 else:
92 value = False
93 ret[k] = value
94 self.diffcache = ret
95 return ret
96
79 def username(self):
97 def username(self):
80 return (os.environ.get("HGUSER") or
98 return (os.environ.get("HGUSER") or
81 self.config("ui", "username") or
99 self.config("ui", "username") or
@@ -110,7 +128,7 b' class ui(object):'
110 sys.stdout.write(str(a))
128 sys.stdout.write(str(a))
111
129
112 def write_err(self, *args):
130 def write_err(self, *args):
113 sys.stdout.flush()
131 if not sys.stdout.closed: sys.stdout.flush()
114 for a in args:
132 for a in args:
115 sys.stderr.write(str(a))
133 sys.stderr.write(str(a))
116
134
@@ -13,7 +13,8 b' platform-specific details from the core.'
13 import os, errno
13 import os, errno
14 from i18n import gettext as _
14 from i18n import gettext as _
15 from demandload import *
15 from demandload import *
16 demandload(globals(), "re cStringIO shutil popen2 sys tempfile threading time")
16 demandload(globals(), "cStringIO errno popen2 re shutil sys tempfile")
17 demandload(globals(), "threading time")
17
18
18 def pipefilter(s, cmd):
19 def pipefilter(s, cmd):
19 '''filter string S through command CMD, returning its output'''
20 '''filter string S through command CMD, returning its output'''
@@ -190,17 +191,17 b' def canonpath(root, cwd, myname):'
190 else:
191 else:
191 raise Abort('%s not under root' % myname)
192 raise Abort('%s not under root' % myname)
192
193
193 def matcher(canonroot, cwd='', names=['.'], inc=[], exc=[], head=''):
194 def matcher(canonroot, cwd='', names=['.'], inc=[], exc=[], head='', src=None):
194 return _matcher(canonroot, cwd, names, inc, exc, head, 'glob')
195 return _matcher(canonroot, cwd, names, inc, exc, head, 'glob', src)
195
196
196 def cmdmatcher(canonroot, cwd='', names=['.'], inc=[], exc=[], head=''):
197 def cmdmatcher(canonroot, cwd='', names=['.'], inc=[], exc=[], head='', src=None):
197 if os.name == 'nt':
198 if os.name == 'nt':
198 dflt_pat = 'glob'
199 dflt_pat = 'glob'
199 else:
200 else:
200 dflt_pat = 'relpath'
201 dflt_pat = 'relpath'
201 return _matcher(canonroot, cwd, names, inc, exc, head, dflt_pat)
202 return _matcher(canonroot, cwd, names, inc, exc, head, dflt_pat, src)
202
203
203 def _matcher(canonroot, cwd, names, inc, exc, head, dflt_pat):
204 def _matcher(canonroot, cwd, names, inc, exc, head, dflt_pat, src):
204 """build a function to match a set of file patterns
205 """build a function to match a set of file patterns
205
206
206 arguments:
207 arguments:
@@ -261,7 +262,8 b' def _matcher(canonroot, cwd, names, inc,'
261 pat = '(?:%s)' % regex(k, p, tail)
262 pat = '(?:%s)' % regex(k, p, tail)
262 matches.append(re.compile(pat).match)
263 matches.append(re.compile(pat).match)
263 except re.error:
264 except re.error:
264 raise Abort("invalid pattern: %s:%s" % (k, p))
265 if src: raise Abort("%s: invalid pattern (%s): %s" % (src, k, p))
266 else: raise Abort("invalid pattern (%s): %s" % (k, p))
265
267
266 def buildfn(text):
268 def buildfn(text):
267 for m in matches:
269 for m in matches:
@@ -357,9 +359,9 b' def copyfiles(src, dst, hardlink=None):'
357 os_link(src, dst)
359 os_link(src, dst)
358 except:
360 except:
359 hardlink = False
361 hardlink = False
360 shutil.copy2(src, dst)
362 shutil.copy(src, dst)
361 else:
363 else:
362 shutil.copy2(src, dst)
364 shutil.copy(src, dst)
363
365
364 def opener(base):
366 def opener(base):
365 """
367 """
@@ -442,12 +444,36 b' else:'
442 if os.name == 'nt':
444 if os.name == 'nt':
443 demandload(globals(), "msvcrt")
445 demandload(globals(), "msvcrt")
444 nulldev = 'NUL:'
446 nulldev = 'NUL:'
445
447
448 class winstdout:
449 '''stdout on windows misbehaves if sent through a pipe'''
450
451 def __init__(self, fp):
452 self.fp = fp
453
454 def __getattr__(self, key):
455 return getattr(self.fp, key)
456
457 def close(self):
458 try:
459 self.fp.close()
460 except: pass
461
462 def write(self, s):
463 try:
464 return self.fp.write(s)
465 except IOError, inst:
466 if inst.errno != 0: raise
467 self.close()
468 raise IOError(errno.EPIPE, 'Broken pipe')
469
470 sys.stdout = winstdout(sys.stdout)
471
446 try:
472 try:
447 import win32api, win32process
473 import win32api, win32process
448 filename = win32process.GetModuleFileNameEx(win32api.GetCurrentProcess(), 0)
474 filename = win32process.GetModuleFileNameEx(win32api.GetCurrentProcess(), 0)
449 systemrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
475 systemrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
450
476
451 except ImportError:
477 except ImportError:
452 systemrc = r'c:\mercurial\mercurial.ini'
478 systemrc = r'c:\mercurial\mercurial.ini'
453 pass
479 pass
@@ -518,14 +544,19 b' else:'
518 if f.endswith(".rc")])
544 if f.endswith(".rc")])
519 except OSError, inst: pass
545 except OSError, inst: pass
520 return rcs
546 return rcs
521 rcpath = rcfiles(os.path.dirname(sys.argv[0]) + '/../etc/mercurial')
547 rcpath = []
548 if len(sys.argv) > 0:
549 rcpath.extend(rcfiles(os.path.dirname(sys.argv[0]) + '/../etc/mercurial'))
522 rcpath.extend(rcfiles('/etc/mercurial'))
550 rcpath.extend(rcfiles('/etc/mercurial'))
523 rcpath.append(os.path.expanduser('~/.hgrc'))
551 rcpath.append(os.path.expanduser('~/.hgrc'))
524 rcpath = [os.path.normpath(f) for f in rcpath]
552 rcpath = [os.path.normpath(f) for f in rcpath]
525
553
526 def parse_patch_output(output_line):
554 def parse_patch_output(output_line):
527 """parses the output produced by patch and returns the file name"""
555 """parses the output produced by patch and returns the file name"""
528 return output_line[14:]
556 pf = output_line[14:]
557 if pf.startswith("'") and pf.endswith("'") and pf.find(" ") >= 0:
558 pf = pf[1:-1] # Remove the quotes
559 return pf
529
560
530 def is_exec(f, last):
561 def is_exec(f, last):
531 """check whether a file is executable"""
562 """check whether a file is executable"""
@@ -11,7 +11,7 b''
11
11
12 <form action="#">
12 <form action="#">
13 <div class="search">
13 <div class="search">
14 <input type="hidden" name="repo" value="#repo#" />
14 <input type="hidden" name="repo" value="#repo|escape#" />
15 <input type="hidden" name="style" value="gitweb" />
15 <input type="hidden" name="style" value="gitweb" />
16 <input type="hidden" name="cmd" value="changelog" />
16 <input type="hidden" name="cmd" value="changelog" />
17 <input type="text" name="rev" />
17 <input type="text" name="rev" />
@@ -8,7 +8,7 b''
8 <i>#author|obfuscate# [#date|rfc822date#]</i><br/>
8 <i>#author|obfuscate# [#date|rfc822date#]</i><br/>
9 </div>
9 </div>
10 <div class="log_body">
10 <div class="log_body">
11 #desc|addbreaks#
11 #desc|escape|addbreaks#
12 <br/>
12 <br/>
13 <br/>
13 <br/>
14 </div>
14 </div>
@@ -8,6 +8,7 b''
8 <td class="changesetNode"><a href="?cs=#node|short#">#node|short#</a></td>
8 <td class="changesetNode"><a href="?cs=#node|short#">#node|short#</a></td>
9 </tr>
9 </tr>
10 #parent%changelogparent#
10 #parent%changelogparent#
11 #child%changelogchild#
11 #changelogtag#
12 #changelogtag#
12 <tr>
13 <tr>
13 <th class="author">author:</th>
14 <th class="author">author:</th>
@@ -10,7 +10,7 b''
10 </div>
10 </div>
11
11
12 <div class="page_nav">
12 <div class="page_nav">
13 <a href="?cmd=summary;style=gitweb">summary</a> | <a href="?cmd=changelog;rev=#rev#;style=gitweb">changelog</a> | <a href="?cmd=tags;style=gitweb">tags</a> | <a href="?cmd=manifest;manifest=#manifest#;path=/;style=gitweb">manifest</a> | changeset | <a href="?cmd=changeset;node=#node#;style=raw">raw</a><br/>
13 <a href="?cmd=summary;style=gitweb">summary</a> | <a href="?cmd=changelog;rev=#rev#;style=gitweb">changelog</a> | <a href="?cmd=tags;style=gitweb">tags</a> | <a href="?cmd=manifest;manifest=#manifest#;path=/;style=gitweb">manifest</a> | changeset | <a href="?cmd=changeset;node=#node#;style=raw">raw</a> #archives%archiveentry#<br/>
14 </div>
14 </div>
15
15
16 <div>
16 <div>
@@ -23,11 +23,12 b''
23 <tr><td>changeset</td><td style="font-family:monospace">#node|short#</td></tr>
23 <tr><td>changeset</td><td style="font-family:monospace">#node|short#</td></tr>
24 <tr><td>manifest</td><td style="font-family:monospace"><a class="list" href="?cmd=manifest;manifest=#manifest|short#;path=/;style=gitweb">#manifest|short#</a></td></tr>
24 <tr><td>manifest</td><td style="font-family:monospace"><a class="list" href="?cmd=manifest;manifest=#manifest|short#;path=/;style=gitweb">#manifest|short#</a></td></tr>
25 #parent%changesetparent#
25 #parent%changesetparent#
26 #child%changesetchild#
26 #changesettag#
27 #changesettag#
27 </table></div>
28 </table></div>
28
29
29 <div class="title_text">
30 <div class="title_text">
30 #desc|addbreaks#
31 #desc|escape|addbreaks#
31 </div>
32 </div>
32
33
33 <div class="title_text">
34 <div class="title_text">
@@ -19,6 +19,7 b''
19 <td class="changeset"><a href="?cs=#node|short#">#node|short#</a></td>
19 <td class="changeset"><a href="?cs=#node|short#">#node|short#</a></td>
20 </tr>
20 </tr>
21 #parent%changesetparent#
21 #parent%changesetparent#
22 #child%changesetchild#
22 #changesettag#
23 #changesettag#
23 <tr>
24 <tr>
24 <th class="author">author:</th>
25 <th class="author">author:</th>
@@ -10,16 +10,17 b''
10 </div>
10 </div>
11
11
12 <div class="page_nav">
12 <div class="page_nav">
13 <a href="?cmd=summary;style=gitweb">summary</a> | <a href="?cmd=changelog;style=gitweb">changelog</a> | <a href="?cmd=tags;style=gitweb">tags</a> | <a href="?cmd=manifest;manifest=#manifest#;path=#path#;style=gitweb">manifest</a> | <a href="?cmd=changeset;node=#node#;style=gitweb">changeset</a> | <a href="?cmd=file;file=#file#;filenode=#filenode#;style=gitweb">file</a> | <a href="?cmd=filelog;file=#file#;filenode=#filenode#;style=gitweb">revisions</a> | annotate<br/>
13 <a href="?cmd=summary;style=gitweb">summary</a> | <a href="?cmd=changelog;style=gitweb">changelog</a> | <a href="?cmd=tags;style=gitweb">tags</a> | <a href="?cmd=manifest;manifest=#manifest#;path=#path|urlescape#;style=gitweb">manifest</a> | <a href="?cmd=changeset;node=#node#;style=gitweb">changeset</a> | <a href="?cmd=file;file=#file|urlescape#;filenode=#filenode#;style=gitweb">file</a> | <a href="?cmd=filelog;file=#file|urlescape#;filenode=#filenode#;style=gitweb">revisions</a> | annotate<br/>
14 </div>
14 </div>
15
15
16 <div class="title">#file#</div>
16 <div class="title">#file|escape#</div>
17
17
18 <table>
18 <table>
19 <tr>
19 <tr>
20 <td class="metatag">changeset #rev#:</td>
20 <td class="metatag">changeset #rev#:</td>
21 <td><a href="?cs=#node|short#;style=gitweb">#node|short#</a></td></tr>
21 <td><a href="?cs=#node|short#;style=gitweb">#node|short#</a></td></tr>
22 #parent%fileannotateparent#
22 #parent%fileannotateparent#
23 #child%fileannotatechild#
23 <tr>
24 <tr>
24 <td class="metatag">manifest:</td>
25 <td class="metatag">manifest:</td>
25 <td><a href="?mf=#manifest|short#;path=/;style=gitweb">#manifest|short#</a></td></tr>
26 <td><a href="?mf=#manifest|short#;path=/;style=gitweb">#manifest|short#</a></td></tr>
@@ -1,5 +1,5 b''
1 #header#
1 #header#
2 <title>#repo|escape#: #file# annotate</title>
2 <title>#repo|escape#: #file|escape# annotate</title>
3 </head>
3 </head>
4 <body>
4 <body>
5
5
@@ -7,18 +7,20 b''
7 <a href="?cl=#rev#">changelog</a>
7 <a href="?cl=#rev#">changelog</a>
8 <a href="?tags=">tags</a>
8 <a href="?tags=">tags</a>
9 <a href="?cs=#node|short#">changeset</a>
9 <a href="?cs=#node|short#">changeset</a>
10 <a href="?mf=#manifest|short#;path=#path#">manifest</a>
10 <a href="?mf=#manifest|short#;path=#path|urlescape#">manifest</a>
11 <a href="?f=#filenode|short#;file=#file#">file</a>
11 <a href="?f=#filenode|short#;file=#file|urlescape#">file</a>
12 <a href="?fl=#filenode|short#;file=#file#">revisions</a>
12 <a href="?fl=#filenode|short#;file=#file|urlescape#">revisions</a>
13 </div>
13 </div>
14
14
15 <h2>Annotate #file#</h2>
15 <h2>Annotate #file|escape#</h2>
16
16
17 <table>
17 <table>
18 <tr>
18 <tr>
19 <td class="metatag">changeset #rev#:</td>
19 <td class="metatag">changeset #rev#:</td>
20 <td><a href="?cs=#node|short#">#node|short#</a></td></tr>
20 <td><a href="?cs=#node|short#">#node|short#</a></td></tr>
21 #rename%filerename#
21 #parent%fileannotateparent#
22 #parent%fileannotateparent#
23 #child%fileannotatechild#
22 <tr>
24 <tr>
23 <td class="metatag">author:</td>
25 <td class="metatag">author:</td>
24 <td>#author|obfuscate#</td></tr>
26 <td>#author|obfuscate#</td></tr>
@@ -1,5 +1,5 b''
1 #header#
1 #header#
2 <title>#repo|escape#: #file# diff</title>
2 <title>#repo|escape#: #file|escape# diff</title>
3 </head>
3 </head>
4 <body>
4 <body>
5
5
@@ -7,13 +7,13 b''
7 <a href="?cl=#rev#">changelog</a>
7 <a href="?cl=#rev#">changelog</a>
8 <a href="?tags=">tags</a>
8 <a href="?tags=">tags</a>
9 <a href="?cs=#node|short#">changeset</a>
9 <a href="?cs=#node|short#">changeset</a>
10 <a href="?f=#filenode|short#;file=#file#">file</a>
10 <a href="?f=#filenode|short#;file=#file|urlescape#">file</a>
11 <a href="?fl=#filenode|short#;file=#file#">revisions</a>
11 <a href="?fl=#filenode|short#;file=#file|urlescape#">revisions</a>
12 <a href="?fa=#filenode|short#;file=#file#">annotate</a>
12 <a href="?fa=#filenode|short#;file=#file|urlescape#">annotate</a>
13 <a href="?fd=#node|short#;file=#file#;style=raw">raw</a>
13 <a href="?fd=#node|short#;file=#file|urlescape#;style=raw">raw</a>
14 </div>
14 </div>
15
15
16 <h2>#file#</h2>
16 <h2>#file|escape#</h2>
17
17
18 <table id="filediffEntry">
18 <table id="filediffEntry">
19 <tr>
19 <tr>
@@ -21,6 +21,7 b''
21 <td class="revision"><a href="?cs=#node|short#">#node|short#</a></td>
21 <td class="revision"><a href="?cs=#node|short#">#node|short#</a></td>
22 </tr>
22 </tr>
23 #parent%filediffparent#
23 #parent%filediffparent#
24 #child%filediffchild#
24 </table>
25 </table>
25
26
26 <div id="fileDiff">
27 <div id="fileDiff">
@@ -10,7 +10,7 b''
10 </div>
10 </div>
11
11
12 <div class="page_nav">
12 <div class="page_nav">
13 <a href="?cmd=summary;style=gitweb">summary</a> | <a href="?cmd=changelog;style=gitweb">changelog</a> | <a href="?cmd=tags;style=gitweb">tags</a> | <a href="?cmd=file;file=#file#;filenode=#filenode#;style=gitweb">file</a> | revisions | <a href="?cmd=annotate;file=#file#;filenode=#filenode#;style=gitweb">annotate</a> | <a href="?fl=#filenode|short#;file=#file#;style=rss">rss</a><br/>
13 <a href="?cmd=summary;style=gitweb">summary</a> | <a href="?cmd=changelog;style=gitweb">changelog</a> | <a href="?cmd=tags;style=gitweb">tags</a> | <a href="?cmd=file;file=#file|urlescape#;filenode=#filenode#;style=gitweb">file</a> | revisions | <a href="?cmd=annotate;file=#file|urlescape#;filenode=#filenode#;style=gitweb">annotate</a> | <a href="?fl=#filenode|short#;file=#file|urlescape#;style=rss">rss</a><br/>
14 </div>
14 </div>
15
15
16 <table>
16 <table>
@@ -1,6 +1,6 b''
1 #header#
1 #header#
2 <title>#repo|escape#: #file# history</title>
2 <title>#repo|escape#: #file|escape# history</title>
3 <description>#file# revision history</description>
3 <description>#file|escape# revision history</description>
4 #entries%filelogentry#
4 #entries%filelogentry#
5 </channel>
5 </channel>
6 </rss> No newline at end of file
6 </rss>
@@ -1,7 +1,7 b''
1 #header#
1 #header#
2 <title>#repo|escape#: #file# history</title>
2 <title>#repo|escape#: #file|escape# history</title>
3 <link rel="alternate" type="application/rss+xml"
3 <link rel="alternate" type="application/rss+xml"
4 href="?fl=0;file=#file#;style=rss" title="RSS feed for #repo|escape#:#file#">
4 href="?fl=0;file=#file|urlescape#;style=rss" title="RSS feed for #repo|escape#:#file#">
5 </head>
5 </head>
6 </head>
6 </head>
7 <body>
7 <body>
@@ -9,12 +9,12 b''
9 <div class="buttons">
9 <div class="buttons">
10 <a href="?cl=tip">changelog</a>
10 <a href="?cl=tip">changelog</a>
11 <a href="?tags=">tags</a>
11 <a href="?tags=">tags</a>
12 <a href="?f=#filenode|short#;file=#file#">file</a>
12 <a href="?f=#filenode|short#;file=#file|urlescape#">file</a>
13 <a href="?fa=#filenode|short#;file=#file#">annotate</a>
13 <a href="?fa=#filenode|short#;file=#file|urlescape#">annotate</a>
14 <a type="application/rss+xml" href="?fl=0;file=#file#;style=rss">rss</a>
14 <a type="application/rss+xml" href="?fl=0;file=#file|urlescape#;style=rss">rss</a>
15 </div>
15 </div>
16
16
17 <h2>#file# revision history</h2>
17 <h2>#file|escape# revision history</h2>
18
18
19 #entries%filelogentry#
19 #entries%filelogentry#
20
20
@@ -1,6 +1,6 b''
1 <item>
1 <item>
2 <title>#desc|strip|firstline|strip|escape#</title>
2 <title>#desc|strip|firstline|strip|escape#</title>
3 <link>#url#?f=#filenode|short#;file=#file#</link>
3 <link>#url#?f=#filenode|short#;file=#file|urlescape#</link>
4 <description><![CDATA[#desc|strip|escape|addbreaks#]]></description>
4 <description><![CDATA[#desc|strip|escape|addbreaks#]]></description>
5 <author>#author|obfuscate#</author>
5 <author>#author|obfuscate#</author>
6 <pubDate>#date|rfc822date#</pubDate>>
6 <pubDate>#date|rfc822date#</pubDate>>
@@ -4,10 +4,11 b''
4 <td><b><a href="?cs=#node|short#">#desc|strip|firstline|escape#</a></b></td></tr>
4 <td><b><a href="?cs=#node|short#">#desc|strip|firstline|escape#</a></b></td></tr>
5 <tr>
5 <tr>
6 <td align="right">revision #filerev#:&nbsp;</td>
6 <td align="right">revision #filerev#:&nbsp;</td>
7 <td><a href="?f=#filenode|short#;file=#file#">#filenode|short#</a>
7 <td><a href="?f=#filenode|short#;file=#file|urlescape#">#filenode|short#</a>
8 <a href="?fd=#node|short#;file=#file#">(diff)</a>
8 <a href="?fd=#node|short#;file=#file|urlescape#">(diff)</a>
9 <a href="?fa=#filenode|short#;file=#file#">(annotate)</a>
9 <a href="?fa=#filenode|short#;file=#file|urlescape#">(annotate)</a>
10 </td></tr>
10 </td></tr>
11 #rename%filelogrename#
11 <tr>
12 <tr>
12 <td align="right">author:&nbsp;</td>
13 <td align="right">author:&nbsp;</td>
13 <td>#author|obfuscate#</td></tr>
14 <td>#author|obfuscate#</td></tr>
@@ -10,16 +10,17 b''
10 </div>
10 </div>
11
11
12 <div class="page_nav">
12 <div class="page_nav">
13 <a href="?cmd=summary;style=gitweb">summary</a> | <a href="?cmd=changelog;style=gitweb">changelog</a> | <a href="?cmd=tags;style=gitweb">tags</a> | <a href="?mf=#manifest|short#;path=#path#;style=gitweb">manifest</a> | <a href="?cmd=changeset;node=#node#;style=gitweb">changeset</a> | file | <a href="?cmd=filelog;file=#file#;filenode=#filenode#;style=gitweb">revisions</a> | <a href="?cmd=annotate;file=#file#;filenode=#filenode#;style=gitweb">annotate</a> | <a href="?cmd=file;file=#file#;filenode=#filenode#;style=raw">raw</a><br/>
13 <a href="?cmd=summary;style=gitweb">summary</a> | <a href="?cmd=changelog;style=gitweb">changelog</a> | <a href="?cmd=tags;style=gitweb">tags</a> | <a href="?mf=#manifest|short#;path=#path|urlescape#;style=gitweb">manifest</a> | <a href="?cmd=changeset;node=#node#;style=gitweb">changeset</a> | file | <a href="?cmd=filelog;file=#file|urlescape#;filenode=#filenode#;style=gitweb">revisions</a> | <a href="?cmd=annotate;file=#file|urlescape#;filenode=#filenode#;style=gitweb">annotate</a> | <a href="?cmd=file;file=#file|urlescape#;filenode=#filenode#;style=raw">raw</a><br/>
14 </div>
14 </div>
15
15
16 <div class="title">#file#</div>
16 <div class="title">#file|escape#</div>
17
17
18 <table>
18 <table>
19 <tr>
19 <tr>
20 <td class="metatag">changeset #rev#:</td>
20 <td class="metatag">changeset #rev#:</td>
21 <td><a href="?cs=#node|short#;style=gitweb">#node|short#</a></td></tr>
21 <td><a href="?cs=#node|short#;style=gitweb">#node|short#</a></td></tr>
22 #parent%fileannotateparent#
22 #parent%fileannotateparent#
23 #child%fileannotatechild#
23 <tr>
24 <tr>
24 <td class="metatag">manifest:</td>
25 <td class="metatag">manifest:</td>
25 <td><a href="?mf=#manifest|short#;path=/;style=gitweb">#manifest|short#</a></td></tr>
26 <td><a href="?mf=#manifest|short#;path=/;style=gitweb">#manifest|short#</a></td></tr>
@@ -1,5 +1,5 b''
1 #header#
1 #header#
2 <title>#repo|escape#:#file#</title>
2 <title>#repo|escape#:#file|escape#</title>
3 </head>
3 </head>
4 <body>
4 <body>
5
5
@@ -7,19 +7,21 b''
7 <a href="?cl=#rev#">changelog</a>
7 <a href="?cl=#rev#">changelog</a>
8 <a href="?tags=">tags</a>
8 <a href="?tags=">tags</a>
9 <a href="?cs=#node|short#">changeset</a>
9 <a href="?cs=#node|short#">changeset</a>
10 <a href="?mf=#manifest|short#;path=#path#">manifest</a>
10 <a href="?mf=#manifest|short#;path=#path|urlescape#">manifest</a>
11 <a href="?fl=#filenode|short#;file=#file#">revisions</a>
11 <a href="?fl=#filenode|short#;file=#file|urlescape#">revisions</a>
12 <a href="?fa=#filenode|short#;file=#file#">annotate</a>
12 <a href="?fa=#filenode|short#;file=#file|urlescape#">annotate</a>
13 <a href="?f=#filenode|short#;file=#file#;style=raw">raw</a>
13 <a href="?f=#filenode|short#;file=#file|urlescape#;style=raw">raw</a>
14 </div>
14 </div>
15
15
16 <h2>#file#</h2>
16 <h2>#file|escape#</h2>
17
17
18 <table>
18 <table>
19 <tr>
19 <tr>
20 <td class="metatag">changeset #rev#:</td>
20 <td class="metatag">changeset #rev#:</td>
21 <td><a href="?cs=#node|short#">#node|short#</a></td></tr>
21 <td><a href="?cs=#node|short#">#node|short#</a></td></tr>
22 #rename%filerename#
22 #parent%filerevparent#
23 #parent%filerevparent#
24 #child%filerevchild#
23 <tr>
25 <tr>
24 <td class="metatag">author:</td>
26 <td class="metatag">author:</td>
25 <td>#author|obfuscate#</td></tr>
27 <td>#author|obfuscate#</td></tr>
@@ -3,6 +3,7 b' Content-type: text/html'
3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4 <html>
4 <html>
5 <head>
5 <head>
6 <meta name="robots" content="index, nofollow" />
6 <style type="text/css">
7 <style type="text/css">
7 <!--
8 <!--
8 a { text-decoration:none; }
9 a { text-decoration:none; }
@@ -10,7 +10,7 b''
10 </div>
10 </div>
11
11
12 <div class="page_nav">
12 <div class="page_nav">
13 <a href="?cmd=summary;style=gitweb">summary</a> | <a href="?cmd=changelog;style=gitweb">changelog</a> | <a href="?cmd=tags;style=gitweb">tags</a> | manifest | <a href="?cs=#node|short#;style=gitweb">changeset</a><br/>
13 <a href="?cmd=summary;style=gitweb">summary</a> | <a href="?cmd=changelog;style=gitweb">changelog</a> | <a href="?cmd=tags;style=gitweb">tags</a> | manifest | <a href="?cs=#node|short#;style=gitweb">changeset</a> #archives%archiveentry#<br/>
14 </div>
14 </div>
15
15
16 <div class="title" >#path|escape#</div>
16 <div class="title" >#path|escape#</div>
@@ -18,7 +18,7 b''
18 <table cellspacing="0">
18 <table cellspacing="0">
19 <tr class="light">
19 <tr class="light">
20 <td style="font-family:monospace">drwxr-xr-x</td>
20 <td style="font-family:monospace">drwxr-xr-x</td>
21 <td><a href="?cmd=manifest;manifest=#manifest#;path=#up#;style=gitweb">[up]</a></td>
21 <td><a href="?cmd=manifest;manifest=#manifest#;path=#up|urlescape#;style=gitweb">[up]</a></td>
22 <td class="link">&nbsp;</td>
22 <td class="link">&nbsp;</td>
23 </tr>
23 </tr>
24 #dentries%manifestdirentry#
24 #dentries%manifestdirentry#
@@ -10,12 +10,12 b''
10 #archives%archiveentry#
10 #archives%archiveentry#
11 </div>
11 </div>
12
12
13 <h2>manifest for changeset #node|short#: #path#</h2>
13 <h2>manifest for changeset #node|short#: #path|escape#</h2>
14
14
15 <table cellpadding="0" cellspacing="0">
15 <table cellpadding="0" cellspacing="0">
16 <tr class="parity1">
16 <tr class="parity1">
17 <td><tt>drwxr-xr-x</tt>&nbsp;
17 <td><tt>drwxr-xr-x</tt>&nbsp;
18 <td><a href="?mf=#manifest|short#;path=#up#">[up]</a>
18 <td><a href="?mf=#manifest|short#;path=#up|urlescape#">[up]</a>
19 #dentries%manifestdirentry#
19 #dentries%manifestdirentry#
20 #fentries%manifestfileentry#
20 #fentries%manifestfileentry#
21 </table>
21 </table>
@@ -3,16 +3,16 b' header = header.tmpl'
3 footer = footer.tmpl
3 footer = footer.tmpl
4 search = search.tmpl
4 search = search.tmpl
5 changelog = changelog.tmpl
5 changelog = changelog.tmpl
6 naventry = "<a href="?cl=#rev#">#label#</a> "
6 naventry = "<a href="?cl=#rev#">#label|escape#</a> "
7 filedifflink = "<a href="?fd=#node|short#;file=#file#">#file#</a> "
7 filedifflink = "<a href="?fd=#node|short#;file=#file|urlescape#">#file|escape#</a> "
8 filenodelink = "<a href="?f=#filenode|short#;file=#file#">#file#</a> "
8 filenodelink = "<a href="?f=#filenode|short#;file=#file|urlescape#">#file|escape#</a> "
9 fileellipses = "..."
9 fileellipses = "..."
10 changelogentry = changelogentry.tmpl
10 changelogentry = changelogentry.tmpl
11 searchentry = changelogentry.tmpl
11 searchentry = changelogentry.tmpl
12 changeset = changeset.tmpl
12 changeset = changeset.tmpl
13 manifest = manifest.tmpl
13 manifest = manifest.tmpl
14 manifestdirentry = "<tr class="parity#parity#"><td><tt>drwxr-xr-x</tt>&nbsp;<td><a href="?cmd=manifest;manifest=#manifest#;path=#path#">#basename#/</a>"
14 manifestdirentry = "<tr class="parity#parity#"><td><tt>drwxr-xr-x</tt>&nbsp;<td><a href="?cmd=manifest;manifest=#manifest#;path=#path|urlescape#">#basename|escape#/</a>"
15 manifestfileentry = "<tr class="parity#parity#"><td><tt>#permissions|permissions#</tt>&nbsp;<td><a href="?f=#filenode|short#;file=#file#">#basename#</a>"
15 manifestfileentry = "<tr class="parity#parity#"><td><tt>#permissions|permissions#</tt>&nbsp;<td><a href="?f=#filenode|short#;file=#file|urlescape#">#basename|escape#</a>"
16 filerevision = filerevision.tmpl
16 filerevision = filerevision.tmpl
17 fileannotate = fileannotate.tmpl
17 fileannotate = fileannotate.tmpl
18 filediff = filediff.tmpl
18 filediff = filediff.tmpl
@@ -26,17 +26,25 b' difflineat = "<span class="atline">#line'
26 diffline = "#line|escape#"
26 diffline = "#line|escape#"
27 changelogparent = "<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cs=#node|short#">#node|short#</a></td></tr>"
27 changelogparent = "<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cs=#node|short#">#node|short#</a></td></tr>"
28 changesetparent = "<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cs=#node|short#">#node|short#</a></td></tr>"
28 changesetparent = "<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cs=#node|short#">#node|short#</a></td></tr>"
29 filerevparent = "<tr><td class="metatag">parent:</td><td><a href="?f=#node|short#;file=#file#">#node|short#</a></td></tr>"
29 filerevparent = "<tr><td class="metatag">parent:</td><td><a href="?f=#node|short#;file=#file|urlescape#">#node|short#</a></td></tr>"
30 fileannotateparent = "<tr><td class="metatag">parent:</td><td><a href="?fa=#filenode|short#;file=#file#">#node|short#</a></td></tr>"
30 filerename = "<tr><td class="metatag">parent:</td><td><a href="?f=#node|short#;file=#file|urlescape#">#file|escape#@#node|short#</a></td></tr>"
31 filelogrename = "<tr><td align="right">base:&nbsp;</td><td><a href="?f=#node|short#;file=#file|urlescape#">#file|escape#@#node|short#</a></td></tr>"
32 fileannotateparent = "<tr><td class="metatag">parent:</td><td><a href="?fa=#filenode|short#;file=#file|urlescape#">#node|short#</a></td></tr>"
33 changesetchild = "<tr><th class="child">child #rev#:</th><td class="child"><a href="?cs=#node|short#">#node|short#</a></td></tr>"
34 changelogchild = "<tr><th class="child">child #rev#:</th><td class="child"><a href="?cs=#node|short#">#node|short#</a></td></tr>"
35 filerevchild = "<tr><td class="metatag">child:</td><td><a href="?f=#node|short#;file=#file|urlescape#">#node|short#</a></td></tr>"
36 fileannotatechild = "<tr><td class="metatag">child:</td><td><a href="?fa=#filenode|short#;file=#file|urlescape#">#node|short#</a></td></tr>"
31 tags = tags.tmpl
37 tags = tags.tmpl
32 tagentry = "<li class="tagEntry parity#parity#"><span class="node">#node#</span> <a href="?cs=#node|short#">#tag#</a></li>"
38 tagentry = "<li class="tagEntry parity#parity#"><span class="node">#node#</span> <a href="?cs=#node|short#">#tag|escape#</a></li>"
33 diffblock = "<pre class="parity#parity#">#lines#</pre>"
39 diffblock = "<pre class="parity#parity#">#lines#</pre>"
34 changelogtag = "<tr><th class="tag">tag:</th><td class="tag">#tag#</td></tr>"
40 changelogtag = "<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>"
35 changesettag = "<tr><th class="tag">tag:</th><td class="tag">#tag#</td></tr>"
41 changesettag = "<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>"
36 filediffparent = "<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cs=#node|short#">#node|short#</a></td></tr>"
42 filediffparent = "<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cs=#node|short#">#node|short#</a></td></tr>"
37 filelogparent = "<tr><td align="right">parent #rev#:&nbsp;</td><td><a href="?f=#node|short#;file=#file#">#node|short#</a></td></tr>"
43 filelogparent = "<tr><td align="right">parent #rev#:&nbsp;</td><td><a href="?f=#node|short#;file=#file|urlescape#">#node|short#</a></td></tr>"
38 indexentry = "<tr class="parity#parity#"><td><a href="#url#">#name#</a></td><td>#shortdesc#</td><td>#contact|obfuscate#</td><td>#lastupdate|age# ago</td><td><a href="#url#?cl=tip;style=rss">RSS</a></td></tr>"
44 filediffchild = "<tr><th class="child">child #rev#:</th><td class="child"><a href="?cs=#node|short#">#node|short#</a></td></tr>"
45 filelogchild = "<tr><td align="right">child #rev#:&nbsp;</td><td><a href="?f=#node|short#;file=#file|urlescape#">#node|short#</a></td></tr>"
46 indexentry = "<tr class="parity#parity#"><td><a href="#url#">#name|escape#</a></td><td>#shortdesc|escape#</td><td>#contact|obfuscate#</td><td>#lastupdate|age# ago</td><td><a href="#url#?cl=tip;style=rss">RSS</a></td></tr>"
39 index = index.tmpl
47 index = index.tmpl
40 archiveentry = "<a href="?ca=#node|short#;type=#type#">#type#</a> "
48 archiveentry = "<a href="?ca=#node|short#;type=#type|urlescape#">#type|escape#</a> "
41 notfound = notfound.tmpl
49 notfound = notfound.tmpl
42 error = error.tmpl
50 error = error.tmpl
@@ -5,17 +5,17 b' search = search-gitweb.tmpl'
5 changelog = changelog-gitweb.tmpl
5 changelog = changelog-gitweb.tmpl
6 summary = summary-gitweb.tmpl
6 summary = summary-gitweb.tmpl
7 error = error-gitweb.tmpl
7 error = error-gitweb.tmpl
8 naventry = "<a href="?cmd=changelog;rev=#rev#;style=gitweb">#label#</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#</a> "
9 navshortentry = "<a href="?cmd=shortlog;rev=#rev#;style=gitweb">#label|escape#</a> "
10 filedifflink = "<a href="?cmd=filediff;node=#node#;file=#file#;style=gitweb">#file#</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#</a></td><td></td><td class="link"><a href="?cmd=file;filenode=#filenode#;file=#file#;style=gitweb">file</a> | <!-- FIXME: <a href="?fd=#filenode|short#;file=#file#;style=gitweb">diff</a> | --> <a href="?cmd=filelog;filenode=#filenode|short#;file=#file#;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> | <!-- 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
15 changeset = changeset-gitweb.tmpl
15 changeset = changeset-gitweb.tmpl
16 manifest = manifest-gitweb.tmpl
16 manifest = manifest-gitweb.tmpl
17 manifestdirentry = "<tr class="parity#parity#"><td style="font-family:monospace">drwxr-xr-x</td><td><a href="?mf=#manifest|short#;path=#path#;style=gitweb">#basename#/</a></td><td class="link"><a href="?mf=#manifest|short#;path=#path#;style=gitweb">manifest</a></td></tr>"
17 manifestdirentry = "<tr class="parity#parity#"><td style="font-family:monospace">drwxr-xr-x</td><td><a href="?mf=#manifest|short#;path=#path|urlescape#;style=gitweb">#basename|escape#/</a></td><td class="link"><a href="?mf=#manifest|short#;path=#path|urlescape#;style=gitweb">manifest</a></td></tr>"
18 manifestfileentry = "<tr class="parity#parity#"><td style="font-family:monospace">#permissions|permissions#</td><td class="list"><a class="list" href="?f=#filenode|short#;file=#file#;style=gitweb">#basename#</a></td><td class="link"><a href="?f=#filenode|short#;file=#file#;style=gitweb">file</a> | <a href="?fl=#filenode|short#;file=#file#;style=gitweb">revisions</a> | <a href="?fa=#filenode|short#;file=#file#;style=gitweb">annotate</a></td></tr>"
18 manifestfileentry = "<tr class="parity#parity#"><td style="font-family:monospace">#permissions|permissions#</td><td class="list"><a class="list" href="?f=#filenode|short#;file=#file|urlescape#;style=gitweb">#basename|escape#</a></td><td class="link"><a href="?f=#filenode|short#;file=#file|urlescape#;style=gitweb">file</a> | <a href="?fl=#filenode|short#;file=#file|urlescape#;style=gitweb">revisions</a> | <a href="?fa=#filenode|short#;file=#file|urlescape#;style=gitweb">annotate</a></td></tr>"
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
@@ -28,15 +28,22 b' difflineat = "<div class="pre" style="co'
28 diffline = "<div class="pre">#line|escape#</div>"
28 diffline = "<div class="pre">#line|escape#</div>"
29 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 changelogparent = "<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cmd=changeset;node=#node#;style=gitweb">#node|short#</a></td></tr>"
30 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 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>"
31 filerevparent = "<tr><td class="metatag">parent:</td><td><a href="?cmd=file;file=#file#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>"
31 filerevparent = "<tr><td class="metatag">parent:</td><td><a href="?cmd=file;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>"
32 fileannotateparent = "<tr><td class="metatag">parent:</td><td><a href="?cmd=annotate;file=#file#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>"
32 fileannotateparent = "<tr><td class="metatag">parent:</td><td><a href="?cmd=annotate;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>"
33 changelogchild = "<tr><th class="child">child #rev#:</th><td class="child"><a href="?cmd=changeset;node=#node#;style=gitweb">#node|short#</a></td></tr>"
34 changesetchild = "<tr><td>child</td><td style="font-family:monospace"><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb">#node|short#</a></td></tr>"
35 filerevchild = "<tr><td class="metatag">child:</td><td><a href="?cmd=file;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>"
36 fileannotatechild = "<tr><td class="metatag">child:</td><td><a href="?cmd=annotate;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>"
33 tags = tags-gitweb.tmpl
37 tags = tags-gitweb.tmpl
34 tagentry = "<tr class="parity#parity#"><td><i>#date|age# ago</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#tag#</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>"
38 tagentry = "<tr class="parity#parity#"><td><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>"
35 diffblock = "#lines#"
39 diffblock = "#lines#"
36 changelogtag = "<tr><th class="tag">tag:</th><td class="tag">#tag#</td></tr>"
40 changelogtag = "<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>"
37 changesettag = "<tr><td>tag</td><td>#tag#</td></tr>"
41 changesettag = "<tr><td>tag</td><td>#tag|escape#</td></tr>"
38 filediffparent = "<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cmd=changeset;node=#node#;style=gitweb">#node|short#</a></td></tr>"
42 filediffparent = "<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="?cmd=changeset;node=#node#;style=gitweb">#node|short#</a></td></tr>"
39 filelogparent = "<tr><td align="right">parent #rev#:&nbsp;</td><td><a href="?cmd=file;file=#file#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>"
43 filelogparent = "<tr><td align="right">parent #rev#:&nbsp;</td><td><a href="?cmd=file;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>"
44 filediffchild = "<tr><th class="child">child #rev#:</th><td class="child"><a href="?cmd=changeset;node=#node#;style=gitweb">#node|short#</a></td></tr>"
45 filelogchild = "<tr><td align="right">child #rev#:&nbsp;</td><td><a href="?cmd=file;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>"
40 shortlog = shortlog-gitweb.tmpl
46 shortlog = shortlog-gitweb.tmpl
41 shortlogentry = "<tr class="parity#parity#"><td><i>#date|age# ago</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#desc|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>"
47 shortlogentry = "<tr class="parity#parity#"><td><i>#date|age# ago</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#desc|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>"
42 filelogentry = "<tr class="parity#parity#"><td><i>#date|age# ago</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#desc|firstline|escape#</b></a></td><td class="link"><!-- FIXME: <a href="?fd=#node|short#;file=#file#;style=gitweb">diff</a> | --> <a href="?fa=#filenode|short#;file=#file#;style=gitweb">annotate</a></td></tr>"
48 filelogentry = "<tr class="parity#parity#"><td><i>#date|age# ago</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#desc|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></td></tr>"
49 archiveentry = " | <a href="?ca=#node|short#;type=#type|urlescape#">#type|escape#</a> "
@@ -1,14 +1,15 b''
1 header = header-raw.tmpl
1 header = header-raw.tmpl
2 footer = ""
2 footer = ""
3 changeset = changeset-raw.tmpl
3 changeset = changeset-raw.tmpl
4 annotateline = "<tr class="parity#parity#"><td class="annotate"><a href="?cmd=changeset;node=#node#">#author#@#rev#</a></td><td><pre>#line#</pre></td></tr>"
4 annotateline = "<tr class="parity#parity#"><td class="annotate"><a href="?cmd=changeset;node=#node#">#author#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>"
5 difflineplus = "#line#"
5 difflineplus = "#line|escape#"
6 difflineminus = "#line#"
6 difflineminus = "#line|escape#"
7 difflineat = "#line#"
7 difflineat = "#line|escape#"
8 diffline = "#line#"
8 diffline = "#line|escape#"
9 changesetparent = "# parent: #node#"
9 changesetparent = "# parent: #node#"
10 filenodelink = "#file#"
10 changesetchild = "# child: #node#"
11 filenodelink = "#file|urlescape#"
11 filerevision = filerevision-raw.tmpl
12 filerevision = filerevision-raw.tmpl
12 fileline = "#line#"
13 fileline = "#line|escape#"
13 diffblock = "#lines#"
14 diffblock = "#lines#"
14 filediff = filediff-raw.tmpl
15 filediff = filediff-raw.tmpl
@@ -14,8 +14,8 b' summary | <a href="?cmd=changelog;style='
14
14
15 <div class="title">&nbsp;</div>
15 <div class="title">&nbsp;</div>
16 <table cellspacing="0">
16 <table cellspacing="0">
17 <tr><td>description</td><td>#desc#</td></tr>
17 <tr><td>description</td><td>#desc|escape#</td></tr>
18 <tr><td>owner</td><td>#owner#</td></tr>
18 <tr><td>owner</td><td>#owner|escape#</td></tr>
19 <!-- <tr><td>last change</td><td>#lastchange|rfc822date#</td></tr> -->
19 <!-- <tr><td>last change</td><td>#lastchange|rfc822date#</td></tr> -->
20 </table>
20 </table>
21
21
@@ -18,6 +18,7 b' desc a description (escaped, wi'
18 shortdesc a short description (escaped)
18 shortdesc a short description (escaped)
19 author a name or email addressv(obfuscated)
19 author a name or email addressv(obfuscated)
20 parent a list of the parent
20 parent a list of the parent
21 child a list of the children
21 tags a list of tag
22 tags a list of tag
22
23
23 header the global page header
24 header the global page header
@@ -3,5 +3,5 b' adding b'
3 0
3 0
4 0
4 0
5 0
5 0
6 a: No such file in rev 551e7cb14b32
6 a: No such file in rev 7040230c159c
7 1
7 1
@@ -64,7 +64,7 b' list of commands (use "hg help -v" to sh'
64 paths show definition of symbolic path names
64 paths show definition of symbolic path names
65 pull pull changes from the specified source
65 pull pull changes from the specified source
66 push push changes to the specified destination
66 push push changes to the specified destination
67 rawcommit raw commit interface
67 rawcommit raw commit interface (DEPRECATED)
68 recover roll back an interrupted transaction
68 recover roll back an interrupted transaction
69 remove remove the specified files on the next commit
69 remove remove the specified files on the next commit
70 rename rename files; equivalent of copy + remove
70 rename rename files; equivalent of copy + remove
@@ -106,7 +106,7 b' list of commands (use "hg help -v" to sh'
106 paths show definition of symbolic path names
106 paths show definition of symbolic path names
107 pull pull changes from the specified source
107 pull pull changes from the specified source
108 push push changes to the specified destination
108 push push changes to the specified destination
109 rawcommit raw commit interface
109 rawcommit raw commit interface (DEPRECATED)
110 recover roll back an interrupted transaction
110 recover roll back an interrupted transaction
111 remove remove the specified files on the next commit
111 remove remove the specified files on the next commit
112 rename rename files; equivalent of copy + remove
112 rename rename files; equivalent of copy + remove
@@ -186,6 +186,7 b' show changed files in the working direct'
186 M = modified
186 M = modified
187 A = added
187 A = added
188 R = removed
188 R = removed
189 ! = deleted, but still tracked
189 ? = not tracked
190 ? = not tracked
190
191
191 aliases: st
192 aliases: st
@@ -195,6 +196,7 b' options:'
195 -m --modified show only modified files
196 -m --modified show only modified files
196 -a --added show only added files
197 -a --added show only added files
197 -r --removed show only removed files
198 -r --removed show only removed files
199 -d --deleted show only deleted (but tracked) files
198 -u --unknown show only unknown (not tracked) files
200 -u --unknown show only unknown (not tracked) files
199 -n --no-status hide status prefix
201 -n --no-status hide status prefix
200 -0 --print0 end filenames with NUL, for use with xargs
202 -0 --print0 end filenames with NUL, for use with xargs
@@ -5,14 +5,14 b' A dir/b.o'
5 ? dir/c.o
5 ? dir/c.o
6 ? syntax
6 ? syntax
7 --
7 --
8 abort: invalid pattern: relre:*.o
8 abort: .hgignore: invalid pattern (relre): *.o
9 --
9 --
10 A dir/b.o
10 A dir/b.o
11 ? .hgignore
11 ? .hgignore
12 ? a.c
12 ? a.c
13 ? syntax
13 ? syntax
14 --
14 --
15 ignoring invalid syntax 'invalid'
15 .hgignore: ignoring invalid syntax 'invalid'
16 A dir/b.o
16 A dir/b.o
17 ? .hgignore
17 ? .hgignore
18 ? a.c
18 ? a.c
@@ -11,7 +11,7 b' merging file1 failed!'
11 diff -r f4d7a8c73d23 file1
11 diff -r f4d7a8c73d23 file1
12 --- a/file1
12 --- a/file1
13 +++ b/file1
13 +++ b/file1
14 @@ -1,3 +1,7 @@
14 @@ -1,3 +1,7 @@ added file1
15 added file1
15 added file1
16 another line of text
16 another line of text
17 +<<<<<<<
17 +<<<<<<<
@@ -1,5 +1,6 b''
1 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
1 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
2 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
2 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
3 (the rawcommit command is deprecated)
3 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
4 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
4 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
5 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
5 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
6 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
@@ -9,6 +10,7 b' user: test'
9 date: Thu Jan 1 00:00:00 1970 +0000
10 date: Thu Jan 1 00:00:00 1970 +0000
10 summary: 2
11 summary: 2
11
12
13 (the rawcommit command is deprecated)
12 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
14 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
13 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
15 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
14 changeset: 3:142428fbbcc5
16 changeset: 3:142428fbbcc5
@@ -17,6 +19,7 b' user: test'
17 date: Thu Jan 1 00:00:00 1970 +0000
19 date: Thu Jan 1 00:00:00 1970 +0000
18 summary: 3
20 summary: 3
19
21
22 (the rawcommit command is deprecated)
20 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
23 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
21 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
24 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
22 changeset: 4:4d450f9aa680
25 changeset: 4:4d450f9aa680
@@ -25,6 +28,7 b' user: test'
25 date: Thu Jan 1 00:00:00 1970 +0000
28 date: Thu Jan 1 00:00:00 1970 +0000
26 summary: 4
29 summary: 4
27
30
31 (the rawcommit command is deprecated)
28 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
32 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
29 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
33 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
30 3570202ceac2b52517df64ebd0a062cb0d8fe33a 644 c
34 3570202ceac2b52517df64ebd0a062cb0d8fe33a 644 c
@@ -33,6 +37,7 b' user: test'
33 date: Thu Jan 1 00:00:00 1970 +0000
37 date: Thu Jan 1 00:00:00 1970 +0000
34 summary: 4
38 summary: 4
35
39
40 (the rawcommit command is deprecated)
36 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
41 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
37 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
42 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
38 changeset: 6:b4b8b9afa8cc
43 changeset: 6:b4b8b9afa8cc
@@ -43,6 +48,7 b' user: test'
43 date: Thu Jan 1 00:00:00 1970 +0000
48 date: Thu Jan 1 00:00:00 1970 +0000
44 summary: 6
49 summary: 6
45
50
51 (the rawcommit command is deprecated)
46 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
52 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
47 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
53 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
48 changeset: 7:f84d0b1b024e
54 changeset: 7:f84d0b1b024e
@@ -11,11 +11,11 b' diff -r 000000000000 -r b51ca55c2035 foo'
11 +a
11 +a
12 # HG changeset patch
12 # HG changeset patch
13 # User test
13 # User test
14 # Node ID 1e555b9b85c52e1e9e8175446f1ede507b2d1ebb
14 # Node ID 451c12a24e5a7336921b8d93e280837d7c2b4fc1
15 # Parent b51ca55c20354097ca299529d18b5cd356976ba2
15 # Parent b51ca55c20354097ca299529d18b5cd356976ba2
16 2
16 2
17
17
18 diff -r b51ca55c2035 -r 1e555b9b85c5 foo
18 diff -r b51ca55c2035 -r 451c12a24e5a foo
19 --- a/foo Thu Jan 1 00:00:00 1970 +0000
19 --- a/foo Thu Jan 1 00:00:00 1970 +0000
20 +++ /dev/null Thu Jan 1 00:00:00 1970 +0000
20 +++ /dev/null Thu Jan 1 00:00:00 1970 +0000
21 @@ -1,1 +0,0 @@
21 @@ -1,1 +0,0 @@
@@ -32,13 +32,13 b' diff -r 000000000000 -r b51ca55c2035 foo'
32 +a
32 +a
33
33
34
34
35 changeset: 1:1e555b9b85c5
35 changeset: 1:451c12a24e5a
36 tag: tip
36 tag: tip
37 user: test
37 user: test
38 date: Thu Jan 1 00:00:00 1970 +0000
38 date: Thu Jan 1 00:00:00 1970 +0000
39 summary: 2
39 summary: 2
40
40
41 diff -r b51ca55c2035 -r 1e555b9b85c5 foo
41 diff -r b51ca55c2035 -r 451c12a24e5a foo
42 --- a/foo Thu Jan 1 00:00:00 1970 +0000
42 --- a/foo Thu Jan 1 00:00:00 1970 +0000
43 +++ /dev/null Thu Jan 1 00:00:00 1970 +0000
43 +++ /dev/null Thu Jan 1 00:00:00 1970 +0000
44 @@ -1,1 +0,0 @@
44 @@ -1,1 +0,0 @@
@@ -134,3 +134,27 b' mkdir d3'
134 hg rename d1/* d2/* d3
134 hg rename d1/* d2/* d3
135 hg status
135 hg status
136 hg update -C
136 hg update -C
137
138 echo "# move a whole subtree with \"hg rename .\""
139 mkdir d3
140 (cd d1; hg rename . ../d3)
141 hg status
142 hg update -C
143
144 echo "# move a whole subtree with \"hg rename --after .\""
145 mkdir d3
146 mv d1/* d3
147 (cd d1; hg rename --after . ../d3)
148 hg status
149 hg update -C
150
151 echo "# move the parent tree with \"hg rename ..\""
152 (cd d1/d11; hg rename .. ../../d3)
153 hg status
154 hg update -C
155
156 echo "# skip removed files"
157 hg remove d1/b
158 hg rename d1 d3
159 hg status
160 hg update -C
@@ -181,3 +181,68 b' R d1/a'
181 R d1/b
181 R d1/b
182 R d1/ba
182 R d1/ba
183 R d1/d11/a1
183 R d1/d11/a1
184 # move a whole subtree with "hg rename ."
185 copying a to ../d3/d1/a
186 copying b to ../d3/d1/b
187 copying ba to ../d3/d1/ba
188 copying d11/a1 to ../d3/d1/d11/a1
189 removing a
190 removing b
191 removing ba
192 removing d11/a1
193 A d3/d1/a
194 A d3/d1/b
195 A d3/d1/ba
196 A d3/d1/d11/a1
197 R d1/a
198 R d1/b
199 R d1/ba
200 R d1/d11/a1
201 # move a whole subtree with "hg rename --after ."
202 copying a to ../d3/a
203 copying b to ../d3/b
204 copying ba to ../d3/ba
205 copying d11/a1 to ../d3/d11/a1
206 removing a
207 removing b
208 removing ba
209 removing d11/a1
210 A d3/a
211 A d3/b
212 A d3/ba
213 A d3/d11/a1
214 R d1/a
215 R d1/b
216 R d1/ba
217 R d1/d11/a1
218 # move the parent tree with "hg rename .."
219 copying ../a to ../../d3/a
220 copying ../b to ../../d3/b
221 copying ../ba to ../../d3/ba
222 copying a1 to ../../d3/d11/a1
223 removing ../a
224 removing ../b
225 removing ../ba
226 removing a1
227 A d3/a
228 A d3/b
229 A d3/ba
230 A d3/d11/a1
231 R d1/a
232 R d1/b
233 R d1/ba
234 R d1/d11/a1
235 # skip removed files
236 copying d1/a to d3/a
237 copying d1/ba to d3/ba
238 copying d1/d11/a1 to d3/d11/a1
239 removing d1/a
240 removing d1/ba
241 removing d1/d11/a1
242 A d3/a
243 A d3/ba
244 A d3/d11/a1
245 R d1/a
246 R d1/b
247 R d1/ba
248 R d1/d11/a1
@@ -1,7 +1,7 b''
1 %% Should show unknown
1 %% Should show unknown
2 ? unknown
2 ? unknown
3 %% Should show unknown and b removed
3 %% Should show unknown and b removed
4 R b
4 ! b
5 ? unknown
5 ? unknown
6 %% Should show a and unknown
6 %% Should show a and unknown
7 a
7 a
@@ -3,9 +3,9 b' adding bomb'
3 adding a.c
3 adding a.c
4 adding dir/a.o
4 adding dir/a.o
5 adding dir/b.o
5 adding dir/b.o
6 R a.c
6 ! a.c
7 R dir/a.o
7 ! dir/a.o
8 R dir/b.o
8 ! dir/b.o
9 ? .hgignore
9 ? .hgignore
10 a.c: unsupported file type (type is fifo)
10 a.c: unsupported file type (type is fifo)
11 R a.c
11 ! a.c
@@ -10,6 +10,14 b' hg history'
10
10
11 echo foo >> .hgtags
11 echo foo >> .hgtags
12 hg tag -d "0 0" "bleah2" || echo "failed"
12 hg tag -d "0 0" "bleah2" || echo "failed"
13 hg tag -d "0 0" -r 0 "bleah2" 1 || echo "failed"
14
15 hg revert .hgtags
16 hg tag -d "0 0" -r 0 "bleah0"
17 hg tag -l -d "0 0" "bleah1" 1
18
19 cat .hgtags
20 cat .hg/localtags
13
21
14 hg tag -l 'xx
22 hg tag -l 'xx
15 newline'
23 newline'
@@ -18,5 +18,12 b' summary: test'
18
18
19 abort: working copy of .hgtags is changed (please commit .hgtags manually)
19 abort: working copy of .hgtags is changed (please commit .hgtags manually)
20 failed
20 failed
21 use of 'hg tag NAME [REV]' is deprecated, please use 'hg tag [-r REV] NAME' instead
22 abort: use only one form to specify the revision
23 failed
24 use of 'hg tag NAME [REV]' is deprecated, please use 'hg tag [-r REV] NAME' instead
25 acb14030fe0a21b60322c440ad2d20cf7685a376 bleah
26 acb14030fe0a21b60322c440ad2d20cf7685a376 bleah0
27 863197ef03781c4fc00276d83eb66c4cb9cd91df bleah1
21 abort: '\n' cannot be used in a tag name
28 abort: '\n' cannot be used in a tag name
22 abort: ':' cannot be used in a tag name
29 abort: ':' cannot be used in a tag name
@@ -24,11 +24,34 b' hg commit -m "2" -d "0 0"'
24 cd ../r2
24 cd ../r2
25 hg -q pull ../r1
25 hg -q pull ../r1
26 hg status
26 hg status
27 hg parents
27 hg --debug up
28 hg --debug up
29 hg parents
30 hg --debug up 0
31 hg parents
28 hg --debug up -m || echo failed
32 hg --debug up -m || echo failed
29 hg --debug up -f -m
33 hg parents
34 hg --debug up
30 hg parents
35 hg parents
31 hg -v history
36 hg -v history
32 hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \
37 hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \
33 -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/"
38 -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/"
34
39
40 # create a second head
41 cd ../r1
42 hg up 0
43 echo b2 > b
44 echo a3 > a
45 hg addremove
46 hg commit -m "3" -d "0 0"
47
48 cd ../r2
49 hg -q pull ../r1
50 hg status
51 hg parents
52 hg --debug up || echo failed
53 hg --debug up -m || echo failed
54 hg --debug up -f -m
55 hg parents
56 hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \
57 -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/"
@@ -2,11 +2,16 b' adding a'
2 diff -r c19d34741b0a a
2 diff -r c19d34741b0a a
3 --- a/a
3 --- a/a
4 +++ b/a
4 +++ b/a
5 @@ -1,1 +1,1 @@
5 @@ -1,1 +1,1 @@ a
6 -a
6 -a
7 +abc
7 +abc
8 adding b
8 adding b
9 M a
9 M a
10 changeset: 0:c19d34741b0a
11 user: test
12 date: Thu Jan 1 00:00:00 1970 +0000
13 summary: 1
14
10 resolving manifests
15 resolving manifests
11 force None allow None moddirstate True linear True
16 force None allow None moddirstate True linear True
12 ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e
17 ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e
@@ -16,11 +21,38 b' getting b'
16 merging a
21 merging a
17 resolving a
22 resolving a
18 file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
23 file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
19 abort: outstanding uncommited changes
24 changeset: 1:1e71731e6fbb
20 failed
25 tag: tip
26 user: test
27 date: Thu Jan 1 00:00:00 1970 +0000
28 summary: 2
29
21 resolving manifests
30 resolving manifests
22 force None allow 1 moddirstate True linear True
31 force None allow None moddirstate True linear True
23 ancestor 1165e8bd193e local 1165e8bd193e remote 1165e8bd193e
32 ancestor a0c8bcbbb45c local 1165e8bd193e remote a0c8bcbbb45c
33 remote deleted b
34 removing b
35 changeset: 0:c19d34741b0a
36 user: test
37 date: Thu Jan 1 00:00:00 1970 +0000
38 summary: 1
39
40 abort: there is nothing to merge, just use 'hg update'
41 failed
42 changeset: 0:c19d34741b0a
43 user: test
44 date: Thu Jan 1 00:00:00 1970 +0000
45 summary: 1
46
47 resolving manifests
48 force None allow None moddirstate True linear True
49 ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e
50 a versions differ, resolve
51 remote created b
52 getting b
53 merging a
54 resolving a
55 file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
24 changeset: 1:1e71731e6fbb
56 changeset: 1:1e71731e6fbb
25 tag: tip
57 tag: tip
26 user: test
58 user: test
@@ -47,6 +79,55 b' 1'
47 diff -r 1e71731e6fbb a
79 diff -r 1e71731e6fbb a
48 --- a/a
80 --- a/a
49 +++ b/a
81 +++ b/a
50 @@ -1,1 +1,1 @@
82 @@ -1,1 +1,1 @@ a2
51 -a2
83 -a2
52 +abc
84 +abc
85 adding b
86 M a
87 changeset: 1:1e71731e6fbb
88 user: test
89 date: Thu Jan 1 00:00:00 1970 +0000
90 summary: 2
91
92 resolving manifests
93 force None allow None moddirstate True linear False
94 ancestor a0c8bcbbb45c local 1165e8bd193e remote 4096f2872392
95 a versions differ, resolve
96 b versions differ, resolve
97 this update spans a branch affecting the following files:
98 a (resolve)
99 b (resolve)
100 aborting update spanning branches!
101 (use update -m to merge across branches or -C to lose changes)
102 failed
103 abort: outstanding uncommited changes
104 failed
105 resolving manifests
106 force None allow 1 moddirstate True linear False
107 ancestor a0c8bcbbb45c local 1165e8bd193e remote 4096f2872392
108 a versions differ, resolve
109 b versions differ, resolve
110 merging a
111 resolving a
112 file a: my d730145abbf9 other 13e0d5f949fa ancestor b789fdd96dc2
113 merging b
114 resolving b
115 file b: my 1e88685f5dde other 61de8c7723ca ancestor 000000000000
116 changeset: 1:1e71731e6fbb
117 user: test
118 date: Thu Jan 1 00:00:00 1970 +0000
119 summary: 2
120
121 changeset: 2:83c51d0caff4
122 tag: tip
123 parent: 0:c19d34741b0a
124 user: test
125 date: Thu Jan 1 00:00:00 1970 +0000
126 summary: 3
127
128 diff -r 1e71731e6fbb a
129 --- a/a
130 +++ b/a
131 @@ -1,1 +1,1 @@ a2
132 -a2
133 +abc
General Comments 0
You need to be logged in to leave comments. Login now