Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/commands.py @ 687:44b30755d07c
Hide file hashes in log
There are six different kinds of revision numbers and hashes:
changeset hash and local number
manifest hash and local number
file hash and local number
We really ought to expose only the changeset hash and local number, so
begin hiding the others from the end user
manifest hash: 40d07cc930e84a9283d5e03ade23e3454401e148
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Tue, 12 Jul 2005 20:55:42 -0800 |
parents | 0cfc5966b2c2 |
children | 4315db147f00 |
rev | line source |
---|---|
249 | 1 # commands.py - command processing for mercurial |
2 # | |
3 # Copyright 2005 Matt Mackall <mpm@selenic.com> | |
4 # | |
5 # This software may be used and distributed according to the terms | |
6 # of the GNU General Public License, incorporated herein by reference. | |
7 | |
262 | 8 from demandload import * |
613
5374955ec5b1
Demand-load most modules in the commands and ui modules.
Bryan O'Sullivan <bos@serpentine.com>
parents:
612
diff
changeset
|
9 demandload(globals(), "os re sys signal") |
5374955ec5b1
Demand-load most modules in the commands and ui modules.
Bryan O'Sullivan <bos@serpentine.com>
parents:
612
diff
changeset
|
10 demandload(globals(), "fancyopts ui hg util") |
627 | 11 demandload(globals(), "fnmatch hgweb mdiff random signal time traceback") |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
12 demandload(globals(), "errno socket version struct") |
209 | 13 |
14 class UnknownCommand(Exception): pass | |
15 | |
245 | 16 def filterfiles(filters, files): |
17 l = [ x for x in files if x in filters ] | |
213 | 18 |
245 | 19 for t in filters: |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
417
diff
changeset
|
20 if t and t[-1] != "/": t += "/" |
245 | 21 l += [ x for x in files if x.startswith(t) ] |
213 | 22 return l |
23 | |
245 | 24 def relfilter(repo, files): |
628
8d7f6e68828a
Use repo.getcwd() in a few obvious places.
Bryan O'Sullivan <bos@serpentine.com>
parents:
627
diff
changeset
|
25 cwd = repo.getcwd() |
8d7f6e68828a
Use repo.getcwd() in a few obvious places.
Bryan O'Sullivan <bos@serpentine.com>
parents:
627
diff
changeset
|
26 if cwd: |
8d7f6e68828a
Use repo.getcwd() in a few obvious places.
Bryan O'Sullivan <bos@serpentine.com>
parents:
627
diff
changeset
|
27 return filterfiles([util.pconvert(cwd)], files) |
245 | 28 return files |
213 | 29 |
209 | 30 def relpath(repo, args): |
628
8d7f6e68828a
Use repo.getcwd() in a few obvious places.
Bryan O'Sullivan <bos@serpentine.com>
parents:
627
diff
changeset
|
31 cwd = repo.getcwd() |
8d7f6e68828a
Use repo.getcwd() in a few obvious places.
Bryan O'Sullivan <bos@serpentine.com>
parents:
627
diff
changeset
|
32 if cwd: |
8d7f6e68828a
Use repo.getcwd() in a few obvious places.
Bryan O'Sullivan <bos@serpentine.com>
parents:
627
diff
changeset
|
33 return [ util.pconvert(os.path.normpath(os.path.join(cwd, x))) for x in args ] |
209 | 34 return args |
245 | 35 |
580 | 36 revrangesep = ':' |
37 | |
38 def revrange(ui, repo, revs = [], revlog = None): | |
39 if revlog is None: | |
40 revlog = repo.changelog | |
41 revcount = revlog.count() | |
42 def fix(val, defval): | |
43 if not val: return defval | |
44 try: | |
45 num = int(val) | |
46 if str(num) != val: raise ValueError | |
47 if num < 0: num += revcount | |
48 if not (0 <= num < revcount): | |
49 raise ValueError | |
50 except ValueError: | |
51 try: | |
52 num = repo.changelog.rev(repo.lookup(val)) | |
53 except KeyError: | |
54 try: | |
55 num = revlog.rev(revlog.lookup(val)) | |
56 except KeyError: | |
57 ui.warn('abort: invalid revision identifier %s\n' % val) | |
58 sys.exit(1) | |
59 return num | |
60 for spec in revs: | |
61 if spec.find(revrangesep) >= 0: | |
62 start, end = spec.split(revrangesep, 1) | |
63 start = fix(start, 0) | |
64 end = fix(end, revcount - 1) | |
65 if end > start: | |
66 end += 1 | |
67 step = 1 | |
68 else: | |
69 end -= 1 | |
70 step = -1 | |
71 for rev in xrange(start, end, step): | |
72 yield str(rev) | |
73 else: | |
74 yield spec | |
75 | |
632 | 76 def make_filename(repo, r, pat, node=None, |
77 total=None, seqno=None, revwidth=None): | |
78 node_expander = { | |
79 'H': lambda: hg.hex(node), | |
80 'R': lambda: str(r.rev(node)), | |
81 'h': lambda: hg.short(node), | |
82 } | |
83 expander = { | |
84 '%': lambda: '%', | |
85 'b': lambda: os.path.basename(repo.root), | |
86 } | |
87 | |
88 if node: expander.update(node_expander) | |
89 if node and revwidth is not None: | |
90 expander['r'] = lambda: str(r.rev(node)).zfill(revwidth) | |
91 if total is not None: expander['N'] = lambda: str(total) | |
92 if seqno is not None: expander['n'] = lambda: str(seqno) | |
93 if total is not None and seqno is not None: | |
94 expander['n'] = lambda:str(seqno).zfill(len(str(total))) | |
95 | |
96 newname = [] | |
97 patlen = len(pat) | |
98 i = 0 | |
99 while i < patlen: | |
100 c = pat[i] | |
101 if c == '%': | |
102 i += 1 | |
103 c = pat[i] | |
104 c = expander[c]() | |
105 newname.append(c) | |
106 i += 1 | |
107 return ''.join(newname) | |
108 | |
580 | 109 def dodiff(fp, ui, repo, files = None, node1 = None, node2 = None): |
245 | 110 def date(c): |
111 return time.asctime(time.gmtime(float(c[2].split(' ')[0]))) | |
112 | |
561 | 113 (c, a, d, u) = repo.changes(node1, node2, files) |
537 | 114 if files: |
115 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d)) | |
116 | |
117 if not c and not a and not d: | |
118 return | |
119 | |
245 | 120 if node2: |
121 change = repo.changelog.read(node2) | |
122 mmap2 = repo.manifest.read(change[0]) | |
123 def read(f): return repo.file(f).read(mmap2[f]) | |
124 date2 = date(change) | |
125 else: | |
126 date2 = time.asctime() | |
127 if not node1: | |
128 node1 = repo.dirstate.parents()[0] | |
417 | 129 def read(f): return repo.wfile(f).read() |
245 | 130 |
396
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
395
diff
changeset
|
131 if ui.quiet: |
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
395
diff
changeset
|
132 r = None |
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
395
diff
changeset
|
133 else: |
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
395
diff
changeset
|
134 hexfunc = ui.verbose and hg.hex or hg.short |
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
395
diff
changeset
|
135 r = [hexfunc(node) for node in [node1, node2] if node] |
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
395
diff
changeset
|
136 |
245 | 137 change = repo.changelog.read(node1) |
138 mmap = repo.manifest.read(change[0]) | |
139 date1 = date(change) | |
140 | |
141 for f in c: | |
275 | 142 to = None |
143 if f in mmap: | |
144 to = repo.file(f).read(mmap[f]) | |
245 | 145 tn = read(f) |
580 | 146 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r)) |
245 | 147 for f in a: |
264
4c1d7072d5cd
Attempt to make diff deal with null sources properly
mpm@selenic.com
parents:
262
diff
changeset
|
148 to = None |
245 | 149 tn = read(f) |
580 | 150 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r)) |
245 | 151 for f in d: |
152 to = repo.file(f).read(mmap[f]) | |
264
4c1d7072d5cd
Attempt to make diff deal with null sources properly
mpm@selenic.com
parents:
262
diff
changeset
|
153 tn = None |
580 | 154 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r)) |
329
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
155 |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
156 def show_changeset(ui, repo, rev=0, changenode=None, filelog=None): |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
157 """show a single changeset or file revision""" |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
158 changelog = repo.changelog |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
159 if filelog: |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
160 log = filelog |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
161 filerev = rev |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
162 node = filenode = filelog.node(filerev) |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
163 changerev = filelog.linkrev(filenode) |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
164 changenode = changenode or changelog.node(changerev) |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
165 else: |
347
a0b2758edee7
Cleaned up show_changeset()
Thomas Arendsen Hein <thomas@intevation.de>
parents:
330
diff
changeset
|
166 log = changelog |
329
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
167 changerev = rev |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
168 if changenode is None: |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
169 changenode = changelog.node(changerev) |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
170 elif not changerev: |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
171 rev = changerev = changelog.rev(changenode) |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
172 node = changenode |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
173 |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
174 if ui.quiet: |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
175 ui.write("%d:%s\n" % (rev, hg.hex(node))) |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
176 return |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
177 |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
178 changes = changelog.read(changenode) |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
179 |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
180 parents = [(log.rev(parent), hg.hex(parent)) |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
181 for parent in log.parents(node) |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
182 if ui.debugflag or parent != hg.nullid] |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
183 if not ui.debugflag and len(parents) == 1 and parents[0][0] == rev-1: |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
184 parents = [] |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
185 |
687 | 186 ui.write("changeset: %d:%s\n" % (changerev, hg.hex(changenode))) |
187 for tag in repo.nodetags(changenode): | |
188 ui.status("tag: %s\n" % tag) | |
189 for parent in parents: | |
190 ui.write("parent: %d:%s\n" % parent) | |
329
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
191 if filelog: |
687 | 192 ui.debug("file rev: %d:%s\n" % (filerev, hg.hex(filenode))) |
193 ui.note("manifest: %d:%s\n" % (repo.manifest.rev(changes[0]), | |
194 hg.hex(changes[0]))) | |
329
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
195 ui.status("user: %s\n" % changes[1]) |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
196 ui.status("date: %s\n" % time.asctime( |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
197 time.localtime(float(changes[2].split(' ')[0])))) |
493
30752b14f759
Make show_changeset show added/deleted files only in debug mode.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
490
diff
changeset
|
198 if ui.debugflag: |
536 | 199 files = repo.changes(changelog.parents(changenode)[0], changenode) |
490
df9b77f67998
Make show_changeset show added and deleted files in verbose mode.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
485
diff
changeset
|
200 for key, value in zip(["files:", "files+:", "files-:"], files): |
df9b77f67998
Make show_changeset show added and deleted files in verbose mode.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
485
diff
changeset
|
201 if value: |
df9b77f67998
Make show_changeset show added and deleted files in verbose mode.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
485
diff
changeset
|
202 ui.note("%-12s %s\n" % (key, " ".join(value))) |
493
30752b14f759
Make show_changeset show added/deleted files only in debug mode.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
490
diff
changeset
|
203 else: |
30752b14f759
Make show_changeset show added/deleted files only in debug mode.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
490
diff
changeset
|
204 ui.note("files: %s\n" % " ".join(changes[3])) |
347
a0b2758edee7
Cleaned up show_changeset()
Thomas Arendsen Hein <thomas@intevation.de>
parents:
330
diff
changeset
|
205 description = changes[4].strip() |
329
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
206 if description: |
330 | 207 if ui.verbose: |
208 ui.status("description:\n") | |
347
a0b2758edee7
Cleaned up show_changeset()
Thomas Arendsen Hein <thomas@intevation.de>
parents:
330
diff
changeset
|
209 ui.status(description) |
546
c8ae964109c1
Add an empty line after description in verbose mode of show_changeset.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
542
diff
changeset
|
210 ui.status("\n\n") |
330 | 211 else: |
347
a0b2758edee7
Cleaned up show_changeset()
Thomas Arendsen Hein <thomas@intevation.de>
parents:
330
diff
changeset
|
212 ui.status("summary: %s\n" % description.splitlines()[0]) |
329
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
213 ui.status("\n") |
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
214 |
470
0ab093b473c5
Fix up version module name and command conflict
mpm@selenic.com
parents:
468
diff
changeset
|
215 def show_version(ui): |
423
25afb21d97ba
Support for 'hg --version'. setup.py stores version from hg repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
396
diff
changeset
|
216 """output version and copyright information""" |
25afb21d97ba
Support for 'hg --version'. setup.py stores version from hg repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
396
diff
changeset
|
217 ui.write("Mercurial version %s\n" % version.get_version()) |
25afb21d97ba
Support for 'hg --version'. setup.py stores version from hg repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
396
diff
changeset
|
218 ui.status( |
25afb21d97ba
Support for 'hg --version'. setup.py stores version from hg repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
396
diff
changeset
|
219 "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n" |
25afb21d97ba
Support for 'hg --version'. setup.py stores version from hg repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
396
diff
changeset
|
220 "This is free software; see the source for copying conditions. " |
25afb21d97ba
Support for 'hg --version'. setup.py stores version from hg repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
396
diff
changeset
|
221 "There is NO\nwarranty; " |
25afb21d97ba
Support for 'hg --version'. setup.py stores version from hg repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
396
diff
changeset
|
222 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" |
25afb21d97ba
Support for 'hg --version'. setup.py stores version from hg repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
396
diff
changeset
|
223 ) |
25afb21d97ba
Support for 'hg --version'. setup.py stores version from hg repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
396
diff
changeset
|
224 |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
225 def help(ui, cmd=None): |
255 | 226 '''show help for a given command or all commands''' |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
227 if cmd: |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
228 try: |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
229 i = find(cmd) |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
230 ui.write("%s\n\n" % i[2]) |
293 | 231 |
232 if i[1]: | |
233 for s, l, d, c in i[1]: | |
234 opt=' ' | |
235 if s: opt = opt + '-' + s + ' ' | |
236 if l: opt = opt + '--' + l + ' ' | |
237 if d: opt = opt + '(' + str(d) + ')' | |
238 ui.write(opt, "\n") | |
239 if c: ui.write(' %s\n' % c) | |
240 ui.write("\n") | |
241 | |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
242 ui.write(i[0].__doc__, "\n") |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
243 except UnknownCommand: |
268 | 244 ui.warn("hg: unknown command %s\n" % cmd) |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
245 sys.exit(0) |
255 | 246 else: |
593 | 247 if ui.verbose: |
470
0ab093b473c5
Fix up version module name and command conflict
mpm@selenic.com
parents:
468
diff
changeset
|
248 show_version(ui) |
423
25afb21d97ba
Support for 'hg --version'. setup.py stores version from hg repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
396
diff
changeset
|
249 ui.write('\n') |
593 | 250 if ui.verbose: |
251 ui.write('hg commands:\n\n') | |
252 else: | |
596 | 253 ui.write('basic hg commands (use "hg help -v" for more):\n\n') |
209 | 254 |
255 | 255 h = {} |
479
7293cb91bf2a
Cleaned up command alias handling in help.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
477
diff
changeset
|
256 for c, e in table.items(): |
7293cb91bf2a
Cleaned up command alias handling in help.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
477
diff
changeset
|
257 f = c.split("|")[0] |
593 | 258 if not ui.verbose and not f.startswith("^"): |
479
7293cb91bf2a
Cleaned up command alias handling in help.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
477
diff
changeset
|
259 continue |
593 | 260 if not ui.debugflag and f.startswith("debug"): |
261 continue | |
262 f = f.lstrip("^") | |
255 | 263 d = "" |
470
0ab093b473c5
Fix up version module name and command conflict
mpm@selenic.com
parents:
468
diff
changeset
|
264 if e[0].__doc__: |
0ab093b473c5
Fix up version module name and command conflict
mpm@selenic.com
parents:
468
diff
changeset
|
265 d = e[0].__doc__.splitlines(0)[0].rstrip() |
0ab093b473c5
Fix up version module name and command conflict
mpm@selenic.com
parents:
468
diff
changeset
|
266 h[f] = d |
255 | 267 |
268 fns = h.keys() | |
269 fns.sort() | |
270 m = max(map(len, fns)) | |
271 for f in fns: | |
423
25afb21d97ba
Support for 'hg --version'. setup.py stores version from hg repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
396
diff
changeset
|
272 ui.write(' %-*s %s\n' % (m, f, h[f])) |
255 | 273 |
274 # Commands start here, listed alphabetically | |
209 | 275 |
245 | 276 def add(ui, repo, file, *files): |
277 '''add the specified files on the next commit''' | |
278 repo.add(relpath(repo, (file,) + files)) | |
213 | 279 |
353 | 280 def addremove(ui, repo, *files): |
255 | 281 """add all new files, delete all missing files""" |
353 | 282 if files: |
283 files = relpath(repo, files) | |
284 d = [] | |
285 u = [] | |
286 for f in files: | |
287 p = repo.wjoin(f) | |
288 s = repo.dirstate.state(f) | |
289 isfile = os.path.isfile(p) | |
290 if s != 'r' and not isfile: | |
291 d.append(f) | |
292 elif s not in 'nmai' and isfile: | |
293 u.append(f) | |
294 else: | |
536 | 295 (c, a, d, u) = repo.changes(None, None) |
259 | 296 repo.add(u) |
245 | 297 repo.remove(d) |
219
8ff4532376a4
hg checkout: refuse to checkout if there are outstanding changes
mpm@selenic.com
parents:
214
diff
changeset
|
298 |
245 | 299 def annotate(u, repo, file, *files, **ops): |
255 | 300 """show changeset information per file line""" |
209 | 301 def getnode(rev): |
302 return hg.short(repo.changelog.node(rev)) | |
303 | |
304 def getname(rev): | |
305 try: | |
306 return bcache[rev] | |
307 except KeyError: | |
308 cl = repo.changelog.read(repo.changelog.node(rev)) | |
309 name = cl[1] | |
310 f = name.find('@') | |
311 if f >= 0: | |
312 name = name[:f] | |
534
ab0d1bfeee7c
[PATCH] Handle 'name firstname <email@server>' correctly in annotate
mpm@selenic.com
parents:
532
diff
changeset
|
313 f = name.find('<') |
ab0d1bfeee7c
[PATCH] Handle 'name firstname <email@server>' correctly in annotate
mpm@selenic.com
parents:
532
diff
changeset
|
314 if f >= 0: |
ab0d1bfeee7c
[PATCH] Handle 'name firstname <email@server>' correctly in annotate
mpm@selenic.com
parents:
532
diff
changeset
|
315 name = name[f+1:] |
209 | 316 bcache[rev] = name |
317 return name | |
500
ebc4714a7632
[PATCH] Clean up destination directory if a clone fails.
mpm@selenic.com
parents:
499
diff
changeset
|
318 |
209 | 319 bcache = {} |
320 opmap = [['user', getname], ['number', str], ['changeset', getnode]] | |
321 if not ops['user'] and not ops['changeset']: | |
322 ops['number'] = 1 | |
323 | |
227 | 324 node = repo.dirstate.parents()[0] |
209 | 325 if ops['revision']: |
326 node = repo.changelog.lookup(ops['revision']) | |
327 change = repo.changelog.read(node) | |
328 mmap = repo.manifest.read(change[0]) | |
245 | 329 for f in relpath(repo, (file,) + files): |
209 | 330 lines = repo.file(f).annotate(mmap[f]) |
331 pieces = [] | |
332 | |
333 for o, f in opmap: | |
334 if ops[o]: | |
335 l = [ f(n) for n,t in lines ] | |
336 m = max(map(len, l)) | |
337 pieces.append([ "%*s" % (m, x) for x in l]) | |
338 | |
339 for p,l in zip(zip(*pieces), lines): | |
340 u.write(" ".join(p) + ": " + l[1]) | |
341 | |
632 | 342 def cat(ui, repo, file, rev = [], **opts): |
255 | 343 """output the latest or given revision of a file""" |
281 | 344 r = repo.file(relpath(repo, [file])[0]) |
248 | 345 n = r.tip() |
346 if rev: n = r.lookup(rev) | |
632 | 347 if opts['output'] and opts['output'] != '-': |
348 try: | |
349 outname = make_filename(repo, r, opts['output'], node=n) | |
350 fp = open(outname, 'wb') | |
351 except KeyError, inst: | |
352 ui.warn("error: invlaid format spec '%%%s' in output file name\n" % | |
353 inst.args[0]) | |
354 sys.exit(1); | |
355 else: | |
356 fp = sys.stdout | |
357 fp.write(r.read(n)) | |
248 | 358 |
485 | 359 def clone(ui, source, dest = None, **opts): |
360 """make a copy of an existing repository""" | |
361 if dest is None: | |
528 | 362 dest = os.path.basename(os.path.normpath(source)) |
532
2e9698a5c92c
clone: abort on pre-existing destination directory
mpm@selenic.com
parents:
528
diff
changeset
|
363 |
2e9698a5c92c
clone: abort on pre-existing destination directory
mpm@selenic.com
parents:
528
diff
changeset
|
364 if os.path.exists(dest): |
2e9698a5c92c
clone: abort on pre-existing destination directory
mpm@selenic.com
parents:
528
diff
changeset
|
365 ui.warn("abort: destination '%s' already exists\n" % dest) |
2e9698a5c92c
clone: abort on pre-existing destination directory
mpm@selenic.com
parents:
528
diff
changeset
|
366 return 1 |
523
003df62ae39f
[PATCH] Force "hg clone" to always create a new directory
mpm@selenic.com
parents:
522
diff
changeset
|
367 |
535
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
368 class dircleanup: |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
369 def __init__(self, dir): |
625 | 370 import shutil |
371 self.rmtree = shutil.rmtree | |
535
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
372 self.dir = dir |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
373 os.mkdir(dir) |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
374 def close(self): |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
375 self.dir = None |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
376 def __del__(self): |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
377 if self.dir: |
625 | 378 self.rmtree(self.dir, True) |
485 | 379 |
535
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
380 d = dircleanup(dest) |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
381 link = 0 |
562
be6233a2bfdd
hg clone: only use the absolute path for .hg/hgrc
mpm@selenic.com
parents:
561
diff
changeset
|
382 abspath = source |
634
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
632
diff
changeset
|
383 source = ui.expandpath(source) |
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
632
diff
changeset
|
384 other = hg.repository(ui, source) |
485 | 385 |
675
49de76abc4da
hg clone stored path fix
Mikael Berthe <mikael@lilotux.net>
parents:
674
diff
changeset
|
386 if other.dev() != -1: |
49de76abc4da
hg clone stored path fix
Mikael Berthe <mikael@lilotux.net>
parents:
674
diff
changeset
|
387 abspath = os.path.abspath(source) |
49de76abc4da
hg clone stored path fix
Mikael Berthe <mikael@lilotux.net>
parents:
674
diff
changeset
|
388 |
634
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
632
diff
changeset
|
389 if other.dev() != -1 and os.stat(dest).st_dev == other.dev(): |
654
fafc16f705b6
Make cloning by hardlink quiet again
Matt Mackall <mpm@selenic.com>
parents:
643
diff
changeset
|
390 ui.note("cloning by hardlink\n") |
535
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
391 util.system("cp -al '%s'/.hg '%s'/.hg" % (source, dest)) |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
392 try: |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
393 os.remove(os.path.join(dest, ".hg", "dirstate")) |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
394 except: pass |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
395 |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
396 repo = hg.repository(ui, dest) |
485 | 397 |
535
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
398 else: |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
399 repo = hg.repository(ui, dest, create=1) |
625 | 400 repo.pull(other) |
503
c6a2e41c8c60
Fix troubles with clone and exception handling
mpm@selenic.com
parents:
500
diff
changeset
|
401 |
535
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
402 f = repo.opener("hgrc", "w") |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
403 f.write("[paths]\n") |
562
be6233a2bfdd
hg clone: only use the absolute path for .hg/hgrc
mpm@selenic.com
parents:
561
diff
changeset
|
404 f.write("default = %s\n" % abspath) |
515 | 405 |
535
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
406 if not opts['noupdate']: |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
407 update(ui, repo) |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
408 |
fba26990604a
Deal with failed clone/transaction interaction
mpm@selenic.com
parents:
534
diff
changeset
|
409 d.close() |
515 | 410 |
289 | 411 def commit(ui, repo, *files, **opts): |
245 | 412 """commit the specified files or all outstanding changes""" |
289 | 413 text = opts['text'] |
414 if not text and opts['logfile']: | |
415 try: text = open(opts['logfile']).read() | |
416 except IOError: pass | |
417 | |
354 | 418 if opts['addremove']: |
419 addremove(ui, repo, *files) | |
317 | 420 repo.commit(relpath(repo, files), text, opts['user'], opts['date']) |
245 | 421 |
363 | 422 def copy(ui, repo, source, dest): |
423 """mark a file as copied or renamed for the next commit""" | |
424 return repo.copy(*relpath(repo, (source, dest))) | |
425 | |
596 | 426 def debugcheckstate(ui, repo): |
427 """validate the correctness of the current dirstate""" | |
460 | 428 parent1, parent2 = repo.dirstate.parents() |
555 | 429 repo.dirstate.read() |
430 dc = repo.dirstate.map | |
460 | 431 keys = dc.keys() |
432 keys.sort() | |
433 m1n = repo.changelog.read(parent1)[0] | |
434 m2n = repo.changelog.read(parent2)[0] | |
435 m1 = repo.manifest.read(m1n) | |
436 m2 = repo.manifest.read(m2n) | |
437 errors = 0 | |
438 for f in dc: | |
439 state = repo.dirstate.state(f) | |
440 if state in "nr" and f not in m1: | |
582 | 441 ui.warn("%s in state %s, but not in manifest1\n" % (f, state)) |
460 | 442 errors += 1 |
443 if state in "a" and f in m1: | |
582 | 444 ui.warn("%s in state %s, but also in manifest1\n" % (f, state)) |
460 | 445 errors += 1 |
446 if state in "m" and f not in m1 and f not in m2: | |
582 | 447 ui.warn("%s in state %s, but not in either manifest\n" % |
448 (f, state)) | |
460 | 449 errors += 1 |
450 for f in m1: | |
451 state = repo.dirstate.state(f) | |
452 if state not in "nrm": | |
582 | 453 ui.warn("%s in manifest1, but listed as state %s" % (f, state)) |
460 | 454 errors += 1 |
455 if errors: | |
582 | 456 ui.warn(".hg/dirstate inconsistent with current parent's manifest\n") |
460 | 457 sys.exit(1) |
458 | |
596 | 459 def debugstate(ui, repo): |
460 """show the contents of the current dirstate""" | |
555 | 461 repo.dirstate.read() |
462 dc = repo.dirstate.map | |
460 | 463 keys = dc.keys() |
464 keys.sort() | |
465 for file in keys: | |
582 | 466 ui.write("%c %s\n" % (dc[file][0], file)) |
460 | 467 |
248 | 468 def debugindex(ui, file): |
596 | 469 """dump the contents of an index file""" |
417 | 470 r = hg.revlog(hg.opener(""), file, "") |
582 | 471 ui.write(" rev offset length base linkrev" + |
472 " p1 p2 nodeid\n") | |
248 | 473 for i in range(r.count()): |
474 e = r.index[i] | |
582 | 475 ui.write("% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s..\n" % ( |
476 i, e[0], e[1], e[2], e[3], | |
477 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))) | |
248 | 478 |
479 def debugindexdot(ui, file): | |
596 | 480 """dump an index DAG as a .dot file""" |
417 | 481 r = hg.revlog(hg.opener(""), file, "") |
582 | 482 ui.write("digraph G {\n") |
248 | 483 for i in range(r.count()): |
484 e = r.index[i] | |
582 | 485 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i)) |
248 | 486 if e[5] != hg.nullid: |
582 | 487 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i)) |
488 ui.write("}\n") | |
248 | 489 |
245 | 490 def diff(ui, repo, *files, **opts): |
255 | 491 """diff working directory (or selected files)""" |
245 | 492 revs = [] |
493 if opts['rev']: | |
494 revs = map(lambda x: repo.lookup(x), opts['rev']) | |
396
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
395
diff
changeset
|
495 |
245 | 496 if len(revs) > 2: |
480
430a10669928
Fixed call to ui.warn()
Thomas Arendsen Hein <thomas@intevation.de>
parents:
479
diff
changeset
|
497 ui.warn("too many revisions to diff\n") |
245 | 498 sys.exit(1) |
499 | |
500 if files: | |
501 files = relpath(repo, files) | |
502 else: | |
503 files = relpath(repo, [""]) | |
504 | |
580 | 505 dodiff(sys.stdout, ui, repo, files, *revs) |
245 | 506 |
580 | 507 def doexport(ui, repo, changeset, seqno, total, revwidth, opts): |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
508 node = repo.lookup(changeset) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
509 prev, other = repo.changelog.parents(node) |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
510 change = repo.changelog.read(node) |
580 | 511 |
512 if opts['output'] and opts['output'] != '-': | |
513 try: | |
632 | 514 outname = make_filename(repo, repo.changelog, opts['output'], |
515 node=node, total=total, seqno=seqno, | |
516 revwidth=revwidth) | |
517 fp = open(outname, 'wb') | |
580 | 518 except KeyError, inst: |
519 ui.warn("error: invalid format spec '%%%s' in output file name\n" % | |
520 inst.args[0]) | |
521 sys.exit(1) | |
522 else: | |
523 fp = sys.stdout | |
524 | |
582 | 525 fp.write("# HG changeset patch\n") |
526 fp.write("# User %s\n" % change[1]) | |
527 fp.write("# Node ID %s\n" % hg.hex(node)) | |
528 fp.write("# Parent %s\n" % hg.hex(prev)) | |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
529 if other != hg.nullid: |
582 | 530 fp.write("# Parent %s\n" % hg.hex(other)) |
531 fp.write(change[4].rstrip()) | |
532 fp.write("\n\n") | |
580 | 533 |
534 dodiff(fp, ui, repo, None, prev, node) | |
396
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
395
diff
changeset
|
535 |
580 | 536 def export(ui, repo, *changesets, **opts): |
537 """dump the header and diffs for one or more changesets""" | |
610
4c02464cb9f0
check export options for changeset before running
shaleh@speakeasy.net
parents:
609
diff
changeset
|
538 if not changesets: |
4c02464cb9f0
check export options for changeset before running
shaleh@speakeasy.net
parents:
609
diff
changeset
|
539 ui.warn("error: export requires at least one changeset\n") |
4c02464cb9f0
check export options for changeset before running
shaleh@speakeasy.net
parents:
609
diff
changeset
|
540 sys.exit(1) |
580 | 541 seqno = 0 |
542 revs = list(revrange(ui, repo, changesets)) | |
543 total = len(revs) | |
544 revwidth = max(len(revs[0]), len(revs[-1])) | |
545 for cset in revs: | |
546 seqno += 1 | |
547 doexport(ui, repo, cset, seqno, total, revwidth, opts) | |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
548 |
245 | 549 def forget(ui, repo, file, *files): |
550 """don't add the specified files on the next commit""" | |
551 repo.forget(relpath(repo, (file,) + files)) | |
552 | |
221 | 553 def heads(ui, repo): |
329
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
554 """show current repository heads""" |
221 | 555 for n in repo.changelog.heads(): |
329
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
556 show_changeset(ui, repo, changenode=n) |
221 | 557 |
339
a76fc9c4b67b
added hg identify|id (based on a patch from Andrew Thompson)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
338
diff
changeset
|
558 def identify(ui, repo): |
a76fc9c4b67b
added hg identify|id (based on a patch from Andrew Thompson)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
338
diff
changeset
|
559 """print information about the working copy""" |
343 | 560 parents = [p for p in repo.dirstate.parents() if p != hg.nullid] |
340
97a897d32dfc
Handle the case where the current working copy is not based on a checkout.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
339
diff
changeset
|
561 if not parents: |
343 | 562 ui.write("unknown\n") |
340
97a897d32dfc
Handle the case where the current working copy is not based on a checkout.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
339
diff
changeset
|
563 return |
97a897d32dfc
Handle the case where the current working copy is not based on a checkout.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
339
diff
changeset
|
564 |
386
494c8e3f47f3
Improvements for hg identify:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
371
diff
changeset
|
565 hexfunc = ui.verbose and hg.hex or hg.short |
536 | 566 (c, a, d, u) = repo.changes(None, None) |
386
494c8e3f47f3
Improvements for hg identify:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
371
diff
changeset
|
567 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]), |
494c8e3f47f3
Improvements for hg identify:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
371
diff
changeset
|
568 (c or a or d) and "+" or "")] |
494c8e3f47f3
Improvements for hg identify:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
371
diff
changeset
|
569 |
339
a76fc9c4b67b
added hg identify|id (based on a patch from Andrew Thompson)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
338
diff
changeset
|
570 if not ui.quiet: |
386
494c8e3f47f3
Improvements for hg identify:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
371
diff
changeset
|
571 # multiple tags for a single parent separated by '/' |
494c8e3f47f3
Improvements for hg identify:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
371
diff
changeset
|
572 parenttags = ['/'.join(tags) |
494c8e3f47f3
Improvements for hg identify:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
371
diff
changeset
|
573 for tags in map(repo.nodetags, parents) if tags] |
494c8e3f47f3
Improvements for hg identify:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
371
diff
changeset
|
574 # tags for multiple parents separated by ' + ' |
494c8e3f47f3
Improvements for hg identify:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
371
diff
changeset
|
575 output.append(' + '.join(parenttags)) |
339
a76fc9c4b67b
added hg identify|id (based on a patch from Andrew Thompson)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
338
diff
changeset
|
576 |
386
494c8e3f47f3
Improvements for hg identify:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
371
diff
changeset
|
577 ui.write("%s\n" % ' '.join(output)) |
339
a76fc9c4b67b
added hg identify|id (based on a patch from Andrew Thompson)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
338
diff
changeset
|
578 |
437 | 579 def import_(ui, repo, patch1, *patches, **opts): |
580 """import an ordered set of patches""" | |
581 try: | |
582 import psyco | |
583 psyco.full() | |
584 except: | |
585 pass | |
586 | |
587 patches = (patch1,) + patches | |
500
ebc4714a7632
[PATCH] Clean up destination directory if a clone fails.
mpm@selenic.com
parents:
499
diff
changeset
|
588 |
437 | 589 d = opts["base"] |
590 strip = opts["strip"] | |
591 | |
592 for patch in patches: | |
593 ui.status("applying %s\n" % patch) | |
594 pf = os.path.join(d, patch) | |
595 | |
596 text = "" | |
597 for l in file(pf): | |
614
6bff574d639f
Stop patch description import at diff -r
Matt Mackall <mpm@selenic.com>
parents:
613
diff
changeset
|
598 if l.startswith("--- ") or l.startswith("diff -r"): break |
437 | 599 text += l |
600 | |
607
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
601 # parse values that exist when importing the result of an hg export |
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
602 hgpatch = user = snippet = None |
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
603 ui.debug('text:\n') |
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
604 for t in text.splitlines(): |
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
605 ui.debug(t,'\n') |
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
606 if t == '# HG changeset patch' or hgpatch == True: |
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
607 hgpatch = True |
674
6513ba7d858a
Make consistent use of str.startswith() in conditionals.
chad.netzer@gmail.com
parents:
668
diff
changeset
|
608 if t.startswith("# User "): |
607
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
609 user = t[7:] |
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
610 ui.debug('User: %s\n' % user) |
674
6513ba7d858a
Make consistent use of str.startswith() in conditionals.
chad.netzer@gmail.com
parents:
668
diff
changeset
|
611 if not t.startswith("# ") and t.strip() and not snippet: snippet = t |
607
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
612 if snippet: text = snippet + '\n' + text |
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
613 ui.debug('text:\n%s\n' % text) |
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
614 |
437 | 615 # make sure text isn't empty |
616 if not text: text = "imported patch %s\n" % patch | |
617 | |
618 f = os.popen("patch -p%d < %s" % (strip, pf)) | |
619 files = [] | |
620 for l in f.read().splitlines(): | |
621 l.rstrip('\r\n'); | |
481
2705d20f77c9
hg import checking for quiet mode didn't work. Fixed using the ui module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
480
diff
changeset
|
622 ui.status("%s\n" % l) |
674
6513ba7d858a
Make consistent use of str.startswith() in conditionals.
chad.netzer@gmail.com
parents:
668
diff
changeset
|
623 if l.startswith('patching file '): |
443 | 624 pf = l[14:] |
625 if pf not in files: | |
626 files.append(pf) | |
627 patcherr = f.close() | |
628 if patcherr: | |
629 sys.stderr.write("patch failed") | |
630 sys.exit(1) | |
437 | 631 |
632 if len(files) > 0: | |
633 addremove(ui, repo, *files) | |
607
94744f6fe0e7
[PATCH] Parse and use header data from an hg export'ed changeset
mpm@selenic.com
parents:
605
diff
changeset
|
634 repo.commit(files, text, user) |
437 | 635 |
496 | 636 def init(ui, source=None): |
637 """create a new repository in the current directory""" | |
290 | 638 |
639 if source: | |
496 | 640 ui.warn("no longer supported: use \"hg clone\" instead\n") |
641 sys.exit(1) | |
642 repo = hg.repository(ui, ".", create=1) | |
338 | 643 |
627 | 644 def locate(ui, repo, *pats, **opts): |
645 """locate files matching specific patterns""" | |
646 if [p for p in pats if os.sep in p]: | |
647 ui.warn("error: patterns may not contain '%s'\n" % os.sep) | |
648 ui.warn("use '-i <dir>' instead\n") | |
649 sys.exit(1) | |
650 def compile(pats, head = '^', tail = os.sep, on_empty = True): | |
651 if not pats: | |
652 class c: | |
653 def match(self, x): return on_empty | |
654 return c() | |
655 regexp = r'%s(?:%s)%s' % ( | |
656 head, | |
657 '|'.join([fnmatch.translate(os.path.normpath(os.path.normcase(p)))[:-1] | |
658 for p in pats]), | |
659 tail) | |
660 return re.compile(regexp) | |
661 exclude = compile(opts['exclude'], on_empty = False) | |
662 include = compile(opts['include']) | |
663 pat = compile([os.path.normcase(p) for p in pats], head = '', tail = '$') | |
664 end = '\n' | |
665 if opts['print0']: end = '\0' | |
666 if opts['rev']: node = repo.manifest.lookup(opts['rev']) | |
667 else: node = repo.manifest.tip() | |
668 manifest = repo.manifest.read(node) | |
669 cwd = repo.getcwd() | |
670 cwd_plus = cwd and (cwd + os.sep) | |
671 found = [] | |
672 for f in manifest: | |
673 f = os.path.normcase(f) | |
674 if exclude.match(f) or not(include.match(f) and | |
675 f.startswith(cwd_plus) and | |
676 pat.match(os.path.basename(f))): continue | |
677 if opts['fullpath']: f = os.path.join(repo.root, f) | |
678 elif cwd: f = f[len(cwd_plus):] | |
679 found.append(f) | |
680 found.sort() | |
681 for f in found: ui.write(f, end) | |
682 | |
552
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
683 def log(ui, repo, f=None, **opts): |
509 | 684 """show the revision history of the repository or a single file""" |
685 if f: | |
612
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
686 files = relpath(repo, [f]) |
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
687 filelog = repo.file(files[0]) |
552
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
688 log = filelog |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
689 lookup = filelog.lookup |
509 | 690 else: |
612
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
691 files = None |
552
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
692 filelog = None |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
693 log = repo.changelog |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
694 lookup = repo.lookup |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
695 revlist = [] |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
696 revs = [log.rev(lookup(rev)) for rev in opts['rev']] |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
697 while revs: |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
698 if len(revs) == 1: |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
699 revlist.append(revs.pop(0)) |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
700 else: |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
701 a = revs.pop(0) |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
702 b = revs.pop(0) |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
703 off = a > b and -1 or 1 |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
704 revlist.extend(range(a, b + off, off)) |
609
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
607
diff
changeset
|
705 |
552
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
706 for i in revlist or range(log.count() - 1, -1, -1): |
2204311609a0
Allow specifying revisions in 'hg log' like with 'hg diff'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
547
diff
changeset
|
707 show_changeset(ui, repo, filelog=filelog, rev=i) |
612
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
708 if opts['patch']: |
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
709 if filelog: |
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
710 filenode = filelog.node(i) |
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
711 i = filelog.linkrev(filenode) |
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
712 changenode = repo.changelog.node(i) |
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
713 prev, other = repo.changelog.parents(changenode) |
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
714 dodiff(sys.stdout, ui, repo, files, prev, changenode) |
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
715 ui.write("\n") |
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
716 ui.write("\n") |
255 | 717 |
718 def manifest(ui, repo, rev = []): | |
719 """output the latest or given revision of the project manifest""" | |
720 n = repo.manifest.tip() | |
721 if rev: | |
722 n = repo.manifest.lookup(rev) | |
723 m = repo.manifest.read(n) | |
276 | 724 mf = repo.manifest.readflags(n) |
255 | 725 files = m.keys() |
726 files.sort() | |
727 | |
728 for f in files: | |
276 | 729 ui.write("%40s %3s %s\n" % (hg.hex(m[f]), mf[f] and "755" or "644", f)) |
255 | 730 |
731 def parents(ui, repo, node = None): | |
732 '''show the parents of the current working dir''' | |
733 if node: | |
734 p = repo.changelog.parents(repo.lookup(hg.bin(node))) | |
735 else: | |
736 p = repo.dirstate.parents() | |
737 | |
738 for n in p: | |
739 if n != hg.nullid: | |
329
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
740 show_changeset(ui, repo, changenode=n) |
255 | 741 |
404 | 742 def pull(ui, repo, source="default", **opts): |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
743 """pull changes from the specified source""" |
506 | 744 source = ui.expandpath(source) |
404 | 745 ui.status('pulling from %s\n' % (source)) |
500
ebc4714a7632
[PATCH] Clean up destination directory if a clone fails.
mpm@selenic.com
parents:
499
diff
changeset
|
746 |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
747 other = hg.repository(ui, source) |
625 | 748 r = repo.pull(other) |
749 if not r: | |
404 | 750 if opts['update']: |
751 return update(ui, repo) | |
580 | 752 else: |
404 | 753 ui.status("(run 'hg update' to get a working copy)\n") |
754 | |
755 return r | |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
756 |
371
6e3436082697
hg push: "default-push" default target path
mpm@selenic.com
parents:
367
diff
changeset
|
757 def push(ui, repo, dest="default-push"): |
319 | 758 """push changes to the specified destination""" |
506 | 759 dest = ui.expandpath(dest) |
640
b48b91d3fb4a
Switch push over to the new scheme
Matt Mackall <mpm@selenic.com>
parents:
639
diff
changeset
|
760 ui.status('pushing to %s\n' % (dest)) |
319 | 761 |
640
b48b91d3fb4a
Switch push over to the new scheme
Matt Mackall <mpm@selenic.com>
parents:
639
diff
changeset
|
762 other = hg.repository(ui, dest) |
b48b91d3fb4a
Switch push over to the new scheme
Matt Mackall <mpm@selenic.com>
parents:
639
diff
changeset
|
763 r = repo.push(other) |
b48b91d3fb4a
Switch push over to the new scheme
Matt Mackall <mpm@selenic.com>
parents:
639
diff
changeset
|
764 return r |
319 | 765 |
403 | 766 def rawcommit(ui, repo, *flist, **rc): |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
767 "raw commit interface" |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
768 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
769 text = rc['text'] |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
770 if not text and rc['logfile']: |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
771 try: text = open(rc['logfile']).read() |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
772 except IOError: pass |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
773 if not text and not rc['logfile']: |
582 | 774 ui.warn("abort: missing commit text\n") |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
775 return 1 |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
776 |
403 | 777 files = relpath(repo, list(flist)) |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
778 if rc['files']: |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
779 files += open(rc['files']).read().splitlines() |
452
a1e91c24dab5
rawcommit: do lookup of parents at the appropriate layer
mpm@selenic.com
parents:
443
diff
changeset
|
780 |
a1e91c24dab5
rawcommit: do lookup of parents at the appropriate layer
mpm@selenic.com
parents:
443
diff
changeset
|
781 rc['parent'] = map(repo.lookup, rc['parent']) |
500
ebc4714a7632
[PATCH] Clean up destination directory if a clone fails.
mpm@selenic.com
parents:
499
diff
changeset
|
782 |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
783 repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent']) |
500
ebc4714a7632
[PATCH] Clean up destination directory if a clone fails.
mpm@selenic.com
parents:
499
diff
changeset
|
784 |
245 | 785 def recover(ui, repo): |
255 | 786 """roll back an interrupted transaction""" |
245 | 787 repo.recover() |
788 | |
789 def remove(ui, repo, file, *files): | |
790 """remove the specified files on the next commit""" | |
791 repo.remove(relpath(repo, (file,) + files)) | |
792 | |
588 | 793 def revert(ui, repo, *names, **opts): |
794 """revert modified files or dirs back to their unmodified states""" | |
590
38d106db75bc
hg revert should revert to parent, not to tip
mpm@selenic.com
parents:
588
diff
changeset
|
795 node = opts['rev'] and repo.lookup(opts['rev']) or \ |
38d106db75bc
hg revert should revert to parent, not to tip
mpm@selenic.com
parents:
588
diff
changeset
|
796 repo.dirstate.parents()[0] |
588 | 797 root = os.path.realpath(repo.root) |
590
38d106db75bc
hg revert should revert to parent, not to tip
mpm@selenic.com
parents:
588
diff
changeset
|
798 |
588 | 799 def trimpath(p): |
800 p = os.path.realpath(p) | |
801 if p.startswith(root): | |
802 rest = p[len(root):] | |
803 if not rest: | |
804 return rest | |
805 if p.startswith(os.sep): | |
806 return rest[1:] | |
807 return p | |
590
38d106db75bc
hg revert should revert to parent, not to tip
mpm@selenic.com
parents:
588
diff
changeset
|
808 |
588 | 809 relnames = map(trimpath, names or [os.getcwd()]) |
810 chosen = {} | |
590
38d106db75bc
hg revert should revert to parent, not to tip
mpm@selenic.com
parents:
588
diff
changeset
|
811 |
588 | 812 def choose(name): |
813 def body(name): | |
814 for r in relnames: | |
815 if not name.startswith(r): continue | |
816 rest = name[len(r):] | |
817 if not rest: return r, True | |
818 depth = rest.count(os.sep) | |
819 if not r: | |
820 if depth == 0 or not opts['nonrecursive']: return r, True | |
821 elif rest[0] == os.sep: | |
822 if depth == 1 or not opts['nonrecursive']: return r, True | |
823 return None, False | |
824 relname, ret = body(name) | |
825 if ret: | |
826 chosen[relname] = 1 | |
827 return ret | |
828 | |
829 r = repo.update(node, False, True, choose, False) | |
830 for n in relnames: | |
831 if n not in chosen: | |
832 ui.warn('error: no matches for %s\n' % n) | |
833 r = 1 | |
834 sys.stdout.flush() | |
835 return r | |
836 | |
468 | 837 def root(ui, repo): |
838 """print the root (top) of the current working dir""" | |
839 ui.write(repo.root + "\n") | |
840 | |
245 | 841 def serve(ui, repo, **opts): |
255 | 842 """export the repository via HTTP""" |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
843 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
844 if opts["stdio"]: |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
845 fin, fout = sys.stdin, sys.stdout |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
846 sys.stdout = sys.stderr |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
847 |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
848 def getarg(): |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
849 argline = fin.readline()[:-1] |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
850 arg, l = argline.split() |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
851 val = fin.read(int(l)) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
852 return arg, val |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
853 def respond(v): |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
854 fout.write("%d\n" % len(v)) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
855 fout.write(v) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
856 fout.flush() |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
857 |
638
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
858 lock = None |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
859 |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
860 while 1: |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
861 cmd = fin.readline()[:-1] |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
862 if cmd == '': |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
863 return |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
864 if cmd == "heads": |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
865 h = repo.heads() |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
866 respond(" ".join(map(hg.hex, h)) + "\n") |
638
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
867 if cmd == "lock": |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
868 lock = repo.lock() |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
869 respond("") |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
870 if cmd == "unlock": |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
871 if lock: lock.release() |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
872 lock = None |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
873 respond("") |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
874 elif cmd == "branches": |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
875 arg, nodes = getarg() |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
876 nodes = map(hg.bin, nodes.split(" ")) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
877 r = [] |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
878 for b in repo.branches(nodes): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
879 r.append(" ".join(map(hg.hex, b)) + "\n") |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
880 respond("".join(r)) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
881 elif cmd == "between": |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
882 arg, pairs = getarg() |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
883 pairs = [ map(hg.bin, p.split("-")) for p in pairs.split(" ") ] |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
884 r = [] |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
885 for b in repo.between(pairs): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
886 r.append(" ".join(map(hg.hex, b)) + "\n") |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
887 respond("".join(r)) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
888 elif cmd == "changegroup": |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
889 nodes = [] |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
890 arg, roots = getarg() |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
891 nodes = map(hg.bin, roots.split(" ")) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
892 |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
893 cg = repo.changegroup(nodes) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
894 while 1: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
895 d = cg.read(4096) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
896 if not d: break |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
897 fout.write(d) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
898 |
667
31a9aa890016
A number of minor fixes to problems that pychecker found.
mark.williamson@cl.cam.ac.uk
parents:
654
diff
changeset
|
899 fout.flush() |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
900 |
639
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
901 elif cmd == "addchangegroup": |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
902 if not lock: |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
903 respond("not locked") |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
904 continue |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
905 respond("") |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
906 |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
907 r = repo.addchangegroup(fin) |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
908 respond("") |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
909 |
605
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
910 def openlog(opt, default): |
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
911 if opts[opt] and opts[opt] != '-': return open(opts[opt], 'w') |
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
912 else: return default |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
913 |
603
bc5d058e65e9
[PATCH] Get "hg serve" to print the URL being served
mpm@selenic.com
parents:
596
diff
changeset
|
914 httpd = hgweb.create_server(repo.root, opts["name"], opts["templates"], |
605
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
915 opts["address"], opts["port"], |
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
916 openlog('accesslog', sys.stdout), |
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
917 openlog('errorlog', sys.stderr)) |
603
bc5d058e65e9
[PATCH] Get "hg serve" to print the URL being served
mpm@selenic.com
parents:
596
diff
changeset
|
918 if ui.verbose: |
bc5d058e65e9
[PATCH] Get "hg serve" to print the URL being served
mpm@selenic.com
parents:
596
diff
changeset
|
919 addr, port = httpd.socket.getsockname() |
bc5d058e65e9
[PATCH] Get "hg serve" to print the URL being served
mpm@selenic.com
parents:
596
diff
changeset
|
920 if addr == '0.0.0.0': |
bc5d058e65e9
[PATCH] Get "hg serve" to print the URL being served
mpm@selenic.com
parents:
596
diff
changeset
|
921 addr = socket.gethostname() |
bc5d058e65e9
[PATCH] Get "hg serve" to print the URL being served
mpm@selenic.com
parents:
596
diff
changeset
|
922 else: |
bc5d058e65e9
[PATCH] Get "hg serve" to print the URL being served
mpm@selenic.com
parents:
596
diff
changeset
|
923 try: |
bc5d058e65e9
[PATCH] Get "hg serve" to print the URL being served
mpm@selenic.com
parents:
596
diff
changeset
|
924 addr = socket.gethostbyaddr(addr)[0] |
bc5d058e65e9
[PATCH] Get "hg serve" to print the URL being served
mpm@selenic.com
parents:
596
diff
changeset
|
925 except: pass |
bc5d058e65e9
[PATCH] Get "hg serve" to print the URL being served
mpm@selenic.com
parents:
596
diff
changeset
|
926 if port != 80: |
605
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
927 ui.status('listening at http://%s:%d/\n' % (addr, port)) |
603
bc5d058e65e9
[PATCH] Get "hg serve" to print the URL being served
mpm@selenic.com
parents:
596
diff
changeset
|
928 else: |
605
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
929 ui.status('listening at http://%s/\n' % addr) |
603
bc5d058e65e9
[PATCH] Get "hg serve" to print the URL being served
mpm@selenic.com
parents:
596
diff
changeset
|
930 httpd.serve_forever() |
500
ebc4714a7632
[PATCH] Clean up destination directory if a clone fails.
mpm@selenic.com
parents:
499
diff
changeset
|
931 |
213 | 932 def status(ui, repo): |
933 '''show changed files in the working directory | |
934 | |
245 | 935 C = changed |
936 A = added | |
937 R = removed | |
938 ? = not tracked''' | |
312 | 939 |
537 | 940 (c, a, d, u) = repo.changes(None, None) |
220 | 941 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u)) |
213 | 942 |
582 | 943 for f in c: ui.write("C ", f, "\n") |
944 for f in a: ui.write("A ", f, "\n") | |
945 for f in d: ui.write("R ", f, "\n") | |
946 for f in u: ui.write("? ", f, "\n") | |
213 | 947 |
401
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
948 def tag(ui, repo, name, rev = None, **opts): |
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
949 """add a tag for the current tip or a given revision""" |
500
ebc4714a7632
[PATCH] Clean up destination directory if a clone fails.
mpm@selenic.com
parents:
499
diff
changeset
|
950 |
401
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
951 if name == "tip": |
580 | 952 ui.warn("abort: 'tip' is a reserved name!\n") |
953 return -1 | |
609
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
607
diff
changeset
|
954 if rev: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
607
diff
changeset
|
955 r = hg.hex(repo.lookup(rev)) |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
607
diff
changeset
|
956 else: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
607
diff
changeset
|
957 r = hg.hex(repo.changelog.tip()) |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
607
diff
changeset
|
958 |
580 | 959 if name.find(revrangesep) >= 0: |
960 ui.warn("abort: '%s' cannot be used in a tag name\n" % revrangesep) | |
961 return -1 | |
401
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
962 |
609
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
607
diff
changeset
|
963 if opts['local']: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
607
diff
changeset
|
964 repo.opener("localtags", "a").write("%s %s\n" % (r, name)) |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
607
diff
changeset
|
965 return |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
607
diff
changeset
|
966 |
536 | 967 (c, a, d, u) = repo.changes(None, None) |
401
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
968 for x in (c, a, d, u): |
580 | 969 if ".hgtags" in x: |
970 ui.warn("abort: working copy of .hgtags is changed!\n") | |
401
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
971 ui.status("(please commit .hgtags manually)\n") |
580 | 972 return -1 |
401
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
973 |
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
974 add = 0 |
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
975 if not os.path.exists(repo.wjoin(".hgtags")): add = 1 |
617 | 976 repo.wfile(".hgtags", "ab").write("%s %s\n" % (r, name)) |
401
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
977 if add: repo.add([".hgtags"]) |
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
978 |
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
979 if not opts['text']: |
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
980 opts['text'] = "Added tag %s for changeset %s" % (name, r) |
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
981 |
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
982 repo.commit([".hgtags"], opts['text'], opts['user'], opts['date']) |
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
983 |
248 | 984 def tags(ui, repo): |
255 | 985 """list repository tags""" |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
470
diff
changeset
|
986 |
343 | 987 l = repo.tagslist() |
988 l.reverse() | |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
470
diff
changeset
|
989 for t, n in l: |
248 | 990 try: |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
470
diff
changeset
|
991 r = "%5d:%s" % (repo.changelog.rev(n), hg.hex(n)) |
248 | 992 except KeyError: |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
470
diff
changeset
|
993 r = " ?:?" |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
470
diff
changeset
|
994 ui.write("%-30s %s\n" % (t, r)) |
248 | 995 |
245 | 996 def tip(ui, repo): |
255 | 997 """show the tip revision""" |
245 | 998 n = repo.changelog.tip() |
329
67c19ad374a9
Use common output function show_changeset() for hg heads|history|log|tip.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
320
diff
changeset
|
999 show_changeset(ui, repo, changenode=n) |
245 | 1000 |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
1001 def undo(ui, repo): |
596 | 1002 """undo the last commit or pull |
1003 | |
1004 Roll back the last pull or commit transaction on the | |
1005 repository, restoring the project to its earlier state. | |
1006 | |
1007 This command should be used with care. There is only one level of | |
1008 undo and there is no redo. | |
1009 | |
1010 This command is not intended for use on public repositories. Once | |
1011 a change is visible for pull by other users, undoing it locally is | |
1012 ineffective. | |
1013 """ | |
210 | 1014 repo.undo() |
1015 | |
275 | 1016 def update(ui, repo, node=None, merge=False, clean=False): |
254 | 1017 '''update or merge working directory |
1018 | |
1019 If there are no outstanding changes in the working directory and | |
1020 there is a linear relationship between the current version and the | |
1021 requested version, the result is the requested version. | |
1022 | |
1023 Otherwise the result is a merge between the contents of the | |
1024 current working directory and the requested version. Files that | |
1025 changed between either parent are marked as changed for the next | |
1026 commit and a commit must be performed before any further updates | |
1027 are allowed. | |
1028 ''' | |
1029 node = node and repo.lookup(node) or repo.changelog.tip() | |
275 | 1030 return repo.update(node, allow=merge, force=clean) |
254 | 1031 |
247 | 1032 def verify(ui, repo): |
1033 """verify the integrity of the repository""" | |
1034 return repo.verify() | |
1035 | |
255 | 1036 # Command options and aliases are listed here, alphabetically |
1037 | |
209 | 1038 table = { |
593 | 1039 "^add": (add, [], "hg add [files]"), |
353 | 1040 "addremove": (addremove, [], "hg addremove [files]"), |
596 | 1041 "^annotate": (annotate, |
209 | 1042 [('r', 'revision', '', 'revision'), |
1043 ('u', 'user', None, 'show user'), | |
1044 ('n', 'number', None, 'show revision number'), | |
1045 ('c', 'changeset', None, 'show changeset')], | |
1046 'hg annotate [-u] [-c] [-n] [-r id] [files]'), | |
643 | 1047 "cat": (cat, [('o', 'output', "", 'output to file')], 'hg cat [-o outfile] <file> [rev]'), |
593 | 1048 "^clone": (clone, [('U', 'noupdate', None, 'skip update after cloning')], |
485 | 1049 'hg clone [options] <source> [dest]'), |
593 | 1050 "^commit|ci": (commit, |
289 | 1051 [('t', 'text', "", 'commit text'), |
354 | 1052 ('A', 'addremove', None, 'run add/remove during commit'), |
317 | 1053 ('l', 'logfile', "", 'commit text file'), |
591 | 1054 ('d', 'date', "", 'date code'), |
317 | 1055 ('u', 'user', "", 'user')], |
289 | 1056 'hg commit [files]'), |
363 | 1057 "copy": (copy, [], 'hg copy <source> <dest>'), |
596 | 1058 "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'), |
1059 "debugstate": (debugstate, [], 'debugstate'), | |
248 | 1060 "debugindex": (debugindex, [], 'debugindex <file>'), |
1061 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'), | |
593 | 1062 "^diff": (diff, [('r', 'rev', [], 'revision')], |
245 | 1063 'hg diff [-r A] [-r B] [files]'), |
596 | 1064 "^export": (export, [('o', 'output', "", 'output to file')], |
580 | 1065 "hg export [-o file] <changeset> ..."), |
245 | 1066 "forget": (forget, [], "hg forget [files]"), |
1067 "heads": (heads, [], 'hg heads'), | |
1068 "help": (help, [], 'hg help [command]'), | |
339
a76fc9c4b67b
added hg identify|id (based on a patch from Andrew Thompson)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
338
diff
changeset
|
1069 "identify|id": (identify, [], 'hg identify'), |
437 | 1070 "import|patch": (import_, |
1071 [('p', 'strip', 1, 'path strip'), | |
1072 ('b', 'base', "", 'base path')], | |
1073 "hg import [options] <patches>"), | |
593 | 1074 "^init": (init, [], 'hg init'), |
627 | 1075 "locate": (locate, |
1076 [('0', 'print0', None, 'end records with NUL'), | |
1077 ('f', 'fullpath', None, 'print complete paths'), | |
1078 ('i', 'include', [], 'include path in search'), | |
1079 ('r', 'rev', '', 'revision'), | |
1080 ('x', 'exclude', [], 'exclude path from search')], | |
1081 'hg locate [options] [files]'), | |
593 | 1082 "^log|history": (log, |
612
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
1083 [('r', 'rev', [], 'revision'), |
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
1084 ('p', 'patch', None, 'show patch')], |
9cd745437269
On Sat, Jul 02, 2005 at 02:11:34PM -0700, Matt Mackall wrote:
Alecs King <alecsk@gmail.com>
parents:
610
diff
changeset
|
1085 'hg log [-r A] [-r B] [-p] [file]'), |
437 | 1086 "manifest": (manifest, [], 'hg manifest [rev]'), |
227 | 1087 "parents": (parents, [], 'hg parents [node]'), |
593 | 1088 "^pull": (pull, |
404 | 1089 [('u', 'update', None, 'update working directory')], |
580 | 1090 'hg pull [options] [source]'), |
593 | 1091 "^push": (push, [], 'hg push <destination>'), |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
1092 "rawcommit": (rawcommit, |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
1093 [('p', 'parent', [], 'parent'), |
591 | 1094 ('d', 'date', "", 'date code'), |
246
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
1095 ('u', 'user', "", 'user'), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
1096 ('F', 'files', "", 'file list'), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
1097 ('t', 'text', "", 'commit text'), |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
1098 ('l', 'logfile', "", 'commit text file')], |
96cde50a746f
Migrate rawcommit, import, export, history, and merge
mpm@selenic.com
parents:
245
diff
changeset
|
1099 'hg rawcommit [options] [files]'), |
245 | 1100 "recover": (recover, [], "hg recover"), |
593 | 1101 "^remove|rm": (remove, [], "hg remove [files]"), |
596 | 1102 "^revert": (revert, |
588 | 1103 [("n", "nonrecursive", None, "don't recurse into subdirs"), |
1104 ("r", "rev", "", "revision")], | |
1105 "hg revert [files|dirs]"), | |
468 | 1106 "root": (root, [], "hg root"), |
605
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
1107 "^serve": (serve, [('A', 'accesslog', '', 'access log file'), |
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
1108 ('E', 'errorlog', '', 'error log file'), |
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
1109 ('p', 'port', 8000, 'listen port'), |
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
1110 ('a', 'address', '', 'interface address'), |
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
1111 ('n', 'name', os.getcwd(), 'repository name'), |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
618
diff
changeset
|
1112 ('', 'stdio', None, 'for remote clients'), |
605
8e82fd763be2
[PATCH] Get "hg serve" to optionally log accesses and errors to files
mpm@selenic.com
parents:
604
diff
changeset
|
1113 ('t', 'templates', "", 'template map')], |
245 | 1114 "hg serve [options]"), |
593 | 1115 "^status": (status, [], 'hg status'), |
609
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
607
diff
changeset
|
1116 "tag": (tag, [('l', 'local', None, 'make the tag local'), |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
607
diff
changeset
|
1117 ('t', 'text', "", 'commit text'), |
591 | 1118 ('d', 'date', "", 'date code'), |
401
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
1119 ('u', 'user', "", 'user')], |
af4848f83e68
From: Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl>
mpm@selenic.com
parents:
396
diff
changeset
|
1120 'hg tag [options] <name> [rev]'), |
248 | 1121 "tags": (tags, [], 'hg tags'), |
245 | 1122 "tip": (tip, [], 'hg tip'), |
210 | 1123 "undo": (undo, [], 'hg undo'), |
593 | 1124 "^update|up|checkout|co": |
437 | 1125 (update, |
1126 [('m', 'merge', None, 'allow merging of conflicts'), | |
1127 ('C', 'clean', None, 'overwrite locally modified files')], | |
1128 'hg update [options] [node]'), | |
247 | 1129 "verify": (verify, [], 'hg verify'), |
470
0ab093b473c5
Fix up version module name and command conflict
mpm@selenic.com
parents:
468
diff
changeset
|
1130 "version": (show_version, [], 'hg version'), |
209 | 1131 } |
1132 | |
596 | 1133 globalopts = [('v', 'verbose', None, 'verbose'), |
1134 ('', 'debug', None, 'debug'), | |
1135 ('q', 'quiet', None, 'quiet'), | |
1136 ('', 'profile', None, 'profile'), | |
1137 ('R', 'repository', "", 'repository root directory'), | |
1138 ('', 'traceback', None, 'print traceback on exception'), | |
1139 ('y', 'noninteractive', None, 'run non-interactively'), | |
1140 ('', 'version', None, 'output version information and exit'), | |
1141 ] | |
1142 | |
485 | 1143 norepo = "clone init version help debugindex debugindexdot" |
209 | 1144 |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
1145 def find(cmd): |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
1146 for e in table.keys(): |
335 | 1147 if re.match("(%s)$" % e, cmd): |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
1148 return table[e] |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
1149 |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
1150 raise UnknownCommand(cmd) |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
1151 |
214 | 1152 class SignalInterrupt(Exception): pass |
1153 | |
1154 def catchterm(*args): | |
1155 raise SignalInterrupt | |
1156 | |
249 | 1157 def run(): |
1158 sys.exit(dispatch(sys.argv[1:])) | |
1159 | |
596 | 1160 class ParseError(Exception): pass |
592 | 1161 |
596 | 1162 def parse(args): |
209 | 1163 options = {} |
596 | 1164 cmdoptions = {} |
209 | 1165 |
592 | 1166 try: |
596 | 1167 args = fancyopts.fancyopts(args, globalopts, options) |
592 | 1168 except fancyopts.getopt.GetoptError, inst: |
618
4051b78c53c7
Handle unrecognised options correctly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
617
diff
changeset
|
1169 raise ParseError(None, inst) |
209 | 1170 |
596 | 1171 if options["version"]: |
1172 return ("version", show_version, [], options, cmdoptions) | |
1173 elif not args: | |
1174 return ("help", help, [], options, cmdoptions) | |
209 | 1175 else: |
1176 cmd, args = args[0], args[1:] | |
1177 | |
596 | 1178 i = find(cmd) |
209 | 1179 |
592 | 1180 # combine global options into local |
1181 c = list(i[1]) | |
1182 l = len(c) | |
596 | 1183 for o in globalopts: |
592 | 1184 c.append((o[0], o[1], options[o[1]], o[3])) |
214 | 1185 |
293 | 1186 try: |
596 | 1187 args = fancyopts.fancyopts(args, c, cmdoptions) |
293 | 1188 except fancyopts.getopt.GetoptError, inst: |
596 | 1189 raise ParseError(cmd, inst) |
209 | 1190 |
592 | 1191 # separate global options back out |
596 | 1192 for o in globalopts: |
592 | 1193 n = o[1] |
1194 options[n] = cmdoptions[n] | |
1195 del cmdoptions[n] | |
1196 | |
596 | 1197 return (cmd, i[0], args, options, cmdoptions) |
1198 | |
1199 def dispatch(args): | |
1200 signal.signal(signal.SIGTERM, catchterm) | |
678
0cfc5966b2c2
Alternate fix for SIGHUP on the other OS
Matt Mackall <mpm@selenic.com>
parents:
675
diff
changeset
|
1201 try: signal.signal(signal.SIGHUP, catchterm) |
0cfc5966b2c2
Alternate fix for SIGHUP on the other OS
Matt Mackall <mpm@selenic.com>
parents:
675
diff
changeset
|
1202 except: pass |
596 | 1203 |
1204 try: | |
1205 cmd, func, args, options, cmdoptions = parse(args) | |
1206 except ParseError, inst: | |
1207 u = ui.ui() | |
1208 if inst.args[0]: | |
1209 u.warn("hg %s: %s\n" % (inst.args[0], inst.args[1])) | |
1210 help(u, inst.args[0]) | |
1211 else: | |
1212 u.warn("hg: %s\n" % inst.args[1]) | |
1213 help(u) | |
1214 sys.exit(-1) | |
1215 except UnknownCommand, inst: | |
1216 u = ui.ui() | |
1217 u.warn("hg: unknown command '%s'\n" % inst.args[0]) | |
1218 help(u) | |
1219 sys.exit(1) | |
1220 | |
1221 u = ui.ui(options["verbose"], options["debug"], options["quiet"], | |
1222 not options["noninteractive"]) | |
592 | 1223 |
499 | 1224 try: |
527 | 1225 try: |
1226 if cmd not in norepo.split(): | |
1227 path = options["repository"] or "" | |
1228 repo = hg.repository(ui=u, path=path) | |
596 | 1229 d = lambda: func(u, repo, *args, **cmdoptions) |
527 | 1230 else: |
596 | 1231 d = lambda: func(u, *args, **cmdoptions) |
209 | 1232 |
527 | 1233 if options['profile']: |
1234 import hotshot, hotshot.stats | |
1235 prof = hotshot.Profile("hg.prof") | |
1236 r = prof.runcall(d) | |
1237 prof.close() | |
1238 stats = hotshot.stats.load("hg.prof") | |
1239 stats.strip_dirs() | |
1240 stats.sort_stats('time', 'calls') | |
1241 stats.print_stats(40) | |
1242 return r | |
1243 else: | |
1244 return d() | |
1245 except: | |
1246 if options['traceback']: | |
1247 traceback.print_exc() | |
1248 raise | |
508 | 1249 except util.CommandError, inst: |
1250 u.warn("abort: %s\n" % inst.args) | |
499 | 1251 except hg.RepoError, inst: |
1252 u.warn("abort: ", inst, "!\n") | |
214 | 1253 except SignalInterrupt: |
1254 u.warn("killed!\n") | |
209 | 1255 except KeyboardInterrupt: |
1256 u.warn("interrupted!\n") | |
250 | 1257 except IOError, inst: |
395 | 1258 if hasattr(inst, "code"): |
1259 u.warn("abort: %s\n" % inst) | |
1260 elif hasattr(inst, "reason"): | |
1261 u.warn("abort: error %d: %s\n" % (inst.reason[0], inst.reason[1])) | |
1262 elif hasattr(inst, "args") and inst[0] == errno.EPIPE: | |
250 | 1263 u.warn("broken pipe\n") |
1264 else: | |
1265 raise | |
549 | 1266 except OSError, inst: |
1267 if hasattr(inst, "filename"): | |
1268 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename)) | |
1269 else: | |
1270 u.warn("abort: %s\n" % inst.strerror) | |
212
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
1271 except TypeError, inst: |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
1272 # was this an argument error? |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
1273 tb = traceback.extract_tb(sys.exc_info()[2]) |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
1274 if len(tb) > 2: # no |
48398a5353e3
commands: better argument processing, per-command help
mpm@selenic.com
parents:
211
diff
changeset
|
1275 raise |
293 | 1276 u.debug(inst, "\n") |
596 | 1277 u.warn("%s: invalid arguments\n" % cmd) |
293 | 1278 help(u, cmd) |
1279 | |
503
c6a2e41c8c60
Fix troubles with clone and exception handling
mpm@selenic.com
parents:
500
diff
changeset
|
1280 sys.exit(-1) |