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