##// END OF EJS Templates
[PATCH] replace history with log...
mpm@selenic.com -
r509:98a2935c default
parent child Browse files
Show More
@@ -1,449 +1,443 b''
1 1 HG(1)
2 2 =====
3 3 Matt Mackall <mpm@selenic.com>
4 4
5 5 NAME
6 6 ----
7 7 hg - Mercurial source code management system
8 8
9 9 SYNOPSIS
10 10 --------
11 11 'hg' [-v -d -q -y] <command> [command options] [files]
12 12
13 13 DESCRIPTION
14 14 -----------
15 15 The hg(1) command provides a command line interface to the Mercurial system.
16 16
17 17 OPTIONS
18 18 -------
19 19
20 20 --debug, -d::
21 21 enable debugging output
22 22
23 23 --quiet, -q::
24 24 suppress output
25 25
26 26 --verbose, -v::
27 27 enable additional output
28 28
29 29 --noninteractive, -y::
30 30 do not prompt, assume 'yes' for any required answers
31 31
32 32 COMMAND ELEMENTS
33 33 ----------------
34 34
35 35 files ...::
36 36 indicates one or more filename or relative path filenames
37 37
38 38 path::
39 39 indicates a path on the local machine
40 40
41 41 revision::
42 42 indicates a changeset which can be specified as a changeset revision
43 43 number, a tag, or a unique substring of the changeset hash value
44 44
45 45 repository path::
46 46 either the pathname of a local repository or the URI of a remote
47 47 repository. There are two available URI protocols, http:// which is
48 48 fast and the old-http:// protocol which is much slower but does not
49 49 require a special server on the web host.
50 50
51 51 COMMANDS
52 52 --------
53 53
54 54 add [files ...]::
55 55 Schedule files to be version controlled and added to the repository.
56 56
57 57 The files will be added to the repository at the next commit.
58 58
59 59 addremove::
60 60 Add all new files and remove all missing files from the repository.
61 61
62 62 New files are ignored if they match any of the patterns in .hgignore. As
63 63 with add, these changes take effect at the next commit.
64 64
65 65 annotate [-r <rev> -u -n -c] [files ...]::
66 66 List changes in files, showing the revision id responsible for each line
67 67
68 68 This command is useful to discover who did a change or when a change took
69 69 place.
70 70
71 71 options:
72 72 -r, --revision <rev> annotate the specified revision
73 73 -u, --user list the author
74 74 -c, --changeset list the changeset
75 75 -n, --number list the revision number (default)
76 76
77 77 cat <file> [revision]::
78 78 Output to stdout the given revision for the specified file.
79 79
80 80 If no revision is given then the tip is used.
81 81
82 82 clone [-U] <source> [dest]::
83 83 Create a copy of an existing repository in a new directory.
84 84
85 85 If the destination directory is specified but doesn't exist, it is
86 86 created. If no destination directory is specified, it defaults to the
87 87 current directory.
88 88
89 89 The source is added to the new repository's .hg/hgrc file to be used in
90 90 future pulls.
91 91
92 92 For efficiency, hardlinks are used for cloning whenever the
93 93 source and destination are on the same filesystem.
94 94
95 95 options:
96 96 -U, --noupdate do not update the new working directory
97 97
98 98 commit [-A -t -l <file> -t <text> -u <user> -d <datecode>] [files...]::
99 99 Commit changes to the given files into the repository.
100 100
101 101 If a list of files is omitted, all changes reported by "hg status"
102 102 will be commited.
103 103
104 104 The HGEDITOR or EDITOR environment variables are used to start an
105 105 editor to add a commit comment.
106 106
107 107 Options:
108 108
109 109 -A, --addremove run addremove during commit
110 110 -t, --text <text> use <text> as commit message
111 111 -l, --logfile <file> show the commit message for the given file
112 112 -d, --date <datecode> record datecode as commit date
113 113 -u, --user <user> record user as commiter
114 114
115 115 aliases: ci
116 116
117 117 copy <source> <dest>::
118 118 Mark <dest> file as a copy or rename of a <source> one
119 119
120 120 This command takes effect for the next commit.
121 121
122 122 diff [-r revision] [-r revision] [files ...]::
123 123 Show differences between revisions for the specified files.
124 124
125 125 Differences between files are shown using the unified diff format.
126 126
127 127 When two revision arguments are given, then changes are shown
128 128 between those revisions. If only one revision is specified then
129 129 that revision is compared to the working directory, and, when no
130 130 revisions are specified, the working directory files are compared
131 131 to its parent.
132 132
133 133 export [revision]::
134 134 Print the changeset header and diffs for a particular revision.
135 135
136 136 The information shown in the changeset header is: author, changeset hash,
137 137 parent and commit comment.
138 138
139 139 forget [files]::
140 140 Undo an 'hg add' scheduled for the next commit.
141 141
142 142 heads::
143 143 Show all repository head changesets.
144 144
145 145 Repository "heads" are changesets that don't have children
146 146 changesets. They are where development generally takes place and
147 147 are the usual targets for update and merge operations.
148 148
149 history::
150 Print a log of the revision history of the repository.
151
152 By default this command outputs: changeset id and hash, tags,
153 parents, user, date and time, and a summary for each commit. The
154 -v switch adds some more detail, such as changed files, manifest
155 hashes or message signatures.
156
157 To display the history of a given file, see the log command.
158
159 149 identify::
160 150 Print a short summary of the current state of the repo.
161 151
162 152 This summary identifies the repository state using one or two parent
163 153 hash identifiers, followed by a "+" if there are uncommitted changes
164 154 in the working directory, followed by a list of tags for this revision.
165 155
166 156 aliases: id
167 157
168 158 import [-p <n> -b <base> -q] <patches>::
169 159 Import a list of patches and commit them individually.
170 160
171 161 options:
172 162 -p, --strip <n> directory strip option for patch. This has the same
173 163 meaning as the correnponding patch option
174 164 -b <path> base directory to read patches from
175 165
176 166 aliases: patch
177 167
178 168 init::
179 169 Initialize a new repository in the current directory.
180 170
181 log <file>::
182 Print the revision history of the specified file.
171 log [file]::
172 Print the revision history of the specified file or the entire project.
183 173
184 To display the revision history for the whole repository, use the history
185 command.
174 By default this command outputs: changeset id and hash, tags,
175 parents, user, date and time, and a summary for each commit. The
176 -v switch adds some more detail, such as changed files, manifest
177 hashes or message signatures.
178
179 aliases: history
186 180
187 181 manifest [revision]::
188 182 Print a list of version controlled files for the given revision.
189 183
190 184 The manifest is the list of files being version controlled. If no revision
191 185 is given then the tip is used.
192 186
193 187 parents::
194 188 Print the working directory's parent revisions.
195 189
196 190 pull <repository path>::
197 191 Pull changes from a remote repository to a local one.
198 192
199 193 This finds all changes from the repository at the specified path
200 194 or URL and adds them to the local repository. By default, this
201 195 does not update the copy of the project in the working directory.
202 196
203 197 options:
204 198 -u, --update update the working directory to tip after pull
205 199
206 200 push <destination>::
207 201 Push changes from the local repository to the given destination.
208 202
209 203 This is the symmetrical operation for pull. It helps to move
210 204 changes from the current repository to a different one. If the
211 205 destination is local this is identical to a pull in that directory
212 206 from the current one.
213 207
214 208 The other currently available push method is SSH. This requires an
215 209 accessible shell account on the destination machine and a copy of
216 210 hg in the remote path. Destinations are specified in the following
217 211 form:
218 212
219 213 ssh://[user@]host[:port]/path
220 214
221 215 rawcommit [-p -d -u -F -t -l]::
222 216 Lowlevel commit, for use in helper scripts.
223 217
224 218 This command is not intended to be used by normal users, as it is
225 219 primarily useful for importing from other SCMs.
226 220
227 221 recover::
228 222 Recover from an interrupted commit or pull.
229 223
230 224 This command tries to fix the repository status after an interrupted
231 225 operation. It should only be necessary when Mercurial suggests it.
232 226
233 227 remove [files ...]::
234 228 Schedule the indicated files for removal from the repository.
235 229
236 230 This command shedules the files to be removed at the next commit.
237 231 This only removes files from the current branch, not from the
238 232 entire project history.
239 233
240 234 aliases: rm
241 235
242 236 root::
243 237 Print the root directory of the current repository.
244 238
245 239 serve [-a addr -n name -p port -t templatedir]::
246 240 Start a local HTTP repository browser and pull server.
247 241
248 242 options:
249 243 -a, --address <addr> address to use
250 244 -p, --port <n> port to use (default: 8000)
251 245 -n, --name <name> name to show in web pages (default: working dir)
252 246 -t, --templatedir <path> web templates to use
253 247
254 248 status::
255 249 Show changed files in the working directory.
256 250
257 251 The codes used to show the status of files are:
258 252
259 253 C = changed
260 254 A = added
261 255 R = removed
262 256 ? = not tracked
263 257
264 258 tag [-t <text> -d <datecode> -u <user>] <name> [revision]::
265 259 Name a particular revision using <name>.
266 260
267 261 Tags are used to name particular revisions of the repository and are
268 262 very useful to compare different revision, to go back to significant
269 263 earlier versions or to mark branch points as releases, etc.
270 264
271 265 If no revision is given, the tip is used.
272 266
273 267 To facilitate version control, distribution, and merging of tags,
274 268 they are stored as a file named ".hgtags" which is managed
275 269 similarly to other project files and can be hand-edited if
276 270 necessary.
277 271
278 272 options:
279 273 -t, --text <text> message for tag commit log entry
280 274 -d, --date <datecode> datecode for commit
281 275 -u, --user <user> user for commit
282 276
283 277 Note: Mercurial also has support for "local tags" that are not
284 278 version-controlled or distributed which are stored in the .hg/hgrc
285 279 file.
286 280
287 281 tags::
288 282 List the repository tags.
289 283
290 284 This lists both regular and local tags.
291 285
292 286 tip::
293 287 Show the tip revision.
294 288
295 289 undo::
296 290 Undo the last commit or pull transaction.
297 291
298 292 update [-m -C] [revision]::
299 293 Update the working directory to the specified revision.
300 294
301 295 By default, update will refuse to run if doing so would require
302 296 merging or discarding local changes.
303 297
304 298 With the -m option, a merge will be performed.
305 299
306 300 With the -C option, local changes will be lost.
307 301
308 302 options:
309 303 -m, --merge allow merging of branches
310 304 -C, --clean overwrite locally modified files
311 305
312 306 aliases: up checkout co
313 307
314 308 verify::
315 309 Verify the integrity of the current repository.
316 310
317 311 This will perform an extensive check of the repository's
318 312 integrity, validating the hashes and checksums of each entry in
319 313 the changelog, manifest, and tracked files, as well as the
320 314 integrity of their crosslinks and indices.
321 315
322 316
323 317 ENVIRONMENT VARIABLES
324 318 ---------------------
325 319
326 320 HGEDITOR::
327 321 This is the name of the editor to use when committing. Defaults to the
328 322 value of EDITOR.
329 323
330 324 HGMERGE::
331 325 An executable to use for resolving merge conflicts. The program
332 326 will be executed with three arguments: local file, remote file,
333 327 ancestor file.
334 328
335 329 The default program is "hgmerge", which is a shell script provided
336 330 by Mercurial with some sensible defaults.
337 331
338 332 HGUSER::
339 333 This is the string used for the author of a commit.
340 334
341 335 EMAIL::
342 336 If HGUSER is not set, this will be used as the author for a commit.
343 337
344 338 LOGNAME::
345 339 If neither HGUSER nor EMAIL is set, LOGNAME will be used (with
346 340 '@hostname' appended) as the author value for a commit.
347 341
348 342 EDITOR::
349 343 This is the name of the editor used in the hgmerge script. It will be
350 344 used for commit messages if HGEDITOR isn't set. Defaults to 'vi'.
351 345
352 346 PYTHONPATH::
353 347 This is used by Python to find imported modules and may need to be set
354 348 appropriately if Mercurial is not installed system-wide.
355 349
356 350 FILES
357 351 -----
358 352 .hgignore::
359 353 This file contains regular expressions (one per line) that describe file
360 354 names that should be ignored by hg.
361 355
362 356 .hgtags::
363 357 This file contains changeset hash values and text tag names (one of each
364 358 seperated by spaces) that correspond to tagged versions of the repository
365 359 contents.
366 360
367 361 $HOME/.hgrc, .hg/hgrc::
368 362 This file contains defaults and configuration. Values in .hg/hgrc
369 363 override those in .hgrc.
370 364
371 365 NAMED REPOSITORIES
372 366 ------------------
373 367
374 368 To give symbolic names to a repository, create a section in .hgrc
375 369 or .hg/hgrc containing assignments of names to paths. Example:
376 370
377 371 -----------------
378 372 [paths]
379 373 hg = http://selenic.com/hg
380 374 tah = http://hg.intevation.org/mercurial-tah/
381 375 -----------------
382 376
383 377
384 378 LOCAL TAGS
385 379 ----------
386 380
387 381 To create tags that are local to the repository and not distributed or
388 382 version-controlled, create an hgrc section like the following:
389 383
390 384 ----------------
391 385 [tags]
392 386 working = 2dcced388cab3677a8f543c3c47a0ad34ac9d435
393 387 tested = 12e0fdbc57a0be78f0e817fd1d170a3615cd35da
394 388 ----------------
395 389
396 390
397 391 HOOKS
398 392 -----
399 393
400 394 Mercurial supports a set of 'hook', commands that get automatically
401 395 executed by various actions such as starting or finishing a commit. To
402 396 specify a hook, simply create an hgrc section like the following:
403 397
404 398 -----------------
405 399 [hooks]
406 400 precommit = echo "this hook gets executed immediately before a commit"
407 401 commit = hg export $NODE | mail -s "new commit $NODE" commit-list
408 402 -----------------
409 403
410 404
411 405 NON_TRANSPARENT PROXY SUPPORT
412 406 -----------------------------
413 407
414 408 To access a Mercurial repository through a proxy, create a file
415 409 $HOME/.hgrc in the following format:
416 410
417 411 --------------
418 412 [http_proxy]
419 413 host=myproxy:8080
420 414 user=<username>
421 415 passwd=<password>
422 416 no=<localhost1>,<localhost2>,<localhost3>,...
423 417 --------------
424 418
425 419 "user" and "passwd" fields are used for authenticating proxies, "no" is a
426 420 comma-separated list of local host names to not proxy.
427 421
428 422 BUGS
429 423 ----
430 424 Probably lots, please post them to the mailing list (See Resources below)
431 425 when you find them.
432 426
433 427 AUTHOR
434 428 ------
435 429 Written by Matt Mackall <mpm@selenic.com>
436 430
437 431 RESOURCES
438 432 ---------
439 433 http://selenic.com/mercurial[Main Web Site]
440 434
441 435 http://selenic.com/hg[Source code repository]
442 436
443 437 http://selenic.com/mailman/listinfo/mercurial[Mailing list]
444 438
445 439 COPYING
446 440 -------
447 441 Copyright (C) 2005 Matt Mackall.
448 442 Free use of this software is granted under the terms of the GNU General
449 443 Public License (GPL).
@@ -1,901 +1,898 b''
1 1 # commands.py - command processing for mercurial
2 2 #
3 3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 import os, re, sys, signal
9 9 import fancyopts, ui, hg, util
10 10 from demandload import *
11 11 demandload(globals(), "mdiff time hgweb traceback random signal errno version")
12 12
13 13 class UnknownCommand(Exception): pass
14 14
15 15 def filterfiles(filters, files):
16 16 l = [ x for x in files if x in filters ]
17 17
18 18 for t in filters:
19 19 if t and t[-1] != "/": t += "/"
20 20 l += [ x for x in files if x.startswith(t) ]
21 21 return l
22 22
23 23 def relfilter(repo, files):
24 24 if os.getcwd() != repo.root:
25 25 p = os.getcwd()[len(repo.root) + 1: ]
26 26 return filterfiles([util.pconvert(p)], files)
27 27 return files
28 28
29 29 def relpath(repo, args):
30 30 if os.getcwd() != repo.root:
31 31 p = os.getcwd()[len(repo.root) + 1: ]
32 32 return [ util.pconvert(os.path.normpath(os.path.join(p, x))) for x in args ]
33 33 return args
34 34
35 35 def dodiff(ui, repo, path, files = None, node1 = None, node2 = None):
36 36 def date(c):
37 37 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
38 38
39 39 if node2:
40 40 change = repo.changelog.read(node2)
41 41 mmap2 = repo.manifest.read(change[0])
42 42 (c, a, d) = repo.diffrevs(node1, node2)
43 43 def read(f): return repo.file(f).read(mmap2[f])
44 44 date2 = date(change)
45 45 else:
46 46 date2 = time.asctime()
47 47 (c, a, d, u) = repo.diffdir(path, node1)
48 48 if not node1:
49 49 node1 = repo.dirstate.parents()[0]
50 50 def read(f): return repo.wfile(f).read()
51 51
52 52 if ui.quiet:
53 53 r = None
54 54 else:
55 55 hexfunc = ui.verbose and hg.hex or hg.short
56 56 r = [hexfunc(node) for node in [node1, node2] if node]
57 57
58 58 change = repo.changelog.read(node1)
59 59 mmap = repo.manifest.read(change[0])
60 60 date1 = date(change)
61 61
62 62 if files:
63 63 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
64 64
65 65 for f in c:
66 66 to = None
67 67 if f in mmap:
68 68 to = repo.file(f).read(mmap[f])
69 69 tn = read(f)
70 70 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r))
71 71 for f in a:
72 72 to = None
73 73 tn = read(f)
74 74 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r))
75 75 for f in d:
76 76 to = repo.file(f).read(mmap[f])
77 77 tn = None
78 78 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r))
79 79
80 80 def show_changeset(ui, repo, rev=0, changenode=None, filelog=None):
81 81 """show a single changeset or file revision"""
82 82 changelog = repo.changelog
83 83 if filelog:
84 84 log = filelog
85 85 filerev = rev
86 86 node = filenode = filelog.node(filerev)
87 87 changerev = filelog.linkrev(filenode)
88 88 changenode = changenode or changelog.node(changerev)
89 89 else:
90 90 log = changelog
91 91 changerev = rev
92 92 if changenode is None:
93 93 changenode = changelog.node(changerev)
94 94 elif not changerev:
95 95 rev = changerev = changelog.rev(changenode)
96 96 node = changenode
97 97
98 98 if ui.quiet:
99 99 ui.write("%d:%s\n" % (rev, hg.hex(node)))
100 100 return
101 101
102 102 changes = changelog.read(changenode)
103 103
104 104 parents = [(log.rev(parent), hg.hex(parent))
105 105 for parent in log.parents(node)
106 106 if ui.debugflag or parent != hg.nullid]
107 107 if not ui.debugflag and len(parents) == 1 and parents[0][0] == rev-1:
108 108 parents = []
109 109
110 110 if filelog:
111 111 ui.write("revision: %d:%s\n" % (filerev, hg.hex(filenode)))
112 112 for parent in parents:
113 113 ui.write("parent: %d:%s\n" % parent)
114 114 ui.status("changeset: %d:%s\n" % (changerev, hg.hex(changenode)))
115 115 else:
116 116 ui.write("changeset: %d:%s\n" % (changerev, hg.hex(changenode)))
117 117 for tag in repo.nodetags(changenode):
118 118 ui.status("tag: %s\n" % tag)
119 119 for parent in parents:
120 120 ui.write("parent: %d:%s\n" % parent)
121 121 ui.note("manifest: %d:%s\n" % (repo.manifest.rev(changes[0]),
122 122 hg.hex(changes[0])))
123 123 ui.status("user: %s\n" % changes[1])
124 124 ui.status("date: %s\n" % time.asctime(
125 125 time.localtime(float(changes[2].split(' ')[0]))))
126 126 if ui.debugflag:
127 127 files = repo.diffrevs(changelog.parents(changenode)[0], changenode)
128 128 for key, value in zip(["files:", "files+:", "files-:"], files):
129 129 if value:
130 130 ui.note("%-12s %s\n" % (key, " ".join(value)))
131 131 else:
132 132 ui.note("files: %s\n" % " ".join(changes[3]))
133 133 description = changes[4].strip()
134 134 if description:
135 135 if ui.verbose:
136 136 ui.status("description:\n")
137 137 ui.status(description)
138 138 ui.status("\n")
139 139 else:
140 140 ui.status("summary: %s\n" % description.splitlines()[0])
141 141 ui.status("\n")
142 142
143 143 def show_version(ui):
144 144 """output version and copyright information"""
145 145 ui.write("Mercurial version %s\n" % version.get_version())
146 146 ui.status(
147 147 "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
148 148 "This is free software; see the source for copying conditions. "
149 149 "There is NO\nwarranty; "
150 150 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
151 151 )
152 152
153 153 def help(ui, cmd=None):
154 154 '''show help for a given command or all commands'''
155 155 if cmd:
156 156 try:
157 157 i = find(cmd)
158 158 ui.write("%s\n\n" % i[2])
159 159
160 160 if i[1]:
161 161 for s, l, d, c in i[1]:
162 162 opt=' '
163 163 if s: opt = opt + '-' + s + ' '
164 164 if l: opt = opt + '--' + l + ' '
165 165 if d: opt = opt + '(' + str(d) + ')'
166 166 ui.write(opt, "\n")
167 167 if c: ui.write(' %s\n' % c)
168 168 ui.write("\n")
169 169
170 170 ui.write(i[0].__doc__, "\n")
171 171 except UnknownCommand:
172 172 ui.warn("hg: unknown command %s\n" % cmd)
173 173 sys.exit(0)
174 174 else:
175 175 if not ui.quiet:
176 176 show_version(ui)
177 177 ui.write('\n')
178 178 ui.write('hg commands:\n\n')
179 179
180 180 h = {}
181 181 for c, e in table.items():
182 182 f = c.split("|")[0]
183 183 if f.startswith("debug"):
184 184 continue
185 185 d = ""
186 186 if e[0].__doc__:
187 187 d = e[0].__doc__.splitlines(0)[0].rstrip()
188 188 h[f] = d
189 189
190 190 fns = h.keys()
191 191 fns.sort()
192 192 m = max(map(len, fns))
193 193 for f in fns:
194 194 ui.write(' %-*s %s\n' % (m, f, h[f]))
195 195
196 196 # Commands start here, listed alphabetically
197 197
198 198 def add(ui, repo, file, *files):
199 199 '''add the specified files on the next commit'''
200 200 repo.add(relpath(repo, (file,) + files))
201 201
202 202 def addremove(ui, repo, *files):
203 203 """add all new files, delete all missing files"""
204 204 if files:
205 205 files = relpath(repo, files)
206 206 d = []
207 207 u = []
208 208 for f in files:
209 209 p = repo.wjoin(f)
210 210 s = repo.dirstate.state(f)
211 211 isfile = os.path.isfile(p)
212 212 if s != 'r' and not isfile:
213 213 d.append(f)
214 214 elif s not in 'nmai' and isfile:
215 215 u.append(f)
216 216 else:
217 217 (c, a, d, u) = repo.diffdir(repo.root)
218 218 repo.add(u)
219 219 repo.remove(d)
220 220
221 221 def annotate(u, repo, file, *files, **ops):
222 222 """show changeset information per file line"""
223 223 def getnode(rev):
224 224 return hg.short(repo.changelog.node(rev))
225 225
226 226 def getname(rev):
227 227 try:
228 228 return bcache[rev]
229 229 except KeyError:
230 230 cl = repo.changelog.read(repo.changelog.node(rev))
231 231 name = cl[1]
232 232 f = name.find('@')
233 233 if f >= 0:
234 234 name = name[:f]
235 235 bcache[rev] = name
236 236 return name
237 237
238 238 bcache = {}
239 239 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
240 240 if not ops['user'] and not ops['changeset']:
241 241 ops['number'] = 1
242 242
243 243 node = repo.dirstate.parents()[0]
244 244 if ops['revision']:
245 245 node = repo.changelog.lookup(ops['revision'])
246 246 change = repo.changelog.read(node)
247 247 mmap = repo.manifest.read(change[0])
248 248 for f in relpath(repo, (file,) + files):
249 249 lines = repo.file(f).annotate(mmap[f])
250 250 pieces = []
251 251
252 252 for o, f in opmap:
253 253 if ops[o]:
254 254 l = [ f(n) for n,t in lines ]
255 255 m = max(map(len, l))
256 256 pieces.append([ "%*s" % (m, x) for x in l])
257 257
258 258 for p,l in zip(zip(*pieces), lines):
259 259 u.write(" ".join(p) + ": " + l[1])
260 260
261 261 def cat(ui, repo, file, rev = []):
262 262 """output the latest or given revision of a file"""
263 263 r = repo.file(relpath(repo, [file])[0])
264 264 n = r.tip()
265 265 if rev: n = r.lookup(rev)
266 266 sys.stdout.write(r.read(n))
267 267
268 268 def clone(ui, source, dest = None, **opts):
269 269 """make a copy of an existing repository"""
270 270 source = ui.expandpath(source)
271 271
272 272 created = success = False
273 273
274 274 if dest is None:
275 275 dest = os.getcwd()
276 276 elif not os.path.exists(dest):
277 277 os.mkdir(dest)
278 278 created = True
279 279
280 280 try:
281 281 dest = os.path.realpath(dest)
282 282
283 283 link = 0
284 284 if not source.startswith("http://"):
285 285 source = os.path.realpath(source)
286 286 d1 = os.stat(dest).st_dev
287 287 d2 = os.stat(source).st_dev
288 288 if d1 == d2: link = 1
289 289
290 290 os.chdir(dest)
291 291
292 292 if link:
293 293 ui.debug("copying by hardlink\n")
294 294 util.system("cp -al %s/.hg .hg" % source)
295 295 try:
296 296 os.remove(".hg/dirstate")
297 297 except: pass
298 298
299 299 repo = hg.repository(ui, ".")
300 300
301 301 else:
302 302 repo = hg.repository(ui, ".", create=1)
303 303 other = hg.repository(ui, source)
304 304 cg = repo.getchangegroup(other)
305 305 repo.addchangegroup(cg)
306 306
307 307 f = repo.opener("hgrc", "w")
308 308 f.write("[paths]\n")
309 309 f.write("default = %s\n" % source)
310 310
311 311 if not opts['noupdate']:
312 312 update(ui, repo)
313 313
314 314 success = True
315 315
316 316 finally:
317 317 if not success:
318 318 del repo
319 319 import shutil
320 320 shutil.rmtree(dest, True)
321 321
322 322 def commit(ui, repo, *files, **opts):
323 323 """commit the specified files or all outstanding changes"""
324 324 text = opts['text']
325 325 if not text and opts['logfile']:
326 326 try: text = open(opts['logfile']).read()
327 327 except IOError: pass
328 328
329 329 if opts['addremove']:
330 330 addremove(ui, repo, *files)
331 331 repo.commit(relpath(repo, files), text, opts['user'], opts['date'])
332 332
333 333 def copy(ui, repo, source, dest):
334 334 """mark a file as copied or renamed for the next commit"""
335 335 return repo.copy(*relpath(repo, (source, dest)))
336 336
337 337 def debugcheckdirstate(ui, repo):
338 338 parent1, parent2 = repo.dirstate.parents()
339 339 dc = repo.dirstate.dup()
340 340 keys = dc.keys()
341 341 keys.sort()
342 342 m1n = repo.changelog.read(parent1)[0]
343 343 m2n = repo.changelog.read(parent2)[0]
344 344 m1 = repo.manifest.read(m1n)
345 345 m2 = repo.manifest.read(m2n)
346 346 errors = 0
347 347 for f in dc:
348 348 state = repo.dirstate.state(f)
349 349 if state in "nr" and f not in m1:
350 350 print "%s in state %s, but not listed in manifest1" % (f, state)
351 351 errors += 1
352 352 if state in "a" and f in m1:
353 353 print "%s in state %s, but also listed in manifest1" % (f, state)
354 354 errors += 1
355 355 if state in "m" and f not in m1 and f not in m2:
356 356 print "%s in state %s, but not listed in either manifest" % (f, state)
357 357 errors += 1
358 358 for f in m1:
359 359 state = repo.dirstate.state(f)
360 360 if state not in "nrm":
361 361 print "%s in manifest1, but listed as state %s" % (f, state)
362 362 errors += 1
363 363 if errors:
364 364 print ".hg/dirstate inconsistent with current parent's manifest, aborting"
365 365 sys.exit(1)
366 366
367 367 def debugdumpdirstate(ui, repo):
368 368 dc = repo.dirstate.dup()
369 369 keys = dc.keys()
370 370 keys.sort()
371 371 for file in keys:
372 372 print "%s => %c" % (file, dc[file][0])
373 373
374 374 def debugindex(ui, file):
375 375 r = hg.revlog(hg.opener(""), file, "")
376 376 print " rev offset length base linkrev"+\
377 377 " p1 p2 nodeid"
378 378 for i in range(r.count()):
379 379 e = r.index[i]
380 380 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
381 381 i, e[0], e[1], e[2], e[3],
382 382 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
383 383
384 384 def debugindexdot(ui, file):
385 385 r = hg.revlog(hg.opener(""), file, "")
386 386 print "digraph G {"
387 387 for i in range(r.count()):
388 388 e = r.index[i]
389 389 print "\t%d -> %d" % (r.rev(e[4]), i)
390 390 if e[5] != hg.nullid:
391 391 print "\t%d -> %d" % (r.rev(e[5]), i)
392 392 print "}"
393 393
394 394 def diff(ui, repo, *files, **opts):
395 395 """diff working directory (or selected files)"""
396 396 revs = []
397 397 if opts['rev']:
398 398 revs = map(lambda x: repo.lookup(x), opts['rev'])
399 399
400 400 if len(revs) > 2:
401 401 ui.warn("too many revisions to diff\n")
402 402 sys.exit(1)
403 403
404 404 if files:
405 405 files = relpath(repo, files)
406 406 else:
407 407 files = relpath(repo, [""])
408 408
409 409 dodiff(ui, repo, os.getcwd(), files, *revs)
410 410
411 411 def export(ui, repo, changeset):
412 412 """dump the changeset header and diffs for a revision"""
413 413 node = repo.lookup(changeset)
414 414 prev, other = repo.changelog.parents(node)
415 415 change = repo.changelog.read(node)
416 416 print "# HG changeset patch"
417 417 print "# User %s" % change[1]
418 418 print "# Node ID %s" % hg.hex(node)
419 419 print "# Parent %s" % hg.hex(prev)
420 420 print
421 421 if other != hg.nullid:
422 422 print "# Parent %s" % hg.hex(other)
423 423 print change[4].rstrip()
424 424 print
425 425
426 426 dodiff(ui, repo, "", None, prev, node)
427 427
428 428 def forget(ui, repo, file, *files):
429 429 """don't add the specified files on the next commit"""
430 430 repo.forget(relpath(repo, (file,) + files))
431 431
432 432 def heads(ui, repo):
433 433 """show current repository heads"""
434 434 for n in repo.changelog.heads():
435 435 show_changeset(ui, repo, changenode=n)
436 436
437 def history(ui, repo):
438 """show the changelog history"""
439 for i in range(repo.changelog.count() - 1, -1, -1):
440 show_changeset(ui, repo, rev=i)
441
442 437 def identify(ui, repo):
443 438 """print information about the working copy"""
444 439 parents = [p for p in repo.dirstate.parents() if p != hg.nullid]
445 440 if not parents:
446 441 ui.write("unknown\n")
447 442 return
448 443
449 444 hexfunc = ui.verbose and hg.hex or hg.short
450 445 (c, a, d, u) = repo.diffdir(repo.root)
451 446 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
452 447 (c or a or d) and "+" or "")]
453 448
454 449 if not ui.quiet:
455 450 # multiple tags for a single parent separated by '/'
456 451 parenttags = ['/'.join(tags)
457 452 for tags in map(repo.nodetags, parents) if tags]
458 453 # tags for multiple parents separated by ' + '
459 454 output.append(' + '.join(parenttags))
460 455
461 456 ui.write("%s\n" % ' '.join(output))
462 457
463 458 def import_(ui, repo, patch1, *patches, **opts):
464 459 """import an ordered set of patches"""
465 460 try:
466 461 import psyco
467 462 psyco.full()
468 463 except:
469 464 pass
470 465
471 466 patches = (patch1,) + patches
472 467
473 468 d = opts["base"]
474 469 strip = opts["strip"]
475 470
476 471 for patch in patches:
477 472 ui.status("applying %s\n" % patch)
478 473 pf = os.path.join(d, patch)
479 474
480 475 text = ""
481 476 for l in file(pf):
482 477 if l[:4] == "--- ": break
483 478 text += l
484 479
485 480 # make sure text isn't empty
486 481 if not text: text = "imported patch %s\n" % patch
487 482
488 483 f = os.popen("patch -p%d < %s" % (strip, pf))
489 484 files = []
490 485 for l in f.read().splitlines():
491 486 l.rstrip('\r\n');
492 487 ui.status("%s\n" % l)
493 488 if l[:14] == 'patching file ':
494 489 pf = l[14:]
495 490 if pf not in files:
496 491 files.append(pf)
497 492 patcherr = f.close()
498 493 if patcherr:
499 494 sys.stderr.write("patch failed")
500 495 sys.exit(1)
501 496
502 497 if len(files) > 0:
503 498 addremove(ui, repo, *files)
504 499 repo.commit(files, text)
505 500
506 501 def init(ui, source=None):
507 502 """create a new repository in the current directory"""
508 503
509 504 if source:
510 505 ui.warn("no longer supported: use \"hg clone\" instead\n")
511 506 sys.exit(1)
512 507 repo = hg.repository(ui, ".", create=1)
513 508
514 def log(ui, repo, f):
515 """show the revision history of a single file"""
509 def log(ui, repo, f = None):
510 """show the revision history of the repository or a single file"""
511 if f:
516 512 f = relpath(repo, [f])[0]
517
518 513 r = repo.file(f)
519 514 for i in range(r.count() - 1, -1, -1):
520 515 show_changeset(ui, repo, filelog=r, rev=i)
516 else:
517 for i in range(repo.changelog.count() - 1, -1, -1):
518 show_changeset(ui, repo, rev=i)
521 519
522 520 def manifest(ui, repo, rev = []):
523 521 """output the latest or given revision of the project manifest"""
524 522 n = repo.manifest.tip()
525 523 if rev:
526 524 n = repo.manifest.lookup(rev)
527 525 m = repo.manifest.read(n)
528 526 mf = repo.manifest.readflags(n)
529 527 files = m.keys()
530 528 files.sort()
531 529
532 530 for f in files:
533 531 ui.write("%40s %3s %s\n" % (hg.hex(m[f]), mf[f] and "755" or "644", f))
534 532
535 533 def parents(ui, repo, node = None):
536 534 '''show the parents of the current working dir'''
537 535 if node:
538 536 p = repo.changelog.parents(repo.lookup(hg.bin(node)))
539 537 else:
540 538 p = repo.dirstate.parents()
541 539
542 540 for n in p:
543 541 if n != hg.nullid:
544 542 show_changeset(ui, repo, changenode=n)
545 543
546 544 def pull(ui, repo, source="default", **opts):
547 545 """pull changes from the specified source"""
548 546 source = ui.expandpath(source)
549 547
550 548 ui.status('pulling from %s\n' % (source))
551 549
552 550 other = hg.repository(ui, source)
553 551 cg = repo.getchangegroup(other)
554 552 r = repo.addchangegroup(cg)
555 553 if cg and not r:
556 554 if opts['update']:
557 555 return update(ui, repo)
558 556 else:
559 557 ui.status("(run 'hg update' to get a working copy)\n")
560 558
561 559 return r
562 560
563 561 def push(ui, repo, dest="default-push"):
564 562 """push changes to the specified destination"""
565 563 dest = ui.expandpath(dest)
566 564
567 565 if not dest.startswith("ssh://"):
568 566 ui.warn("abort: can only push to ssh:// destinations currently\n")
569 567 return 1
570 568
571 569 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', dest)
572 570 if not m:
573 571 ui.warn("abort: couldn't parse destination %s\n" % dest)
574 572 return 1
575 573
576 574 user, host, port, path = map(m.group, (2, 3, 5, 7))
577 575 host = user and ("%s@%s" % (user, host)) or host
578 576 port = port and (" -p %s") % port or ""
579 577 path = path or ""
580 578
581 579 sport = random.randrange(30000, 60000)
582 580 cmd = "ssh %s%s -R %d:localhost:%d 'cd %s; hg pull http://localhost:%d/'"
583 581 cmd = cmd % (host, port, sport+1, sport, path, sport+1)
584 582
585 583 child = os.fork()
586 584 if not child:
587 585 sys.stdout = file("/dev/null", "w")
588 586 sys.stderr = sys.stdout
589 587 hgweb.server(repo.root, "pull", "", "localhost", sport)
590 588 else:
591 589 r = os.system(cmd)
592 590 os.kill(child, signal.SIGTERM)
593 591 return r
594 592
595 593 def rawcommit(ui, repo, *flist, **rc):
596 594 "raw commit interface"
597 595
598 596 text = rc['text']
599 597 if not text and rc['logfile']:
600 598 try: text = open(rc['logfile']).read()
601 599 except IOError: pass
602 600 if not text and not rc['logfile']:
603 601 print "missing commit text"
604 602 return 1
605 603
606 604 files = relpath(repo, list(flist))
607 605 if rc['files']:
608 606 files += open(rc['files']).read().splitlines()
609 607
610 608 rc['parent'] = map(repo.lookup, rc['parent'])
611 609
612 610 repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
613 611
614 612 def recover(ui, repo):
615 613 """roll back an interrupted transaction"""
616 614 repo.recover()
617 615
618 616 def remove(ui, repo, file, *files):
619 617 """remove the specified files on the next commit"""
620 618 repo.remove(relpath(repo, (file,) + files))
621 619
622 620 def root(ui, repo):
623 621 """print the root (top) of the current working dir"""
624 622 ui.write(repo.root + "\n")
625 623
626 624 def serve(ui, repo, **opts):
627 625 """export the repository via HTTP"""
628 626 hgweb.server(repo.root, opts["name"], opts["templates"],
629 627 opts["address"], opts["port"])
630 628
631 629 def status(ui, repo):
632 630 '''show changed files in the working directory
633 631
634 632 C = changed
635 633 A = added
636 634 R = removed
637 635 ? = not tracked'''
638 636
639 637 (c, a, d, u) = repo.diffdir(os.getcwd())
640 638 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
641 639
642 640 for f in c: print "C", f
643 641 for f in a: print "A", f
644 642 for f in d: print "R", f
645 643 for f in u: print "?", f
646 644
647 645 def tag(ui, repo, name, rev = None, **opts):
648 646 """add a tag for the current tip or a given revision"""
649 647
650 648 if name == "tip":
651 649 ui.warn("abort: 'tip' is a reserved name!\n")
652 650 return -1
653 651
654 652 (c, a, d, u) = repo.diffdir(repo.root)
655 653 for x in (c, a, d, u):
656 654 if ".hgtags" in x:
657 655 ui.warn("abort: working copy of .hgtags is changed!\n")
658 656 ui.status("(please commit .hgtags manually)\n")
659 657 return -1
660 658
661 659 if rev:
662 660 r = hg.hex(repo.lookup(rev))
663 661 else:
664 662 r = hg.hex(repo.changelog.tip())
665 663
666 664 add = 0
667 665 if not os.path.exists(repo.wjoin(".hgtags")): add = 1
668 666 repo.wfile(".hgtags", "a").write("%s %s\n" % (r, name))
669 667 if add: repo.add([".hgtags"])
670 668
671 669 if not opts['text']:
672 670 opts['text'] = "Added tag %s for changeset %s" % (name, r)
673 671
674 672 repo.commit([".hgtags"], opts['text'], opts['user'], opts['date'])
675 673
676 674 def tags(ui, repo):
677 675 """list repository tags"""
678 676
679 677 l = repo.tagslist()
680 678 l.reverse()
681 679 for t, n in l:
682 680 try:
683 681 r = "%5d:%s" % (repo.changelog.rev(n), hg.hex(n))
684 682 except KeyError:
685 683 r = " ?:?"
686 684 ui.write("%-30s %s\n" % (t, r))
687 685
688 686 def tip(ui, repo):
689 687 """show the tip revision"""
690 688 n = repo.changelog.tip()
691 689 show_changeset(ui, repo, changenode=n)
692 690
693 691 def undo(ui, repo):
694 692 """undo the last transaction"""
695 693 repo.undo()
696 694
697 695 def update(ui, repo, node=None, merge=False, clean=False):
698 696 '''update or merge working directory
699 697
700 698 If there are no outstanding changes in the working directory and
701 699 there is a linear relationship between the current version and the
702 700 requested version, the result is the requested version.
703 701
704 702 Otherwise the result is a merge between the contents of the
705 703 current working directory and the requested version. Files that
706 704 changed between either parent are marked as changed for the next
707 705 commit and a commit must be performed before any further updates
708 706 are allowed.
709 707 '''
710 708 node = node and repo.lookup(node) or repo.changelog.tip()
711 709 return repo.update(node, allow=merge, force=clean)
712 710
713 711 def verify(ui, repo):
714 712 """verify the integrity of the repository"""
715 713 return repo.verify()
716 714
717 715 # Command options and aliases are listed here, alphabetically
718 716
719 717 table = {
720 718 "add": (add, [], "hg add [files]"),
721 719 "addremove": (addremove, [], "hg addremove [files]"),
722 720 "annotate": (annotate,
723 721 [('r', 'revision', '', 'revision'),
724 722 ('u', 'user', None, 'show user'),
725 723 ('n', 'number', None, 'show revision number'),
726 724 ('c', 'changeset', None, 'show changeset')],
727 725 'hg annotate [-u] [-c] [-n] [-r id] [files]'),
728 726 "cat": (cat, [], 'hg cat <file> [rev]'),
729 727 "clone": (clone, [('U', 'noupdate', None, 'skip update after cloning')],
730 728 'hg clone [options] <source> [dest]'),
731 729 "commit|ci": (commit,
732 730 [('t', 'text', "", 'commit text'),
733 731 ('A', 'addremove', None, 'run add/remove during commit'),
734 732 ('l', 'logfile', "", 'commit text file'),
735 733 ('d', 'date', "", 'data'),
736 734 ('u', 'user', "", 'user')],
737 735 'hg commit [files]'),
738 736 "copy": (copy, [], 'hg copy <source> <dest>'),
739 737 "debugcheckdirstate": (debugcheckdirstate, [], 'debugcheckdirstate'),
740 738 "debugdumpdirstate": (debugdumpdirstate, [], 'debugdumpdirstate'),
741 739 "debugindex": (debugindex, [], 'debugindex <file>'),
742 740 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'),
743 741 "diff": (diff, [('r', 'rev', [], 'revision')],
744 742 'hg diff [-r A] [-r B] [files]'),
745 743 "export": (export, [], "hg export <changeset>"),
746 744 "forget": (forget, [], "hg forget [files]"),
747 745 "heads": (heads, [], 'hg heads'),
748 "history": (history, [], 'hg history'),
749 746 "help": (help, [], 'hg help [command]'),
750 747 "identify|id": (identify, [], 'hg identify'),
751 748 "import|patch": (import_,
752 749 [('p', 'strip', 1, 'path strip'),
753 750 ('b', 'base', "", 'base path')],
754 751 "hg import [options] <patches>"),
755 752 "init": (init, [], 'hg init'),
756 "log": (log, [], 'hg log <file>'),
753 "log|history": (log, [], 'hg log [file]'),
757 754 "manifest": (manifest, [], 'hg manifest [rev]'),
758 755 "parents": (parents, [], 'hg parents [node]'),
759 756 "pull": (pull,
760 757 [('u', 'update', None, 'update working directory')],
761 758 'hg pull [options] [source]'),
762 759 "push": (push, [], 'hg push <destination>'),
763 760 "rawcommit": (rawcommit,
764 761 [('p', 'parent', [], 'parent'),
765 762 ('d', 'date', "", 'data'),
766 763 ('u', 'user', "", 'user'),
767 764 ('F', 'files', "", 'file list'),
768 765 ('t', 'text', "", 'commit text'),
769 766 ('l', 'logfile', "", 'commit text file')],
770 767 'hg rawcommit [options] [files]'),
771 768 "recover": (recover, [], "hg recover"),
772 769 "remove|rm": (remove, [], "hg remove [files]"),
773 770 "root": (root, [], "hg root"),
774 771 "serve": (serve, [('p', 'port', 8000, 'listen port'),
775 772 ('a', 'address', '', 'interface address'),
776 773 ('n', 'name', os.getcwd(), 'repository name'),
777 774 ('t', 'templates', "", 'template map')],
778 775 "hg serve [options]"),
779 776 "status": (status, [], 'hg status'),
780 777 "tag": (tag, [('t', 'text', "", 'commit text'),
781 778 ('d', 'date', "", 'date'),
782 779 ('u', 'user', "", 'user')],
783 780 'hg tag [options] <name> [rev]'),
784 781 "tags": (tags, [], 'hg tags'),
785 782 "tip": (tip, [], 'hg tip'),
786 783 "undo": (undo, [], 'hg undo'),
787 784 "update|up|checkout|co":
788 785 (update,
789 786 [('m', 'merge', None, 'allow merging of conflicts'),
790 787 ('C', 'clean', None, 'overwrite locally modified files')],
791 788 'hg update [options] [node]'),
792 789 "verify": (verify, [], 'hg verify'),
793 790 "version": (show_version, [], 'hg version'),
794 791 }
795 792
796 793 norepo = "clone init version help debugindex debugindexdot"
797 794
798 795 def find(cmd):
799 796 for e in table.keys():
800 797 if re.match("(%s)$" % e, cmd):
801 798 return table[e]
802 799
803 800 raise UnknownCommand(cmd)
804 801
805 802 class SignalInterrupt(Exception): pass
806 803
807 804 def catchterm(*args):
808 805 raise SignalInterrupt
809 806
810 807 def run():
811 808 sys.exit(dispatch(sys.argv[1:]))
812 809
813 810 def dispatch(args):
814 811 options = {}
815 812 opts = [('v', 'verbose', None, 'verbose'),
816 813 ('d', 'debug', None, 'debug'),
817 814 ('q', 'quiet', None, 'quiet'),
818 815 ('p', 'profile', None, 'profile'),
819 816 ('y', 'noninteractive', None, 'run non-interactively'),
820 817 ('', 'version', None, 'output version information and exit'),
821 818 ]
822 819
823 820 args = fancyopts.fancyopts(args, opts, options,
824 821 'hg [options] <command> [options] [files]')
825 822
826 823 if not args:
827 824 cmd = "help"
828 825 else:
829 826 cmd, args = args[0], args[1:]
830 827
831 828 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
832 829 not options["noninteractive"])
833 830
834 831 if options["version"]:
835 832 show_version(u)
836 833 sys.exit(0)
837 834
838 835 try:
839 836 i = find(cmd)
840 837 except UnknownCommand:
841 838 u.warn("hg: unknown command '%s'\n" % cmd)
842 839 help(u)
843 840 sys.exit(1)
844 841
845 842 signal.signal(signal.SIGTERM, catchterm)
846 843
847 844 cmdoptions = {}
848 845 try:
849 846 args = fancyopts.fancyopts(args, i[1], cmdoptions, i[2])
850 847 except fancyopts.getopt.GetoptError, inst:
851 848 u.warn("hg %s: %s\n" % (cmd, inst))
852 849 help(u, cmd)
853 850 sys.exit(-1)
854 851
855 852 try:
856 853 if cmd not in norepo.split():
857 854 repo = hg.repository(ui = u)
858 855 d = lambda: i[0](u, repo, *args, **cmdoptions)
859 856 else:
860 857 d = lambda: i[0](u, *args, **cmdoptions)
861 858
862 859 if options['profile']:
863 860 import hotshot, hotshot.stats
864 861 prof = hotshot.Profile("hg.prof")
865 862 r = prof.runcall(d)
866 863 prof.close()
867 864 stats = hotshot.stats.load("hg.prof")
868 865 stats.strip_dirs()
869 866 stats.sort_stats('time', 'calls')
870 867 stats.print_stats(40)
871 868 return r
872 869 else:
873 870 return d()
874 871 except util.CommandError, inst:
875 872 u.warn("abort: %s\n" % inst.args)
876 873 except hg.RepoError, inst:
877 874 u.warn("abort: ", inst, "!\n")
878 875 except SignalInterrupt:
879 876 u.warn("killed!\n")
880 877 except KeyboardInterrupt:
881 878 u.warn("interrupted!\n")
882 879 except IOError, inst:
883 880 if hasattr(inst, "code"):
884 881 u.warn("abort: %s\n" % inst)
885 882 elif hasattr(inst, "reason"):
886 883 u.warn("abort: error %d: %s\n" % (inst.reason[0], inst.reason[1]))
887 884 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
888 885 u.warn("broken pipe\n")
889 886 else:
890 887 raise
891 888 except TypeError, inst:
892 889 # was this an argument error?
893 890 tb = traceback.extract_tb(sys.exc_info()[2])
894 891 if len(tb) > 2: # no
895 892 raise
896 893 u.debug(inst, "\n")
897 894 u.warn("%s: invalid arguments\n" % i[0].__name__)
898 895 help(u, cmd)
899 896
900 897 sys.exit(-1)
901 898
@@ -1,90 +1,88 b''
1 1 + hg -q help
2 2 hg commands:
3 3
4 4 add add the specified files on the next commit
5 5 addremove add all new files, delete all missing files
6 6 annotate show changeset information per file line
7 7 cat output the latest or given revision of a file
8 8 clone make a copy of an existing repository
9 9 commit commit the specified files or all outstanding changes
10 10 copy mark a file as copied or renamed for the next commit
11 11 diff diff working directory (or selected files)
12 12 export dump the changeset header and diffs for a revision
13 13 forget don't add the specified files on the next commit
14 14 heads show current repository heads
15 15 help show help for a given command or all commands
16 history show the changelog history
17 16 identify print information about the working copy
18 17 import import an ordered set of patches
19 18 init create a new repository in the current directory
20 log show the revision history of a single file
19 log show the revision history of the repository or a single file
21 20 manifest output the latest or given revision of the project manifest
22 21 parents show the parents of the current working dir
23 22 pull pull changes from the specified source
24 23 push push changes to the specified destination
25 24 rawcommit raw commit interface
26 25 recover roll back an interrupted transaction
27 26 remove remove the specified files on the next commit
28 27 root print the root (top) of the current working dir
29 28 serve export the repository via HTTP
30 29 status show changed files in the working directory
31 30 tag add a tag for the current tip or a given revision
32 31 tags list repository tags
33 32 tip show the tip revision
34 33 undo undo the last transaction
35 34 update update or merge working directory
36 35 verify verify the integrity of the repository
37 36 version output version and copyright information
38 37 + hg add -h
39 38 hg add: option -h not recognized
40 39 hg add [files]
41 40
42 41 add the specified files on the next commit
43 42 + hg help diff
44 43 hg diff [-r A] [-r B] [files]
45 44
46 45 -r --rev
47 46 revision
48 47
49 48 diff working directory (or selected files)
50 49 + hg help foo
51 50 hg: unknown command foo
52 51 + hg -q commands
53 52 hg: unknown command 'commands'
54 53 hg commands:
55 54
56 55 add add the specified files on the next commit
57 56 addremove add all new files, delete all missing files
58 57 annotate show changeset information per file line
59 58 cat output the latest or given revision of a file
60 59 clone make a copy of an existing repository
61 60 commit commit the specified files or all outstanding changes
62 61 copy mark a file as copied or renamed for the next commit
63 62 diff diff working directory (or selected files)
64 63 export dump the changeset header and diffs for a revision
65 64 forget don't add the specified files on the next commit
66 65 heads show current repository heads
67 66 help show help for a given command or all commands
68 history show the changelog history
69 67 identify print information about the working copy
70 68 import import an ordered set of patches
71 69 init create a new repository in the current directory
72 log show the revision history of a single file
70 log show the revision history of the repository or a single file
73 71 manifest output the latest or given revision of the project manifest
74 72 parents show the parents of the current working dir
75 73 pull pull changes from the specified source
76 74 push push changes to the specified destination
77 75 rawcommit raw commit interface
78 76 recover roll back an interrupted transaction
79 77 remove remove the specified files on the next commit
80 78 root print the root (top) of the current working dir
81 79 serve export the repository via HTTP
82 80 status show changed files in the working directory
83 81 tag add a tag for the current tip or a given revision
84 82 tags list repository tags
85 83 tip show the tip revision
86 84 undo undo the last transaction
87 85 update update or merge working directory
88 86 verify verify the integrity of the repository
89 87 version output version and copyright information
90 88 + exit 0
General Comments 0
You need to be logged in to leave comments. Login now