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