Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/commands.py @ 249:619e775aa7f9
import and startup cleanups
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
import and startup cleanups
add commands:run()
add copyright notice to commands
eliminate/reorganize imports to speed up start time:
0.5b:
$ time bash -c 'for i in `seq 100`; do ~/bin/hg > /dev/null; done'
real 0m7.718s
user 0m6.719s
sys 0m0.794s
new:
$ time bash -c 'for i in `seq 100`; do hg > /dev/null; done'
real 0m2.171s
user 0m1.684s
sys 0m0.444s
just python:
$ time bash -c 'for i in `seq 100`; do python -c pass; done'
real 0m0.988s
user 0m0.771s
sys 0m0.207s
Ignoring the fixed cost of loading the Python interpreter, we're 5.6
times faster. With the Python load time, we're still 3.5 times faster.
manifest hash: acce5882a55c76eb165316f5741724c8ce4ef587
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCoihAywK+sNU5EO8RAqMdAJwMe6Ur0R9G6jjayNa5hH2C3c4k/gCeIYvc
N178vaWWGciX9zq+g5qCAls=
=buhv
-----END PGP SIGNATURE-----
author | mpm@selenic.com |
---|---|
date | Sat, 04 Jun 2005 14:16:32 -0800 |
parents | b7645b3c86ff |
children | 45ee7c4cae4f |
rev | line source |
---|---|
249 | 1 # commands.py - command processing for mercurial |
2 # | |
3 # Copyright 2005 Matt Mackall <mpm@selenic.com> | |
4 # | |
5 # This software may be used and distributed according to the terms | |
6 # of the GNU General Public License, incorporated herein by reference. | |
7 | |
8 import os, re, sys, signal, time, mdiff | |
209 | 9 from mercurial import fancyopts, ui, hg |
10 | |
11 class UnknownCommand(Exception): pass | |
12 | |
245 | 13 def filterfiles(filters, files): |
14 l = [ x for x in files if x in filters ] | |
213 | 15 |
245 | 16 for t in filters: |
17 if t and t[-1] != os.sep: t += os.sep | |
18 l += [ x for x in files if x.startswith(t) ] | |
213 | 19 return l |
20 | |
245 | 21 def relfilter(repo, files): |
213 | 22 if os.getcwd() != repo.root: |
23 p = os.getcwd()[len(repo.root) + 1: ] | |
245 | 24 return filterfiles(p, files) |
25 return files | |
213 | 26 |
209 | 27 def relpath(repo, args): |
28 if os.getcwd() != repo.root: | |
29 p = os.getcwd()[len(repo.root) + 1: ] | |
245 | 30 return [ os.path.normpath(os.path.join(p, x)) for x in args ] |
209 | 31 return args |
245 | 32 |
33 def dodiff(repo, files = None, node1 = None, node2 = None): | |
34 def date(c): | |
35 return time.asctime(time.gmtime(float(c[2].split(' ')[0]))) | |
36 | |
37 if node2: | |
38 change = repo.changelog.read(node2) | |
39 mmap2 = repo.manifest.read(change[0]) | |
40 (c, a, d) = repo.diffrevs(node1, node2) | |
41 def read(f): return repo.file(f).read(mmap2[f]) | |
42 date2 = date(change) | |
43 else: | |
44 date2 = time.asctime() | |
45 (c, a, d, u) = repo.diffdir(repo.root, node1) | |
46 if not node1: | |
47 node1 = repo.dirstate.parents()[0] | |
48 def read(f): return file(os.path.join(repo.root, f)).read() | |
49 | |
50 change = repo.changelog.read(node1) | |
51 mmap = repo.manifest.read(change[0]) | |
52 date1 = date(change) | |
53 | |
54 if files: | |
55 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d)) | |
56 | |
57 for f in c: | |
58 to = repo.file(f).read(mmap[f]) | |
59 tn = read(f) | |
60 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f)) | |
61 for f in a: | |
62 to = "" | |
63 tn = read(f) | |
64 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f)) | |
65 for f in d: | |
66 to = repo.file(f).read(mmap[f]) | |
67 tn = "" | |
68 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f)) | |
209 | 69 |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
70 def help(ui, cmd=None): |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
71 '''show help''' |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
72 if cmd: |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
73 try: |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
74 i = find(cmd) |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
75 ui.write("%s\n\n" % i[2]) |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
76 ui.write(i[0].__doc__, "\n") |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
77 except UnknownCommand: |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
78 ui.warn("unknown command %s", cmd) |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
79 sys.exit(0) |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
80 |
209 | 81 ui.status("""\ |
82 hg commands: | |
83 | |
84 add [files...] add the given files in the next commit | |
85 addremove add all new files, delete all missing files | |
86 annotate [files...] show changeset number per file line | |
87 branch <path> create a branch of <path> in this directory | |
88 checkout [changeset] checkout the latest or given changeset | |
89 commit commit all changes to the repository | |
90 diff [files...] diff working directory (or selected files) | |
91 dump <file> [rev] dump the latest or given revision of a file | |
92 dumpmanifest [rev] dump the latest or given revision of the manifest | |
93 export <rev> dump the changeset header and diffs for a revision | |
94 history show changeset history | |
95 init create a new repository in this directory | |
96 log <file> show revision history of a single file | |
97 merge <path> merge changes from <path> into local repository | |
98 recover rollback an interrupted transaction | |
99 remove [files...] remove the given files in the next commit | |
100 serve export the repository via HTTP | |
101 status show new, missing, and changed files in working dir | |
102 tags show current changeset tags | |
103 undo undo the last transaction | |
104 """) | |
105 | |
245 | 106 def add(ui, repo, file, *files): |
107 '''add the specified files on the next commit''' | |
108 repo.add(relpath(repo, (file,) + files)) | |
213 | 109 |
245 | 110 def addremove(ui, repo): |
230 | 111 (c, a, d, u) = repo.diffdir(repo.root) |
245 | 112 repo.add(a) |
113 repo.remove(d) | |
219
8ff4532376a4
hg checkout: refuse to checkout if there are outstanding changes
mpm@selenic.com
parents:
214
diff
changeset
|
114 |
245 | 115 def annotate(u, repo, file, *files, **ops): |
209 | 116 def getnode(rev): |
117 return hg.short(repo.changelog.node(rev)) | |
118 | |
119 def getname(rev): | |
120 try: | |
121 return bcache[rev] | |
122 except KeyError: | |
123 cl = repo.changelog.read(repo.changelog.node(rev)) | |
124 name = cl[1] | |
125 f = name.find('@') | |
126 if f >= 0: | |
127 name = name[:f] | |
128 bcache[rev] = name | |
129 return name | |
130 | |
131 bcache = {} | |
132 opmap = [['user', getname], ['number', str], ['changeset', getnode]] | |
133 if not ops['user'] and not ops['changeset']: | |
134 ops['number'] = 1 | |
135 | |
227 | 136 node = repo.dirstate.parents()[0] |
209 | 137 if ops['revision']: |
138 node = repo.changelog.lookup(ops['revision']) | |
139 change = repo.changelog.read(node) | |
140 mmap = repo.manifest.read(change[0]) | |
141 maxuserlen = 0 | |
142 maxchangelen = 0 | |
245 | 143 for f in relpath(repo, (file,) + files): |
209 | 144 lines = repo.file(f).annotate(mmap[f]) |
145 pieces = [] | |
146 | |
147 for o, f in opmap: | |
148 if ops[o]: | |
149 l = [ f(n) for n,t in lines ] | |
150 m = max(map(len, l)) | |
151 pieces.append([ "%*s" % (m, x) for x in l]) | |
152 | |
153 for p,l in zip(zip(*pieces), lines): | |
154 u.write(" ".join(p) + ": " + l[1]) | |
155 | |
245 | 156 def branch(ui, path): |
157 '''branch from a local repository''' | |
158 # this should eventually support remote repos | |
159 os.system("cp -al %s/.hg .hg" % path) | |
160 | |
248 | 161 def cat(ui, repo, file, rev = []): |
162 r = repo.file(file) | |
163 n = r.tip() | |
164 if rev: n = r.lookup(rev) | |
165 sys.stdout.write(r.read(n)) | |
166 | |
245 | 167 def checkout(ui, repo, changeset=None): |
168 '''checkout a given changeset or the current tip''' | |
169 (c, a, d, u) = repo.diffdir(repo.root) | |
170 if c or a or d: | |
171 ui.warn("aborting (outstanding changes in working directory)\n") | |
172 sys.exit(1) | |
173 | |
174 node = repo.changelog.tip() | |
175 if changeset: | |
176 node = repo.lookup(changeset) | |
177 repo.checkout(node) | |
178 | |
179 def commit(ui, repo, *files): | |
180 """commit the specified files or all outstanding changes""" | |
181 repo.commit(relpath(repo, files)) | |
182 | |
248 | 183 def debugaddchangegroup(ui, repo): |
184 data = sys.stdin.read() | |
185 repo.addchangegroup(data) | |
186 | |
187 def debugchangegroup(ui, repo, roots): | |
188 newer = repo.newer(map(repo.lookup, roots)) | |
189 for chunk in repo.changegroup(newer): | |
190 sys.stdout.write(chunk) | |
191 | |
192 def debugindex(ui, file): | |
193 r = hg.revlog(open, file, "") | |
194 print " rev offset length base linkrev"+\ | |
195 " p1 p2 nodeid" | |
196 for i in range(r.count()): | |
197 e = r.index[i] | |
198 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % ( | |
199 i, e[0], e[1], e[2], e[3], | |
200 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5])) | |
201 | |
202 def debugindexdot(ui, file): | |
203 r = hg.revlog(open, file, "") | |
204 print "digraph G {" | |
205 for i in range(r.count()): | |
206 e = r.index[i] | |
207 print "\t%d -> %d" % (r.rev(e[4]), i) | |
208 if e[5] != hg.nullid: | |
209 print "\t%d -> %d" % (r.rev(e[5]), i) | |
210 print "}" | |
211 | |
245 | 212 def diff(ui, repo, *files, **opts): |
213 revs = [] | |
214 if opts['rev']: | |
215 revs = map(lambda x: repo.lookup(x), opts['rev']) | |
216 | |
217 if len(revs) > 2: | |
218 self.ui.warn("too many revisions to diff\n") | |
219 sys.exit(1) | |
220 | |
221 if files: | |
222 files = relpath(repo, files) | |
223 else: | |
224 files = relpath(repo, [""]) | |
225 | |
226 dodiff(repo, files, *revs) | |
227 | |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
228 def export(ui, repo, changeset): |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
229 node = repo.lookup(changeset) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
230 prev, other = repo.changelog.parents(node) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
231 change = repo.changelog.read(node) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
232 print "# HG changeset patch" |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
233 print "# User %s" % change[1] |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
234 print "# Node ID %s" % hg.hex(node) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
235 print "# Parent %s" % hg.hex(prev) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
236 print |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
237 if other != hg.nullid: |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
238 print "# Parent %s" % hg.hex(other) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
239 print change[4].rstrip() |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
240 print |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
241 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
242 dodiff(repo, None, prev, node) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
243 |
245 | 244 def forget(ui, repo, file, *files): |
245 """don't add the specified files on the next commit""" | |
246 repo.forget(relpath(repo, (file,) + files)) | |
247 | |
221 | 248 def heads(ui, repo): |
249 '''show current repository heads''' | |
250 for n in repo.changelog.heads(): | |
251 i = repo.changelog.rev(n) | |
252 changes = repo.changelog.read(n) | |
253 (p1, p2) = repo.changelog.parents(n) | |
254 (h, h1, h2) = map(hg.hex, (n, p1, p2)) | |
255 (i1, i2) = map(repo.changelog.rev, (p1, p2)) | |
256 print "rev: %4d:%s" % (i, h) | |
257 print "parents: %4d:%s" % (i1, h1) | |
258 if i2: print " %4d:%s" % (i2, h2) | |
259 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]), | |
260 hg.hex(changes[0])) | |
261 print "user:", changes[1] | |
262 print "date:", time.asctime( | |
263 time.localtime(float(changes[2].split(' ')[0]))) | |
264 if ui.verbose: print "files:", " ".join(changes[3]) | |
265 print "description:" | |
266 print changes[4] | |
267 | |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
268 def history(ui, repo): |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
269 """show the changelog history""" |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
270 for i in range(repo.changelog.count()): |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
271 n = repo.changelog.node(i) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
272 changes = repo.changelog.read(n) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
273 (p1, p2) = repo.changelog.parents(n) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
274 (h, h1, h2) = map(hg.hex, (n, p1, p2)) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
275 (i1, i2) = map(repo.changelog.rev, (p1, p2)) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
276 print "rev: %4d:%s" % (i, h) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
277 print "parents: %4d:%s" % (i1, h1) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
278 if i2: print " %4d:%s" % (i2, h2) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
279 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
280 hg.hex(changes[0])) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
281 print "user:", changes[1] |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
282 print "date:", time.asctime( |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
283 time.localtime(float(changes[2].split(' ')[0]))) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
284 if ui.verbose: print "files:", " ".join(changes[3]) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
285 print "description:" |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
286 print changes[4] |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
287 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
288 def patch(ui, repo, patches, opts): |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
289 """import an ordered set of patches""" |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
290 try: |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
291 import psyco |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
292 psyco.full() |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
293 except: |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
294 pass |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
295 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
296 d = opts["base"] |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
297 strip = opts["strip"] |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
298 quiet = opts["quiet"] and "> /dev/null" or "" |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
299 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
300 for patch in patches: |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
301 ui.status("applying %s\n" % patch) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
302 pf = os.path.join(d, patch) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
303 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
304 text = "" |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
305 for l in file(pf): |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
306 if l[:4] == "--- ": break |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
307 text += l |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
308 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
309 f = os.popen("lsdiff --strip %d %s" % (strip, pf)) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
310 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines())) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
311 f.close() |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
312 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
313 if files: |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
314 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)): |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
315 raise "patch failed!" |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
316 repo.commit(files, text) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
317 |
245 | 318 def init(ui): |
319 """create a repository""" | |
320 hg.repository(ui, ".", create=1) | |
321 | |
322 def log(ui, repo, f): | |
323 f = relpath(repo, [f])[0] | |
324 | |
325 r = repo.file(f) | |
326 for i in range(r.count()): | |
327 n = r.node(i) | |
328 (p1, p2) = r.parents(n) | |
329 (h, h1, h2) = map(hg.hex, (n, p1, p2)) | |
330 (i1, i2) = map(r.rev, (p1, p2)) | |
331 cr = r.linkrev(n) | |
332 cn = hg.hex(repo.changelog.node(cr)) | |
333 print "rev: %4d:%s" % (i, h) | |
334 print "changeset: %4d:%s" % (cr, cn) | |
335 print "parents: %4d:%s" % (i1, h1) | |
336 if i2: print " %4d:%s" % (i2, h2) | |
337 changes = repo.changelog.read(repo.changelog.node(cr)) | |
338 print "user: %s" % changes[1] | |
339 print "date: %s" % time.asctime( | |
340 time.localtime(float(changes[2].split(' ')[0]))) | |
341 print "description:" | |
342 print changes[4].rstrip() | |
343 print | |
344 | |
248 | 345 def manifest(ui, repo, rev = []): |
346 n = repo.manifest.tip() | |
347 if rev: | |
348 n = repo.manifest.lookup(rev) | |
349 m = repo.manifest.read(n) | |
350 files = m.keys() | |
351 files.sort() | |
352 | |
353 for f in files: | |
354 print hg.hex(m[f]), f | |
355 | |
227 | 356 def parents(ui, repo, node = None): |
357 '''show the parents of the current working dir''' | |
358 if node: | |
359 p = repo.changelog.parents(repo.lookup(hg.bin(node))) | |
360 else: | |
361 p = repo.dirstate.parents() | |
362 | |
363 for n in p: | |
364 if n != hg.nullid: | |
365 ui.write("%d:%s\n" % (repo.changelog.rev(n), hg.hex(n))) | |
366 | |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
367 def pull(ui, repo, source): |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
368 """pull changes from the specified source""" |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
369 paths = {} |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
370 try: |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
371 pf = os.path.expanduser("~/.hgpaths") |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
372 for l in file(pf): |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
373 name, path = l.split() |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
374 paths[name] = path |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
375 except IOError: |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
376 pass |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
377 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
378 if source in paths: source = paths[source] |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
379 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
380 other = hg.repository(ui, source) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
381 cg = repo.getchangegroup(other) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
382 repo.addchangegroup(cg) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
383 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
384 def rawcommit(ui, repo, files, rc): |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
385 "raw commit interface" |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
386 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
387 text = rc['text'] |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
388 if not text and rc['logfile']: |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
389 try: text = open(rc['logfile']).read() |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
390 except IOError: pass |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
391 if not text and not rc['logfile']: |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
392 print "missing commit text" |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
393 return 1 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
394 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
395 files = relpath(repo, files) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
396 if rc['files']: |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
397 files += open(rc['files']).read().splitlines() |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
398 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
399 repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent']) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
400 |
245 | 401 def recover(ui, repo): |
402 repo.recover() | |
403 | |
404 def remove(ui, repo, file, *files): | |
405 """remove the specified files on the next commit""" | |
406 repo.remove(relpath(repo, (file,) + files)) | |
407 | |
408 def resolve(ui, repo, node=None): | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
230
diff
changeset
|
409 '''merge a given node or the current tip into the working dir''' |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
230
diff
changeset
|
410 if not node: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
230
diff
changeset
|
411 node = repo.changelog.tip() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
230
diff
changeset
|
412 else: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
230
diff
changeset
|
413 node = repo.lookup(node) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
230
diff
changeset
|
414 repo.resolve(node) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
230
diff
changeset
|
415 |
245 | 416 def serve(ui, repo, **opts): |
417 from mercurial import hgweb | |
418 hgweb.server(repo.root, opts["name"], opts["templates"], | |
419 opts["address"], opts["port"]) | |
420 | |
213 | 421 def status(ui, repo): |
422 '''show changed files in the working directory | |
423 | |
245 | 424 C = changed |
425 A = added | |
426 R = removed | |
427 ? = not tracked''' | |
428 | |
230 | 429 (c, a, d, u) = repo.diffdir(repo.root) |
220 | 430 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u)) |
213 | 431 |
432 for f in c: print "C", f | |
220 | 433 for f in a: print "A", f |
213 | 434 for f in d: print "R", f |
220 | 435 for f in u: print "?", f |
213 | 436 |
248 | 437 def tags(ui, repo): |
438 repo.lookup(0) # prime the cache | |
439 i = repo.tags.items() | |
440 i.sort() | |
441 for k, n in i: | |
442 try: | |
443 r = repo.changelog.rev(n) | |
444 except KeyError: | |
445 r = "?" | |
446 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n)) | |
447 | |
245 | 448 def tip(ui, repo): |
449 n = repo.changelog.tip() | |
450 t = repo.changelog.rev(n) | |
451 ui.status("%d:%s\n" % (t, hg.hex(n))) | |
452 | |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
453 def undo(ui, repo): |
210 | 454 repo.undo() |
455 | |
247 | 456 def verify(ui, repo): |
457 """verify the integrity of the repository""" | |
458 return repo.verify() | |
459 | |
209 | 460 table = { |
245 | 461 "add": (add, [], "hg add [files]"), |
462 "addremove": (addremove, [], "hg addremove"), | |
209 | 463 "ann|annotate": (annotate, |
464 [('r', 'revision', '', 'revision'), | |
465 ('u', 'user', None, 'show user'), | |
466 ('n', 'number', None, 'show revision number'), | |
467 ('c', 'changeset', None, 'show changeset')], | |
468 'hg annotate [-u] [-c] [-n] [-r id] [files]'), | |
245 | 469 "branch|clone": (branch, [], 'hg branch [path]'), |
248 | 470 "cat|dump": (cat, [], 'hg cat <file> [rev]'), |
245 | 471 "checkout|co": (checkout, [], 'hg checkout [changeset]'), |
472 "commit|ci": (commit, [], 'hg commit [files]'), | |
248 | 473 "debugaddchangegroup": (debugaddchangegroup, [], 'debugaddchangegroup'), |
474 "debugchangegroup": (debugchangegroup, [], 'debugchangegroup [roots]'), | |
475 "debugindex": (debugindex, [], 'debugindex <file>'), | |
476 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'), | |
245 | 477 "diff": (diff, [('r', 'rev', [], 'revision')], |
478 'hg diff [-r A] [-r B] [files]'), | |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
479 "export": (export, [], "hg export <changeset>"), |
245 | 480 "forget": (forget, [], "hg forget [files]"), |
481 "heads": (heads, [], 'hg heads'), | |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
482 "history": (history, [], 'hg history'), |
245 | 483 "help": (help, [], 'hg help [command]'), |
484 "init": (init, [], 'hg init'), | |
485 "log": (log, [], 'hg log <file>'), | |
248 | 486 "manifest|dumpmanifest": (manifest, [], 'hg manifest [rev]'), |
227 | 487 "parents": (parents, [], 'hg parents [node]'), |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
488 "patch|import": (patch, |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
489 [('p', 'strip', 1, 'path strip'), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
490 ('b', 'base', "", 'base path'), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
491 ('q', 'quiet', "", 'silence diff')], |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
492 "hg import [options] patches"), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
493 "pull|merge": (pull, [], 'hg pull [source]'), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
494 "rawcommit": (rawcommit, |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
495 [('p', 'parent', [], 'parent'), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
496 ('d', 'date', "", 'data'), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
497 ('u', 'user', "", 'user'), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
498 ('F', 'files', "", 'file list'), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
499 ('t', 'text', "", 'commit text'), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
500 ('l', 'logfile', "", 'commit text file')], |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
501 'hg rawcommit [options] [files]'), |
245 | 502 "recover": (recover, [], "hg recover"), |
503 "remove": (remove, [], "hg remove [files]"), | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
230
diff
changeset
|
504 "resolve": (resolve, [], 'hg resolve [node]'), |
245 | 505 "serve": (serve, [('p', 'port', 8000, 'listen port'), |
506 ('a', 'address', '', 'interface address'), | |
507 ('n', 'name', os.getcwd(), 'repository name'), | |
508 ('t', 'templates', "", 'template map')], | |
509 "hg serve [options]"), | |
213 | 510 "status": (status, [], 'hg status'), |
248 | 511 "tags": (tags, [], 'hg tags'), |
245 | 512 "tip": (tip, [], 'hg tip'), |
210 | 513 "undo": (undo, [], 'hg undo'), |
247 | 514 "verify": (verify, [], 'hg verify'), |
209 | 515 } |
516 | |
248 | 517 norepo = "init branch help debugindex debugindexdot" |
209 | 518 |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
519 def find(cmd): |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
520 i = None |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
521 for e in table.keys(): |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
522 if re.match(e + "$", cmd): |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
523 return table[e] |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
524 |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
525 raise UnknownCommand(cmd) |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
526 |
214 | 527 class SignalInterrupt(Exception): pass |
528 | |
529 def catchterm(*args): | |
530 raise SignalInterrupt | |
531 | |
249 | 532 def run(): |
533 sys.exit(dispatch(sys.argv[1:])) | |
534 | |
209 | 535 def dispatch(args): |
536 options = {} | |
537 opts = [('v', 'verbose', None, 'verbose'), | |
538 ('d', 'debug', None, 'debug'), | |
539 ('q', 'quiet', None, 'quiet'), | |
540 ('y', 'noninteractive', None, 'run non-interactively'), | |
541 ] | |
542 | |
543 args = fancyopts.fancyopts(args, opts, options, | |
544 'hg [options] <command> [options] [files]') | |
545 | |
546 if not args: | |
547 cmd = "help" | |
548 else: | |
549 cmd, args = args[0], args[1:] | |
550 | |
551 u = ui.ui(options["verbose"], options["debug"], options["quiet"], | |
552 not options["noninteractive"]) | |
553 | |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
554 # deal with unfound commands later |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
555 i = find(cmd) |
209 | 556 |
214 | 557 signal.signal(signal.SIGTERM, catchterm) |
558 | |
209 | 559 cmdoptions = {} |
560 args = fancyopts.fancyopts(args, i[1], cmdoptions, i[2]) | |
561 | |
562 if cmd not in norepo.split(): | |
563 repo = hg.repository(ui = u) | |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
564 d = lambda: i[0](u, repo, *args, **cmdoptions) |
209 | 565 else: |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
566 d = lambda: i[0](u, *args, **cmdoptions) |
209 | 567 |
568 try: | |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
569 return d() |
214 | 570 except SignalInterrupt: |
571 u.warn("killed!\n") | |
209 | 572 except KeyboardInterrupt: |
573 u.warn("interrupted!\n") | |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
574 except TypeError, inst: |
249 | 575 import traceback |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
576 # was this an argument error? |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
577 tb = traceback.extract_tb(sys.exc_info()[2]) |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
578 if len(tb) > 2: # no |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
579 raise |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
580 u.warn("%s: invalid arguments\n" % i[0].__name__) |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
581 u.warn("syntax: %s\n" % i[2]) |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
582 sys.exit(-1) |