##// END OF EJS Templates
Added options -h/--help.
Thomas Arendsen Hein -
r1048:7fbb440b default
parent child Browse files
Show More
@@ -1,1707 +1,1711 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from demandload import demandload
8 from demandload import demandload
9 demandload(globals(), "os re sys signal shutil")
9 demandload(globals(), "os re sys signal shutil")
10 demandload(globals(), "fancyopts ui hg util lock")
10 demandload(globals(), "fancyopts ui hg util lock")
11 demandload(globals(), "fnmatch hgweb mdiff random signal time traceback")
11 demandload(globals(), "fnmatch hgweb mdiff random signal time traceback")
12 demandload(globals(), "errno socket version struct atexit")
12 demandload(globals(), "errno socket version struct atexit")
13
13
14 class UnknownCommand(Exception):
14 class UnknownCommand(Exception):
15 """Exception raised if command is not in the command table."""
15 """Exception raised if command is not in the command table."""
16
16
17 def filterfiles(filters, files):
17 def filterfiles(filters, files):
18 l = [x for x in files if x in filters]
18 l = [x for x in files if x in filters]
19
19
20 for t in filters:
20 for t in filters:
21 if t and t[-1] != "/":
21 if t and t[-1] != "/":
22 t += "/"
22 t += "/"
23 l += [x for x in files if x.startswith(t)]
23 l += [x for x in files if x.startswith(t)]
24 return l
24 return l
25
25
26 def relpath(repo, args):
26 def relpath(repo, args):
27 cwd = repo.getcwd()
27 cwd = repo.getcwd()
28 if cwd:
28 if cwd:
29 return [util.normpath(os.path.join(cwd, x)) for x in args]
29 return [util.normpath(os.path.join(cwd, x)) for x in args]
30 return args
30 return args
31
31
32 def matchpats(repo, cwd, pats = [], opts = {}, head = ''):
32 def matchpats(repo, cwd, pats = [], opts = {}, head = ''):
33 return util.matcher(repo, cwd, pats or ['.'], opts.get('include'),
33 return util.matcher(repo, cwd, pats or ['.'], opts.get('include'),
34 opts.get('exclude'), head)
34 opts.get('exclude'), head)
35
35
36 def makewalk(repo, pats, opts, head = ''):
36 def makewalk(repo, pats, opts, head = ''):
37 cwd = repo.getcwd()
37 cwd = repo.getcwd()
38 files, matchfn, anypats = matchpats(repo, cwd, pats, opts, head)
38 files, matchfn, anypats = matchpats(repo, cwd, pats, opts, head)
39 exact = dict(zip(files, files))
39 exact = dict(zip(files, files))
40 def walk():
40 def walk():
41 for src, fn in repo.walk(files = files, match = matchfn):
41 for src, fn in repo.walk(files = files, match = matchfn):
42 yield src, fn, util.pathto(cwd, fn), fn in exact
42 yield src, fn, util.pathto(cwd, fn), fn in exact
43 return files, matchfn, walk()
43 return files, matchfn, walk()
44
44
45 def walk(repo, pats, opts, head = ''):
45 def walk(repo, pats, opts, head = ''):
46 files, matchfn, results = makewalk(repo, pats, opts, head)
46 files, matchfn, results = makewalk(repo, pats, opts, head)
47 for r in results: yield r
47 for r in results: yield r
48
48
49 revrangesep = ':'
49 revrangesep = ':'
50
50
51 def revrange(ui, repo, revs, revlog=None):
51 def revrange(ui, repo, revs, revlog=None):
52 if revlog is None:
52 if revlog is None:
53 revlog = repo.changelog
53 revlog = repo.changelog
54 revcount = revlog.count()
54 revcount = revlog.count()
55 def fix(val, defval):
55 def fix(val, defval):
56 if not val:
56 if not val:
57 return defval
57 return defval
58 try:
58 try:
59 num = int(val)
59 num = int(val)
60 if str(num) != val:
60 if str(num) != val:
61 raise ValueError
61 raise ValueError
62 if num < 0:
62 if num < 0:
63 num += revcount
63 num += revcount
64 if not (0 <= num < revcount):
64 if not (0 <= num < revcount):
65 raise ValueError
65 raise ValueError
66 except ValueError:
66 except ValueError:
67 try:
67 try:
68 num = repo.changelog.rev(repo.lookup(val))
68 num = repo.changelog.rev(repo.lookup(val))
69 except KeyError:
69 except KeyError:
70 try:
70 try:
71 num = revlog.rev(revlog.lookup(val))
71 num = revlog.rev(revlog.lookup(val))
72 except KeyError:
72 except KeyError:
73 raise util.Abort('invalid revision identifier %s', val)
73 raise util.Abort('invalid revision identifier %s', val)
74 return num
74 return num
75 for spec in revs:
75 for spec in revs:
76 if spec.find(revrangesep) >= 0:
76 if spec.find(revrangesep) >= 0:
77 start, end = spec.split(revrangesep, 1)
77 start, end = spec.split(revrangesep, 1)
78 start = fix(start, 0)
78 start = fix(start, 0)
79 end = fix(end, revcount - 1)
79 end = fix(end, revcount - 1)
80 if end > start:
80 if end > start:
81 end += 1
81 end += 1
82 step = 1
82 step = 1
83 else:
83 else:
84 end -= 1
84 end -= 1
85 step = -1
85 step = -1
86 for rev in xrange(start, end, step):
86 for rev in xrange(start, end, step):
87 yield str(rev)
87 yield str(rev)
88 else:
88 else:
89 yield str(fix(spec, None))
89 yield str(fix(spec, None))
90
90
91 def make_filename(repo, r, pat, node=None,
91 def make_filename(repo, r, pat, node=None,
92 total=None, seqno=None, revwidth=None):
92 total=None, seqno=None, revwidth=None):
93 node_expander = {
93 node_expander = {
94 'H': lambda: hg.hex(node),
94 'H': lambda: hg.hex(node),
95 'R': lambda: str(r.rev(node)),
95 'R': lambda: str(r.rev(node)),
96 'h': lambda: hg.short(node),
96 'h': lambda: hg.short(node),
97 }
97 }
98 expander = {
98 expander = {
99 '%': lambda: '%',
99 '%': lambda: '%',
100 'b': lambda: os.path.basename(repo.root),
100 'b': lambda: os.path.basename(repo.root),
101 }
101 }
102
102
103 try:
103 try:
104 if node:
104 if node:
105 expander.update(node_expander)
105 expander.update(node_expander)
106 if node and revwidth is not None:
106 if node and revwidth is not None:
107 expander['r'] = lambda: str(r.rev(node)).zfill(revwidth)
107 expander['r'] = lambda: str(r.rev(node)).zfill(revwidth)
108 if total is not None:
108 if total is not None:
109 expander['N'] = lambda: str(total)
109 expander['N'] = lambda: str(total)
110 if seqno is not None:
110 if seqno is not None:
111 expander['n'] = lambda: str(seqno)
111 expander['n'] = lambda: str(seqno)
112 if total is not None and seqno is not None:
112 if total is not None and seqno is not None:
113 expander['n'] = lambda:str(seqno).zfill(len(str(total)))
113 expander['n'] = lambda:str(seqno).zfill(len(str(total)))
114
114
115 newname = []
115 newname = []
116 patlen = len(pat)
116 patlen = len(pat)
117 i = 0
117 i = 0
118 while i < patlen:
118 while i < patlen:
119 c = pat[i]
119 c = pat[i]
120 if c == '%':
120 if c == '%':
121 i += 1
121 i += 1
122 c = pat[i]
122 c = pat[i]
123 c = expander[c]()
123 c = expander[c]()
124 newname.append(c)
124 newname.append(c)
125 i += 1
125 i += 1
126 return ''.join(newname)
126 return ''.join(newname)
127 except KeyError, inst:
127 except KeyError, inst:
128 raise util.Abort("invalid format spec '%%%s' in output file name",
128 raise util.Abort("invalid format spec '%%%s' in output file name",
129 inst.args[0])
129 inst.args[0])
130
130
131 def make_file(repo, r, pat, node=None,
131 def make_file(repo, r, pat, node=None,
132 total=None, seqno=None, revwidth=None, mode='wb'):
132 total=None, seqno=None, revwidth=None, mode='wb'):
133 if not pat or pat == '-':
133 if not pat or pat == '-':
134 if 'w' in mode: return sys.stdout
134 if 'w' in mode: return sys.stdout
135 else: return sys.stdin
135 else: return sys.stdin
136 if hasattr(pat, 'write') and 'w' in mode:
136 if hasattr(pat, 'write') and 'w' in mode:
137 return pat
137 return pat
138 if hasattr(pat, 'read') and 'r' in mode:
138 if hasattr(pat, 'read') and 'r' in mode:
139 return pat
139 return pat
140 return open(make_filename(repo, r, pat, node, total, seqno, revwidth),
140 return open(make_filename(repo, r, pat, node, total, seqno, revwidth),
141 mode)
141 mode)
142
142
143 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always,
143 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always,
144 changes=None, text=False):
144 changes=None, text=False):
145 def date(c):
145 def date(c):
146 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
146 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
147
147
148 if not changes:
148 if not changes:
149 (c, a, d, u) = repo.changes(node1, node2, files, match = match)
149 (c, a, d, u) = repo.changes(node1, node2, files, match = match)
150 else:
150 else:
151 (c, a, d, u) = changes
151 (c, a, d, u) = changes
152 if files:
152 if files:
153 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
153 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
154
154
155 if not c and not a and not d:
155 if not c and not a and not d:
156 return
156 return
157
157
158 if node2:
158 if node2:
159 change = repo.changelog.read(node2)
159 change = repo.changelog.read(node2)
160 mmap2 = repo.manifest.read(change[0])
160 mmap2 = repo.manifest.read(change[0])
161 date2 = date(change)
161 date2 = date(change)
162 def read(f):
162 def read(f):
163 return repo.file(f).read(mmap2[f])
163 return repo.file(f).read(mmap2[f])
164 else:
164 else:
165 date2 = time.asctime()
165 date2 = time.asctime()
166 if not node1:
166 if not node1:
167 node1 = repo.dirstate.parents()[0]
167 node1 = repo.dirstate.parents()[0]
168 def read(f):
168 def read(f):
169 return repo.wfile(f).read()
169 return repo.wfile(f).read()
170
170
171 if ui.quiet:
171 if ui.quiet:
172 r = None
172 r = None
173 else:
173 else:
174 hexfunc = ui.verbose and hg.hex or hg.short
174 hexfunc = ui.verbose and hg.hex or hg.short
175 r = [hexfunc(node) for node in [node1, node2] if node]
175 r = [hexfunc(node) for node in [node1, node2] if node]
176
176
177 change = repo.changelog.read(node1)
177 change = repo.changelog.read(node1)
178 mmap = repo.manifest.read(change[0])
178 mmap = repo.manifest.read(change[0])
179 date1 = date(change)
179 date1 = date(change)
180
180
181 for f in c:
181 for f in c:
182 to = None
182 to = None
183 if f in mmap:
183 if f in mmap:
184 to = repo.file(f).read(mmap[f])
184 to = repo.file(f).read(mmap[f])
185 tn = read(f)
185 tn = read(f)
186 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
186 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
187 for f in a:
187 for f in a:
188 to = None
188 to = None
189 tn = read(f)
189 tn = read(f)
190 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
190 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
191 for f in d:
191 for f in d:
192 to = repo.file(f).read(mmap[f])
192 to = repo.file(f).read(mmap[f])
193 tn = None
193 tn = None
194 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
194 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
195
195
196 def show_changeset(ui, repo, rev=0, changenode=None, brinfo=None):
196 def show_changeset(ui, repo, rev=0, changenode=None, brinfo=None):
197 """show a single changeset or file revision"""
197 """show a single changeset or file revision"""
198 log = repo.changelog
198 log = repo.changelog
199 if changenode is None:
199 if changenode is None:
200 changenode = log.node(rev)
200 changenode = log.node(rev)
201 elif not rev:
201 elif not rev:
202 rev = log.rev(changenode)
202 rev = log.rev(changenode)
203
203
204 if ui.quiet:
204 if ui.quiet:
205 ui.write("%d:%s\n" % (rev, hg.short(changenode)))
205 ui.write("%d:%s\n" % (rev, hg.short(changenode)))
206 return
206 return
207
207
208 changes = log.read(changenode)
208 changes = log.read(changenode)
209
209
210 t, tz = changes[2].split(' ')
210 t, tz = changes[2].split(' ')
211 # a conversion tool was sticking non-integer offsets into repos
211 # a conversion tool was sticking non-integer offsets into repos
212 try:
212 try:
213 tz = int(tz)
213 tz = int(tz)
214 except ValueError:
214 except ValueError:
215 tz = 0
215 tz = 0
216 date = time.asctime(time.localtime(float(t))) + " %+05d" % (int(tz)/-36)
216 date = time.asctime(time.localtime(float(t))) + " %+05d" % (int(tz)/-36)
217
217
218 parents = [(log.rev(p), ui.verbose and hg.hex(p) or hg.short(p))
218 parents = [(log.rev(p), ui.verbose and hg.hex(p) or hg.short(p))
219 for p in log.parents(changenode)
219 for p in log.parents(changenode)
220 if ui.debugflag or p != hg.nullid]
220 if ui.debugflag or p != hg.nullid]
221 if not ui.debugflag and len(parents) == 1 and parents[0][0] == rev-1:
221 if not ui.debugflag and len(parents) == 1 and parents[0][0] == rev-1:
222 parents = []
222 parents = []
223
223
224 if ui.verbose:
224 if ui.verbose:
225 ui.write("changeset: %d:%s\n" % (rev, hg.hex(changenode)))
225 ui.write("changeset: %d:%s\n" % (rev, hg.hex(changenode)))
226 else:
226 else:
227 ui.write("changeset: %d:%s\n" % (rev, hg.short(changenode)))
227 ui.write("changeset: %d:%s\n" % (rev, hg.short(changenode)))
228
228
229 for tag in repo.nodetags(changenode):
229 for tag in repo.nodetags(changenode):
230 ui.status("tag: %s\n" % tag)
230 ui.status("tag: %s\n" % tag)
231 for parent in parents:
231 for parent in parents:
232 ui.write("parent: %d:%s\n" % parent)
232 ui.write("parent: %d:%s\n" % parent)
233
233
234 if brinfo and changenode in brinfo:
234 if brinfo and changenode in brinfo:
235 br = brinfo[changenode]
235 br = brinfo[changenode]
236 ui.write("branch: %s\n" % " ".join(br))
236 ui.write("branch: %s\n" % " ".join(br))
237
237
238 ui.debug("manifest: %d:%s\n" % (repo.manifest.rev(changes[0]),
238 ui.debug("manifest: %d:%s\n" % (repo.manifest.rev(changes[0]),
239 hg.hex(changes[0])))
239 hg.hex(changes[0])))
240 ui.status("user: %s\n" % changes[1])
240 ui.status("user: %s\n" % changes[1])
241 ui.status("date: %s\n" % date)
241 ui.status("date: %s\n" % date)
242
242
243 if ui.debugflag:
243 if ui.debugflag:
244 files = repo.changes(log.parents(changenode)[0], changenode)
244 files = repo.changes(log.parents(changenode)[0], changenode)
245 for key, value in zip(["files:", "files+:", "files-:"], files):
245 for key, value in zip(["files:", "files+:", "files-:"], files):
246 if value:
246 if value:
247 ui.note("%-12s %s\n" % (key, " ".join(value)))
247 ui.note("%-12s %s\n" % (key, " ".join(value)))
248 else:
248 else:
249 ui.note("files: %s\n" % " ".join(changes[3]))
249 ui.note("files: %s\n" % " ".join(changes[3]))
250
250
251 description = changes[4].strip()
251 description = changes[4].strip()
252 if description:
252 if description:
253 if ui.verbose:
253 if ui.verbose:
254 ui.status("description:\n")
254 ui.status("description:\n")
255 ui.status(description)
255 ui.status(description)
256 ui.status("\n\n")
256 ui.status("\n\n")
257 else:
257 else:
258 ui.status("summary: %s\n" % description.splitlines()[0])
258 ui.status("summary: %s\n" % description.splitlines()[0])
259 ui.status("\n")
259 ui.status("\n")
260
260
261 def show_version(ui):
261 def show_version(ui):
262 """output version and copyright information"""
262 """output version and copyright information"""
263 ui.write("Mercurial Distributed SCM (version %s)\n"
263 ui.write("Mercurial Distributed SCM (version %s)\n"
264 % version.get_version())
264 % version.get_version())
265 ui.status(
265 ui.status(
266 "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
266 "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
267 "This is free software; see the source for copying conditions. "
267 "This is free software; see the source for copying conditions. "
268 "There is NO\nwarranty; "
268 "There is NO\nwarranty; "
269 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
269 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
270 )
270 )
271
271
272 def help_(ui, cmd=None):
272 def help_(ui, cmd=None):
273 """show help for a given command or all commands"""
273 """show help for a given command or all commands"""
274 if cmd and cmd != 'shortlist':
274 if cmd and cmd != 'shortlist':
275 key, i = find(cmd)
275 key, i = find(cmd)
276 # synopsis
276 # synopsis
277 ui.write("%s\n\n" % i[2])
277 ui.write("%s\n\n" % i[2])
278
278
279 # description
279 # description
280 doc = i[0].__doc__
280 doc = i[0].__doc__
281 if ui.quiet:
281 if ui.quiet:
282 doc = doc.splitlines(0)[0]
282 doc = doc.splitlines(0)[0]
283 ui.write("%s\n" % doc.rstrip())
283 ui.write("%s\n" % doc.rstrip())
284
284
285 # aliases
285 # aliases
286 if not ui.quiet:
286 if not ui.quiet:
287 aliases = ', '.join(key.split('|')[1:])
287 aliases = ', '.join(key.split('|')[1:])
288 if aliases:
288 if aliases:
289 ui.write("\naliases: %s\n" % aliases)
289 ui.write("\naliases: %s\n" % aliases)
290
290
291 # options
291 # options
292 if not ui.quiet and i[1]:
292 if not ui.quiet and i[1]:
293 ui.write("\noptions:\n\n")
293 ui.write("\noptions:\n\n")
294 for s, l, d, c in i[1]:
294 for s, l, d, c in i[1]:
295 opt = ' '
295 opt = ' '
296 if s:
296 if s:
297 opt = opt + '-' + s + ' '
297 opt = opt + '-' + s + ' '
298 if l:
298 if l:
299 opt = opt + '--' + l + ' '
299 opt = opt + '--' + l + ' '
300 if d:
300 if d:
301 opt = opt + '(' + str(d) + ')'
301 opt = opt + '(' + str(d) + ')'
302 ui.write(opt, "\n")
302 ui.write(opt, "\n")
303 if c:
303 if c:
304 ui.write(' %s\n' % c)
304 ui.write(' %s\n' % c)
305
305
306 else:
306 else:
307 # program name
307 # program name
308 if ui.verbose:
308 if ui.verbose:
309 show_version(ui)
309 show_version(ui)
310 else:
310 else:
311 ui.status("Mercurial Distributed SCM\n")
311 ui.status("Mercurial Distributed SCM\n")
312 ui.status('\n')
312 ui.status('\n')
313
313
314 # list of commands
314 # list of commands
315 if cmd == "shortlist":
315 if cmd == "shortlist":
316 ui.status('basic commands (use "hg help" '
316 ui.status('basic commands (use "hg help" '
317 'for the full list or option "-v" for details):\n\n')
317 'for the full list or option "-v" for details):\n\n')
318 elif ui.verbose:
318 elif ui.verbose:
319 ui.status('list of commands:\n\n')
319 ui.status('list of commands:\n\n')
320 else:
320 else:
321 ui.status('list of commands (use "hg help -v" '
321 ui.status('list of commands (use "hg help -v" '
322 'to show aliases and global options):\n\n')
322 'to show aliases and global options):\n\n')
323
323
324 h = {}
324 h = {}
325 cmds = {}
325 cmds = {}
326 for c, e in table.items():
326 for c, e in table.items():
327 f = c.split("|")[0]
327 f = c.split("|")[0]
328 if cmd == "shortlist" and not f.startswith("^"):
328 if cmd == "shortlist" and not f.startswith("^"):
329 continue
329 continue
330 f = f.lstrip("^")
330 f = f.lstrip("^")
331 if not ui.debugflag and f.startswith("debug"):
331 if not ui.debugflag and f.startswith("debug"):
332 continue
332 continue
333 d = ""
333 d = ""
334 if e[0].__doc__:
334 if e[0].__doc__:
335 d = e[0].__doc__.splitlines(0)[0].rstrip()
335 d = e[0].__doc__.splitlines(0)[0].rstrip()
336 h[f] = d
336 h[f] = d
337 cmds[f]=c.lstrip("^")
337 cmds[f]=c.lstrip("^")
338
338
339 fns = h.keys()
339 fns = h.keys()
340 fns.sort()
340 fns.sort()
341 m = max(map(len, fns))
341 m = max(map(len, fns))
342 for f in fns:
342 for f in fns:
343 if ui.verbose:
343 if ui.verbose:
344 commands = cmds[f].replace("|",", ")
344 commands = cmds[f].replace("|",", ")
345 ui.write(" %s:\n %s\n"%(commands,h[f]))
345 ui.write(" %s:\n %s\n"%(commands,h[f]))
346 else:
346 else:
347 ui.write(' %-*s %s\n' % (m, f, h[f]))
347 ui.write(' %-*s %s\n' % (m, f, h[f]))
348
348
349 # global options
349 # global options
350 if ui.verbose:
350 if ui.verbose:
351 ui.write("\nglobal options:\n\n")
351 ui.write("\nglobal options:\n\n")
352 for s, l, d, c in globalopts:
352 for s, l, d, c in globalopts:
353 opt = ' '
353 opt = ' '
354 if s:
354 if s:
355 opt = opt + '-' + s + ' '
355 opt = opt + '-' + s + ' '
356 if l:
356 if l:
357 opt = opt + '--' + l + ' '
357 opt = opt + '--' + l + ' '
358 if d:
358 if d:
359 opt = opt + '(' + str(d) + ')'
359 opt = opt + '(' + str(d) + ')'
360 ui.write(opt, "\n")
360 ui.write(opt, "\n")
361 if c:
361 if c:
362 ui.write(' %s\n' % c)
362 ui.write(' %s\n' % c)
363
363
364 # Commands start here, listed alphabetically
364 # Commands start here, listed alphabetically
365
365
366 def add(ui, repo, *pats, **opts):
366 def add(ui, repo, *pats, **opts):
367 '''add the specified files on the next commit'''
367 '''add the specified files on the next commit'''
368 names = []
368 names = []
369 for src, abs, rel, exact in walk(repo, pats, opts):
369 for src, abs, rel, exact in walk(repo, pats, opts):
370 if exact:
370 if exact:
371 names.append(abs)
371 names.append(abs)
372 elif repo.dirstate.state(abs) == '?':
372 elif repo.dirstate.state(abs) == '?':
373 ui.status('adding %s\n' % rel)
373 ui.status('adding %s\n' % rel)
374 names.append(abs)
374 names.append(abs)
375 repo.add(names)
375 repo.add(names)
376
376
377 def addremove(ui, repo, *pats, **opts):
377 def addremove(ui, repo, *pats, **opts):
378 """add all new files, delete all missing files"""
378 """add all new files, delete all missing files"""
379 add, remove = [], []
379 add, remove = [], []
380 for src, abs, rel, exact in walk(repo, pats, opts):
380 for src, abs, rel, exact in walk(repo, pats, opts):
381 if src == 'f' and repo.dirstate.state(abs) == '?':
381 if src == 'f' and repo.dirstate.state(abs) == '?':
382 add.append(abs)
382 add.append(abs)
383 if not exact: ui.status('adding ', rel, '\n')
383 if not exact: ui.status('adding ', rel, '\n')
384 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
384 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
385 remove.append(abs)
385 remove.append(abs)
386 if not exact: ui.status('removing ', rel, '\n')
386 if not exact: ui.status('removing ', rel, '\n')
387 repo.add(add)
387 repo.add(add)
388 repo.remove(remove)
388 repo.remove(remove)
389
389
390 def annotate(ui, repo, *pats, **opts):
390 def annotate(ui, repo, *pats, **opts):
391 """show changeset information per file line"""
391 """show changeset information per file line"""
392 def getnode(rev):
392 def getnode(rev):
393 return hg.short(repo.changelog.node(rev))
393 return hg.short(repo.changelog.node(rev))
394
394
395 def getname(rev):
395 def getname(rev):
396 try:
396 try:
397 return bcache[rev]
397 return bcache[rev]
398 except KeyError:
398 except KeyError:
399 cl = repo.changelog.read(repo.changelog.node(rev))
399 cl = repo.changelog.read(repo.changelog.node(rev))
400 name = cl[1]
400 name = cl[1]
401 f = name.find('@')
401 f = name.find('@')
402 if f >= 0:
402 if f >= 0:
403 name = name[:f]
403 name = name[:f]
404 f = name.find('<')
404 f = name.find('<')
405 if f >= 0:
405 if f >= 0:
406 name = name[f+1:]
406 name = name[f+1:]
407 bcache[rev] = name
407 bcache[rev] = name
408 return name
408 return name
409
409
410 if not pats:
410 if not pats:
411 raise util.Abort('at least one file name or pattern required')
411 raise util.Abort('at least one file name or pattern required')
412
412
413 bcache = {}
413 bcache = {}
414 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
414 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
415 if not opts['user'] and not opts['changeset']:
415 if not opts['user'] and not opts['changeset']:
416 opts['number'] = 1
416 opts['number'] = 1
417
417
418 if opts['rev']:
418 if opts['rev']:
419 node = repo.changelog.lookup(opts['rev'])
419 node = repo.changelog.lookup(opts['rev'])
420 else:
420 else:
421 node = repo.dirstate.parents()[0]
421 node = repo.dirstate.parents()[0]
422 change = repo.changelog.read(node)
422 change = repo.changelog.read(node)
423 mmap = repo.manifest.read(change[0])
423 mmap = repo.manifest.read(change[0])
424
424
425 for src, abs, rel, exact in walk(repo, pats, opts):
425 for src, abs, rel, exact in walk(repo, pats, opts):
426 if abs not in mmap:
426 if abs not in mmap:
427 ui.warn("warning: %s is not in the repository!\n" % rel)
427 ui.warn("warning: %s is not in the repository!\n" % rel)
428 continue
428 continue
429
429
430 f = repo.file(abs)
430 f = repo.file(abs)
431 if not opts['text'] and util.binary(f.read(mmap[abs])):
431 if not opts['text'] and util.binary(f.read(mmap[abs])):
432 ui.write("%s: binary file\n" % rel)
432 ui.write("%s: binary file\n" % rel)
433 continue
433 continue
434
434
435 lines = f.annotate(mmap[abs])
435 lines = f.annotate(mmap[abs])
436 pieces = []
436 pieces = []
437
437
438 for o, f in opmap:
438 for o, f in opmap:
439 if opts[o]:
439 if opts[o]:
440 l = [f(n) for n, dummy in lines]
440 l = [f(n) for n, dummy in lines]
441 if l:
441 if l:
442 m = max(map(len, l))
442 m = max(map(len, l))
443 pieces.append(["%*s" % (m, x) for x in l])
443 pieces.append(["%*s" % (m, x) for x in l])
444
444
445 if pieces:
445 if pieces:
446 for p, l in zip(zip(*pieces), lines):
446 for p, l in zip(zip(*pieces), lines):
447 ui.write("%s: %s" % (" ".join(p), l[1]))
447 ui.write("%s: %s" % (" ".join(p), l[1]))
448
448
449 def cat(ui, repo, file1, rev=None, **opts):
449 def cat(ui, repo, file1, rev=None, **opts):
450 """output the latest or given revision of a file"""
450 """output the latest or given revision of a file"""
451 r = repo.file(relpath(repo, [file1])[0])
451 r = repo.file(relpath(repo, [file1])[0])
452 if rev:
452 if rev:
453 try:
453 try:
454 # assume all revision numbers are for changesets
454 # assume all revision numbers are for changesets
455 n = repo.lookup(rev)
455 n = repo.lookup(rev)
456 change = repo.changelog.read(n)
456 change = repo.changelog.read(n)
457 m = repo.manifest.read(change[0])
457 m = repo.manifest.read(change[0])
458 n = m[relpath(repo, [file1])[0]]
458 n = m[relpath(repo, [file1])[0]]
459 except hg.RepoError, KeyError:
459 except hg.RepoError, KeyError:
460 n = r.lookup(rev)
460 n = r.lookup(rev)
461 else:
461 else:
462 n = r.tip()
462 n = r.tip()
463 fp = make_file(repo, r, opts['output'], node=n)
463 fp = make_file(repo, r, opts['output'], node=n)
464 fp.write(r.read(n))
464 fp.write(r.read(n))
465
465
466 def clone(ui, source, dest=None, **opts):
466 def clone(ui, source, dest=None, **opts):
467 """make a copy of an existing repository"""
467 """make a copy of an existing repository"""
468 if dest is None:
468 if dest is None:
469 dest = os.path.basename(os.path.normpath(source))
469 dest = os.path.basename(os.path.normpath(source))
470
470
471 if os.path.exists(dest):
471 if os.path.exists(dest):
472 ui.warn("abort: destination '%s' already exists\n" % dest)
472 ui.warn("abort: destination '%s' already exists\n" % dest)
473 return 1
473 return 1
474
474
475 dest = os.path.realpath(dest)
475 dest = os.path.realpath(dest)
476
476
477 class Dircleanup:
477 class Dircleanup:
478 def __init__(self, dir_):
478 def __init__(self, dir_):
479 self.rmtree = shutil.rmtree
479 self.rmtree = shutil.rmtree
480 self.dir_ = dir_
480 self.dir_ = dir_
481 os.mkdir(dir_)
481 os.mkdir(dir_)
482 def close(self):
482 def close(self):
483 self.dir_ = None
483 self.dir_ = None
484 def __del__(self):
484 def __del__(self):
485 if self.dir_:
485 if self.dir_:
486 self.rmtree(self.dir_, True)
486 self.rmtree(self.dir_, True)
487
487
488 if opts['ssh']:
488 if opts['ssh']:
489 ui.setconfig("ui", "ssh", opts['ssh'])
489 ui.setconfig("ui", "ssh", opts['ssh'])
490 if opts['remotecmd']:
490 if opts['remotecmd']:
491 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
491 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
492
492
493 d = Dircleanup(dest)
493 d = Dircleanup(dest)
494 source = ui.expandpath(source)
494 source = ui.expandpath(source)
495 abspath = source
495 abspath = source
496 other = hg.repository(ui, source)
496 other = hg.repository(ui, source)
497
497
498 if other.dev() != -1:
498 if other.dev() != -1:
499 abspath = os.path.abspath(source)
499 abspath = os.path.abspath(source)
500 copyfile = (os.stat(dest).st_dev == other.dev()
500 copyfile = (os.stat(dest).st_dev == other.dev()
501 and getattr(os, 'link', None) or shutil.copy2)
501 and getattr(os, 'link', None) or shutil.copy2)
502 if copyfile is not shutil.copy2:
502 if copyfile is not shutil.copy2:
503 ui.note("cloning by hardlink\n")
503 ui.note("cloning by hardlink\n")
504 # we use a lock here because because we're not nicely ordered
504 # we use a lock here because because we're not nicely ordered
505 l = lock.lock(os.path.join(source, ".hg", "lock"))
505 l = lock.lock(os.path.join(source, ".hg", "lock"))
506
506
507 util.copytree(os.path.join(source, ".hg"), os.path.join(dest, ".hg"),
507 util.copytree(os.path.join(source, ".hg"), os.path.join(dest, ".hg"),
508 copyfile)
508 copyfile)
509 try:
509 try:
510 os.unlink(os.path.join(dest, ".hg", "dirstate"))
510 os.unlink(os.path.join(dest, ".hg", "dirstate"))
511 except OSError:
511 except OSError:
512 pass
512 pass
513
513
514 repo = hg.repository(ui, dest)
514 repo = hg.repository(ui, dest)
515
515
516 else:
516 else:
517 repo = hg.repository(ui, dest, create=1)
517 repo = hg.repository(ui, dest, create=1)
518 repo.pull(other)
518 repo.pull(other)
519
519
520 f = repo.opener("hgrc", "w")
520 f = repo.opener("hgrc", "w")
521 f.write("[paths]\n")
521 f.write("[paths]\n")
522 f.write("default = %s\n" % abspath)
522 f.write("default = %s\n" % abspath)
523
523
524 if not opts['noupdate']:
524 if not opts['noupdate']:
525 update(ui, repo)
525 update(ui, repo)
526
526
527 d.close()
527 d.close()
528
528
529 def commit(ui, repo, *pats, **opts):
529 def commit(ui, repo, *pats, **opts):
530 """commit the specified files or all outstanding changes"""
530 """commit the specified files or all outstanding changes"""
531 if opts['text']:
531 if opts['text']:
532 ui.warn("Warning: -t and --text is deprecated,"
532 ui.warn("Warning: -t and --text is deprecated,"
533 " please use -m or --message instead.\n")
533 " please use -m or --message instead.\n")
534 message = opts['message'] or opts['text']
534 message = opts['message'] or opts['text']
535 logfile = opts['logfile']
535 logfile = opts['logfile']
536 if not message and logfile:
536 if not message and logfile:
537 try:
537 try:
538 if logfile == '-':
538 if logfile == '-':
539 message = sys.stdin.read()
539 message = sys.stdin.read()
540 else:
540 else:
541 message = open(logfile).read()
541 message = open(logfile).read()
542 except IOError, why:
542 except IOError, why:
543 ui.warn("Can't read commit message %s: %s\n" % (logfile, why))
543 ui.warn("Can't read commit message %s: %s\n" % (logfile, why))
544
544
545 if opts['addremove']:
545 if opts['addremove']:
546 addremove(ui, repo, *pats, **opts)
546 addremove(ui, repo, *pats, **opts)
547 cwd = repo.getcwd()
547 cwd = repo.getcwd()
548 if not pats and cwd:
548 if not pats and cwd:
549 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
549 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
550 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
550 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
551 fns, match, anypats = matchpats(repo, (pats and repo.getcwd()) or '',
551 fns, match, anypats = matchpats(repo, (pats and repo.getcwd()) or '',
552 pats, opts)
552 pats, opts)
553 if pats:
553 if pats:
554 c, a, d, u = repo.changes(files = fns, match = match)
554 c, a, d, u = repo.changes(files = fns, match = match)
555 files = c + a + [fn for fn in d if repo.dirstate.state(fn) == 'r']
555 files = c + a + [fn for fn in d if repo.dirstate.state(fn) == 'r']
556 else:
556 else:
557 files = []
557 files = []
558 repo.commit(files, message, opts['user'], opts['date'], match)
558 repo.commit(files, message, opts['user'], opts['date'], match)
559
559
560 def copy(ui, repo, source, dest):
560 def copy(ui, repo, source, dest):
561 """mark a file as copied or renamed for the next commit"""
561 """mark a file as copied or renamed for the next commit"""
562 return repo.copy(*relpath(repo, (source, dest)))
562 return repo.copy(*relpath(repo, (source, dest)))
563
563
564 def debugcheckstate(ui, repo):
564 def debugcheckstate(ui, repo):
565 """validate the correctness of the current dirstate"""
565 """validate the correctness of the current dirstate"""
566 parent1, parent2 = repo.dirstate.parents()
566 parent1, parent2 = repo.dirstate.parents()
567 repo.dirstate.read()
567 repo.dirstate.read()
568 dc = repo.dirstate.map
568 dc = repo.dirstate.map
569 keys = dc.keys()
569 keys = dc.keys()
570 keys.sort()
570 keys.sort()
571 m1n = repo.changelog.read(parent1)[0]
571 m1n = repo.changelog.read(parent1)[0]
572 m2n = repo.changelog.read(parent2)[0]
572 m2n = repo.changelog.read(parent2)[0]
573 m1 = repo.manifest.read(m1n)
573 m1 = repo.manifest.read(m1n)
574 m2 = repo.manifest.read(m2n)
574 m2 = repo.manifest.read(m2n)
575 errors = 0
575 errors = 0
576 for f in dc:
576 for f in dc:
577 state = repo.dirstate.state(f)
577 state = repo.dirstate.state(f)
578 if state in "nr" and f not in m1:
578 if state in "nr" and f not in m1:
579 ui.warn("%s in state %s, but not in manifest1\n" % (f, state))
579 ui.warn("%s in state %s, but not in manifest1\n" % (f, state))
580 errors += 1
580 errors += 1
581 if state in "a" and f in m1:
581 if state in "a" and f in m1:
582 ui.warn("%s in state %s, but also in manifest1\n" % (f, state))
582 ui.warn("%s in state %s, but also in manifest1\n" % (f, state))
583 errors += 1
583 errors += 1
584 if state in "m" and f not in m1 and f not in m2:
584 if state in "m" and f not in m1 and f not in m2:
585 ui.warn("%s in state %s, but not in either manifest\n" %
585 ui.warn("%s in state %s, but not in either manifest\n" %
586 (f, state))
586 (f, state))
587 errors += 1
587 errors += 1
588 for f in m1:
588 for f in m1:
589 state = repo.dirstate.state(f)
589 state = repo.dirstate.state(f)
590 if state not in "nrm":
590 if state not in "nrm":
591 ui.warn("%s in manifest1, but listed as state %s" % (f, state))
591 ui.warn("%s in manifest1, but listed as state %s" % (f, state))
592 errors += 1
592 errors += 1
593 if errors:
593 if errors:
594 raise util.Abort(".hg/dirstate inconsistent with current parent's manifest")
594 raise util.Abort(".hg/dirstate inconsistent with current parent's manifest")
595
595
596 def debugconfig(ui):
596 def debugconfig(ui):
597 try:
597 try:
598 repo = hg.repository(ui)
598 repo = hg.repository(ui)
599 except: pass
599 except: pass
600 for section, name, value in ui.walkconfig():
600 for section, name, value in ui.walkconfig():
601 ui.write('%s.%s=%s\n' % (section, name, value))
601 ui.write('%s.%s=%s\n' % (section, name, value))
602
602
603 def debugstate(ui, repo):
603 def debugstate(ui, repo):
604 """show the contents of the current dirstate"""
604 """show the contents of the current dirstate"""
605 repo.dirstate.read()
605 repo.dirstate.read()
606 dc = repo.dirstate.map
606 dc = repo.dirstate.map
607 keys = dc.keys()
607 keys = dc.keys()
608 keys.sort()
608 keys.sort()
609 for file_ in keys:
609 for file_ in keys:
610 ui.write("%c %3o %10d %s %s\n"
610 ui.write("%c %3o %10d %s %s\n"
611 % (dc[file_][0], dc[file_][1] & 0777, dc[file_][2],
611 % (dc[file_][0], dc[file_][1] & 0777, dc[file_][2],
612 time.strftime("%x %X",
612 time.strftime("%x %X",
613 time.localtime(dc[file_][3])), file_))
613 time.localtime(dc[file_][3])), file_))
614
614
615 def debugdata(ui, file_, rev):
615 def debugdata(ui, file_, rev):
616 """dump the contents of an data file revision"""
616 """dump the contents of an data file revision"""
617 r = hg.revlog(hg.opener(""), file_[:-2] + ".i", file_)
617 r = hg.revlog(hg.opener(""), file_[:-2] + ".i", file_)
618 ui.write(r.revision(r.lookup(rev)))
618 ui.write(r.revision(r.lookup(rev)))
619
619
620 def debugindex(ui, file_):
620 def debugindex(ui, file_):
621 """dump the contents of an index file"""
621 """dump the contents of an index file"""
622 r = hg.revlog(hg.opener(""), file_, "")
622 r = hg.revlog(hg.opener(""), file_, "")
623 ui.write(" rev offset length base linkrev" +
623 ui.write(" rev offset length base linkrev" +
624 " nodeid p1 p2\n")
624 " nodeid p1 p2\n")
625 for i in range(r.count()):
625 for i in range(r.count()):
626 e = r.index[i]
626 e = r.index[i]
627 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
627 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
628 i, e[0], e[1], e[2], e[3],
628 i, e[0], e[1], e[2], e[3],
629 hg.short(e[6]), hg.short(e[4]), hg.short(e[5])))
629 hg.short(e[6]), hg.short(e[4]), hg.short(e[5])))
630
630
631 def debugindexdot(ui, file_):
631 def debugindexdot(ui, file_):
632 """dump an index DAG as a .dot file"""
632 """dump an index DAG as a .dot file"""
633 r = hg.revlog(hg.opener(""), file_, "")
633 r = hg.revlog(hg.opener(""), file_, "")
634 ui.write("digraph G {\n")
634 ui.write("digraph G {\n")
635 for i in range(r.count()):
635 for i in range(r.count()):
636 e = r.index[i]
636 e = r.index[i]
637 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i))
637 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i))
638 if e[5] != hg.nullid:
638 if e[5] != hg.nullid:
639 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i))
639 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i))
640 ui.write("}\n")
640 ui.write("}\n")
641
641
642 def debugwalk(ui, repo, *pats, **opts):
642 def debugwalk(ui, repo, *pats, **opts):
643 items = list(walk(repo, pats, opts))
643 items = list(walk(repo, pats, opts))
644 if not items: return
644 if not items: return
645 fmt = '%%s %%-%ds %%-%ds %%s' % (
645 fmt = '%%s %%-%ds %%-%ds %%s' % (
646 max([len(abs) for (src, abs, rel, exact) in items]),
646 max([len(abs) for (src, abs, rel, exact) in items]),
647 max([len(rel) for (src, abs, rel, exact) in items]))
647 max([len(rel) for (src, abs, rel, exact) in items]))
648 exactly = {True: 'exact', False: ''}
648 exactly = {True: 'exact', False: ''}
649 for src, abs, rel, exact in items:
649 for src, abs, rel, exact in items:
650 print fmt % (src, abs, rel, exactly[exact])
650 print fmt % (src, abs, rel, exactly[exact])
651
651
652 def diff(ui, repo, *pats, **opts):
652 def diff(ui, repo, *pats, **opts):
653 """diff working directory (or selected files)"""
653 """diff working directory (or selected files)"""
654 node1, node2 = None, None
654 node1, node2 = None, None
655 revs = [repo.lookup(x) for x in opts['rev']]
655 revs = [repo.lookup(x) for x in opts['rev']]
656
656
657 if len(revs) > 0:
657 if len(revs) > 0:
658 node1 = revs[0]
658 node1 = revs[0]
659 if len(revs) > 1:
659 if len(revs) > 1:
660 node2 = revs[1]
660 node2 = revs[1]
661 if len(revs) > 2:
661 if len(revs) > 2:
662 raise util.Abort("too many revisions to diff")
662 raise util.Abort("too many revisions to diff")
663
663
664 files = []
664 files = []
665 match = util.always
665 match = util.always
666 if pats:
666 if pats:
667 roots, match, results = makewalk(repo, pats, opts)
667 roots, match, results = makewalk(repo, pats, opts)
668 for src, abs, rel, exact in results:
668 for src, abs, rel, exact in results:
669 files.append(abs)
669 files.append(abs)
670
670
671 dodiff(sys.stdout, ui, repo, node1, node2, files, match=match,
671 dodiff(sys.stdout, ui, repo, node1, node2, files, match=match,
672 text=opts['text'])
672 text=opts['text'])
673
673
674 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
674 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
675 node = repo.lookup(changeset)
675 node = repo.lookup(changeset)
676 prev, other = repo.changelog.parents(node)
676 prev, other = repo.changelog.parents(node)
677 change = repo.changelog.read(node)
677 change = repo.changelog.read(node)
678
678
679 fp = make_file(repo, repo.changelog, opts['output'],
679 fp = make_file(repo, repo.changelog, opts['output'],
680 node=node, total=total, seqno=seqno,
680 node=node, total=total, seqno=seqno,
681 revwidth=revwidth)
681 revwidth=revwidth)
682 if fp != sys.stdout:
682 if fp != sys.stdout:
683 ui.note("%s\n" % fp.name)
683 ui.note("%s\n" % fp.name)
684
684
685 fp.write("# HG changeset patch\n")
685 fp.write("# HG changeset patch\n")
686 fp.write("# User %s\n" % change[1])
686 fp.write("# User %s\n" % change[1])
687 fp.write("# Node ID %s\n" % hg.hex(node))
687 fp.write("# Node ID %s\n" % hg.hex(node))
688 fp.write("# Parent %s\n" % hg.hex(prev))
688 fp.write("# Parent %s\n" % hg.hex(prev))
689 if other != hg.nullid:
689 if other != hg.nullid:
690 fp.write("# Parent %s\n" % hg.hex(other))
690 fp.write("# Parent %s\n" % hg.hex(other))
691 fp.write(change[4].rstrip())
691 fp.write(change[4].rstrip())
692 fp.write("\n\n")
692 fp.write("\n\n")
693
693
694 dodiff(fp, ui, repo, prev, node, text=opts['text'])
694 dodiff(fp, ui, repo, prev, node, text=opts['text'])
695 if fp != sys.stdout: fp.close()
695 if fp != sys.stdout: fp.close()
696
696
697 def export(ui, repo, *changesets, **opts):
697 def export(ui, repo, *changesets, **opts):
698 """dump the header and diffs for one or more changesets"""
698 """dump the header and diffs for one or more changesets"""
699 if not changesets:
699 if not changesets:
700 raise util.Abort("export requires at least one changeset")
700 raise util.Abort("export requires at least one changeset")
701 seqno = 0
701 seqno = 0
702 revs = list(revrange(ui, repo, changesets))
702 revs = list(revrange(ui, repo, changesets))
703 total = len(revs)
703 total = len(revs)
704 revwidth = max(len(revs[0]), len(revs[-1]))
704 revwidth = max(len(revs[0]), len(revs[-1]))
705 ui.note(len(revs) > 1 and "Exporting patches:\n" or "Exporting patch:\n")
705 ui.note(len(revs) > 1 and "Exporting patches:\n" or "Exporting patch:\n")
706 for cset in revs:
706 for cset in revs:
707 seqno += 1
707 seqno += 1
708 doexport(ui, repo, cset, seqno, total, revwidth, opts)
708 doexport(ui, repo, cset, seqno, total, revwidth, opts)
709
709
710 def forget(ui, repo, *pats, **opts):
710 def forget(ui, repo, *pats, **opts):
711 """don't add the specified files on the next commit"""
711 """don't add the specified files on the next commit"""
712 forget = []
712 forget = []
713 for src, abs, rel, exact in walk(repo, pats, opts):
713 for src, abs, rel, exact in walk(repo, pats, opts):
714 if repo.dirstate.state(abs) == 'a':
714 if repo.dirstate.state(abs) == 'a':
715 forget.append(abs)
715 forget.append(abs)
716 if not exact: ui.status('forgetting ', rel, '\n')
716 if not exact: ui.status('forgetting ', rel, '\n')
717 repo.forget(forget)
717 repo.forget(forget)
718
718
719 def heads(ui, repo, **opts):
719 def heads(ui, repo, **opts):
720 """show current repository heads"""
720 """show current repository heads"""
721 heads = repo.changelog.heads()
721 heads = repo.changelog.heads()
722 br = None
722 br = None
723 if opts['branches']:
723 if opts['branches']:
724 br = repo.branchlookup(heads)
724 br = repo.branchlookup(heads)
725 for n in repo.changelog.heads():
725 for n in repo.changelog.heads():
726 show_changeset(ui, repo, changenode=n, brinfo=br)
726 show_changeset(ui, repo, changenode=n, brinfo=br)
727
727
728 def identify(ui, repo):
728 def identify(ui, repo):
729 """print information about the working copy"""
729 """print information about the working copy"""
730 parents = [p for p in repo.dirstate.parents() if p != hg.nullid]
730 parents = [p for p in repo.dirstate.parents() if p != hg.nullid]
731 if not parents:
731 if not parents:
732 ui.write("unknown\n")
732 ui.write("unknown\n")
733 return
733 return
734
734
735 hexfunc = ui.verbose and hg.hex or hg.short
735 hexfunc = ui.verbose and hg.hex or hg.short
736 (c, a, d, u) = repo.changes()
736 (c, a, d, u) = repo.changes()
737 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
737 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
738 (c or a or d) and "+" or "")]
738 (c or a or d) and "+" or "")]
739
739
740 if not ui.quiet:
740 if not ui.quiet:
741 # multiple tags for a single parent separated by '/'
741 # multiple tags for a single parent separated by '/'
742 parenttags = ['/'.join(tags)
742 parenttags = ['/'.join(tags)
743 for tags in map(repo.nodetags, parents) if tags]
743 for tags in map(repo.nodetags, parents) if tags]
744 # tags for multiple parents separated by ' + '
744 # tags for multiple parents separated by ' + '
745 if parenttags:
745 if parenttags:
746 output.append(' + '.join(parenttags))
746 output.append(' + '.join(parenttags))
747
747
748 ui.write("%s\n" % ' '.join(output))
748 ui.write("%s\n" % ' '.join(output))
749
749
750 def import_(ui, repo, patch1, *patches, **opts):
750 def import_(ui, repo, patch1, *patches, **opts):
751 """import an ordered set of patches"""
751 """import an ordered set of patches"""
752 patches = (patch1,) + patches
752 patches = (patch1,) + patches
753
753
754 if not opts['force']:
754 if not opts['force']:
755 (c, a, d, u) = repo.changes()
755 (c, a, d, u) = repo.changes()
756 if c or a or d:
756 if c or a or d:
757 ui.warn("abort: outstanding uncommitted changes!\n")
757 ui.warn("abort: outstanding uncommitted changes!\n")
758 return 1
758 return 1
759
759
760 d = opts["base"]
760 d = opts["base"]
761 strip = opts["strip"]
761 strip = opts["strip"]
762
762
763 for patch in patches:
763 for patch in patches:
764 ui.status("applying %s\n" % patch)
764 ui.status("applying %s\n" % patch)
765 pf = os.path.join(d, patch)
765 pf = os.path.join(d, patch)
766
766
767 message = []
767 message = []
768 user = None
768 user = None
769 hgpatch = False
769 hgpatch = False
770 for line in file(pf):
770 for line in file(pf):
771 line = line.rstrip()
771 line = line.rstrip()
772 if line.startswith("--- ") or line.startswith("diff -r"):
772 if line.startswith("--- ") or line.startswith("diff -r"):
773 break
773 break
774 elif hgpatch:
774 elif hgpatch:
775 # parse values when importing the result of an hg export
775 # parse values when importing the result of an hg export
776 if line.startswith("# User "):
776 if line.startswith("# User "):
777 user = line[7:]
777 user = line[7:]
778 ui.debug('User: %s\n' % user)
778 ui.debug('User: %s\n' % user)
779 elif not line.startswith("# ") and line:
779 elif not line.startswith("# ") and line:
780 message.append(line)
780 message.append(line)
781 hgpatch = False
781 hgpatch = False
782 elif line == '# HG changeset patch':
782 elif line == '# HG changeset patch':
783 hgpatch = True
783 hgpatch = True
784 message = [] # We may have collected garbage
784 message = [] # We may have collected garbage
785 else:
785 else:
786 message.append(line)
786 message.append(line)
787
787
788 # make sure message isn't empty
788 # make sure message isn't empty
789 if not message:
789 if not message:
790 message = "imported patch %s\n" % patch
790 message = "imported patch %s\n" % patch
791 else:
791 else:
792 message = "%s\n" % '\n'.join(message)
792 message = "%s\n" % '\n'.join(message)
793 ui.debug('message:\n%s\n' % message)
793 ui.debug('message:\n%s\n' % message)
794
794
795 f = os.popen("patch -p%d < '%s'" % (strip, pf))
795 f = os.popen("patch -p%d < '%s'" % (strip, pf))
796 files = []
796 files = []
797 for l in f.read().splitlines():
797 for l in f.read().splitlines():
798 l.rstrip('\r\n');
798 l.rstrip('\r\n');
799 ui.status("%s\n" % l)
799 ui.status("%s\n" % l)
800 if l.startswith('patching file '):
800 if l.startswith('patching file '):
801 pf = l[14:]
801 pf = l[14:]
802 if pf not in files:
802 if pf not in files:
803 files.append(pf)
803 files.append(pf)
804 patcherr = f.close()
804 patcherr = f.close()
805 if patcherr:
805 if patcherr:
806 raise util.Abort("patch failed")
806 raise util.Abort("patch failed")
807
807
808 if len(files) > 0:
808 if len(files) > 0:
809 addremove(ui, repo, *files)
809 addremove(ui, repo, *files)
810 repo.commit(files, message, user)
810 repo.commit(files, message, user)
811
811
812 def incoming(ui, repo, source="default"):
812 def incoming(ui, repo, source="default"):
813 """show new changesets found in source"""
813 """show new changesets found in source"""
814 source = ui.expandpath(source)
814 source = ui.expandpath(source)
815 other = hg.repository(ui, source)
815 other = hg.repository(ui, source)
816 if not other.local():
816 if not other.local():
817 ui.warn("abort: incoming doesn't work for remote"
817 ui.warn("abort: incoming doesn't work for remote"
818 + " repositories yet, sorry!\n")
818 + " repositories yet, sorry!\n")
819 return 1
819 return 1
820 o = repo.findincoming(other)
820 o = repo.findincoming(other)
821 if not o:
821 if not o:
822 return
822 return
823 o = other.newer(o)
823 o = other.newer(o)
824 o.reverse()
824 o.reverse()
825 for n in o:
825 for n in o:
826 show_changeset(ui, other, changenode=n)
826 show_changeset(ui, other, changenode=n)
827
827
828 def init(ui, dest="."):
828 def init(ui, dest="."):
829 """create a new repository in the given directory"""
829 """create a new repository in the given directory"""
830 if not os.path.exists(dest):
830 if not os.path.exists(dest):
831 os.mkdir(dest)
831 os.mkdir(dest)
832 hg.repository(ui, dest, create=1)
832 hg.repository(ui, dest, create=1)
833
833
834 def locate(ui, repo, *pats, **opts):
834 def locate(ui, repo, *pats, **opts):
835 """locate files matching specific patterns"""
835 """locate files matching specific patterns"""
836 end = '\n'
836 end = '\n'
837 if opts['print0']: end = '\0'
837 if opts['print0']: end = '\0'
838
838
839 for src, abs, rel, exact in walk(repo, pats, opts, '(?:.*/|)'):
839 for src, abs, rel, exact in walk(repo, pats, opts, '(?:.*/|)'):
840 if repo.dirstate.state(abs) == '?': continue
840 if repo.dirstate.state(abs) == '?': continue
841 if opts['fullpath']:
841 if opts['fullpath']:
842 ui.write(os.path.join(repo.root, abs), end)
842 ui.write(os.path.join(repo.root, abs), end)
843 else:
843 else:
844 ui.write(rel, end)
844 ui.write(rel, end)
845
845
846 def log(ui, repo, *pats, **opts):
846 def log(ui, repo, *pats, **opts):
847 """show revision history of entire repository or files"""
847 """show revision history of entire repository or files"""
848 # This code most commonly needs to iterate backwards over the
848 # This code most commonly needs to iterate backwards over the
849 # history it is interested in. This has awful (quadratic-looking)
849 # history it is interested in. This has awful (quadratic-looking)
850 # performance, so we use iterators that walk forwards through
850 # performance, so we use iterators that walk forwards through
851 # windows of revisions, yielding revisions in reverse order, while
851 # windows of revisions, yielding revisions in reverse order, while
852 # walking the windows backwards.
852 # walking the windows backwards.
853 cwd = repo.getcwd()
853 cwd = repo.getcwd()
854 if not pats and cwd:
854 if not pats and cwd:
855 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
855 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
856 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
856 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
857 files, matchfn, anypats = matchpats(repo, (pats and cwd) or '',
857 files, matchfn, anypats = matchpats(repo, (pats and cwd) or '',
858 pats, opts)
858 pats, opts)
859 revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
859 revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
860 wanted = {}
860 wanted = {}
861 slowpath = anypats
861 slowpath = anypats
862 window = 300
862 window = 300
863 if not slowpath and not files:
863 if not slowpath and not files:
864 # No files, no patterns. Display all revs.
864 # No files, no patterns. Display all revs.
865 wanted = dict(zip(revs, revs))
865 wanted = dict(zip(revs, revs))
866 if not slowpath:
866 if not slowpath:
867 # Only files, no patterns. Check the history of each file.
867 # Only files, no patterns. Check the history of each file.
868 def filerevgen(filelog):
868 def filerevgen(filelog):
869 for i in xrange(filelog.count() - 1, -1, -window):
869 for i in xrange(filelog.count() - 1, -1, -window):
870 revs = []
870 revs = []
871 for j in xrange(max(0, i - window), i + 1):
871 for j in xrange(max(0, i - window), i + 1):
872 revs.append(filelog.linkrev(filelog.node(j)))
872 revs.append(filelog.linkrev(filelog.node(j)))
873 revs.reverse()
873 revs.reverse()
874 for rev in revs:
874 for rev in revs:
875 yield rev
875 yield rev
876
876
877 minrev, maxrev = min(revs), max(revs)
877 minrev, maxrev = min(revs), max(revs)
878 for filelog in map(repo.file, files):
878 for filelog in map(repo.file, files):
879 # A zero count may be a directory or deleted file, so
879 # A zero count may be a directory or deleted file, so
880 # try to find matching entries on the slow path.
880 # try to find matching entries on the slow path.
881 if filelog.count() == 0:
881 if filelog.count() == 0:
882 slowpath = True
882 slowpath = True
883 break
883 break
884 for rev in filerevgen(filelog):
884 for rev in filerevgen(filelog):
885 if rev <= maxrev:
885 if rev <= maxrev:
886 if rev < minrev: break
886 if rev < minrev: break
887 wanted[rev] = 1
887 wanted[rev] = 1
888 if slowpath:
888 if slowpath:
889 # The slow path checks files modified in every changeset.
889 # The slow path checks files modified in every changeset.
890 def mfrevgen():
890 def mfrevgen():
891 for i in xrange(repo.changelog.count() - 1, -1, -window):
891 for i in xrange(repo.changelog.count() - 1, -1, -window):
892 for j in xrange(max(0, i - window), i + 1):
892 for j in xrange(max(0, i - window), i + 1):
893 yield j, repo.changelog.read(repo.lookup(str(j)))[3]
893 yield j, repo.changelog.read(repo.lookup(str(j)))[3]
894
894
895 for rev, mf in mfrevgen():
895 for rev, mf in mfrevgen():
896 if filter(matchfn, mf):
896 if filter(matchfn, mf):
897 wanted[rev] = 1
897 wanted[rev] = 1
898
898
899 def changerevgen():
899 def changerevgen():
900 class dui:
900 class dui:
901 # Implement and delegate some ui protocol. Save hunks of
901 # Implement and delegate some ui protocol. Save hunks of
902 # output for later display in the desired order.
902 # output for later display in the desired order.
903 def __init__(self, ui):
903 def __init__(self, ui):
904 self.ui = ui
904 self.ui = ui
905 self.hunk = {}
905 self.hunk = {}
906 def bump(self, rev):
906 def bump(self, rev):
907 self.rev = rev
907 self.rev = rev
908 self.hunk[rev] = []
908 self.hunk[rev] = []
909 def note(self, *args):
909 def note(self, *args):
910 if self.verbose: self.write(*args)
910 if self.verbose: self.write(*args)
911 def status(self, *args):
911 def status(self, *args):
912 if not self.quiet: self.write(*args)
912 if not self.quiet: self.write(*args)
913 def write(self, *args):
913 def write(self, *args):
914 self.hunk[self.rev].append(args)
914 self.hunk[self.rev].append(args)
915 def __getattr__(self, key):
915 def __getattr__(self, key):
916 return getattr(self.ui, key)
916 return getattr(self.ui, key)
917 for i in xrange(0, len(revs), window):
917 for i in xrange(0, len(revs), window):
918 nrevs = [rev for rev in revs[i : min(i + window, len(revs))]
918 nrevs = [rev for rev in revs[i : min(i + window, len(revs))]
919 if rev in wanted]
919 if rev in wanted]
920 srevs = list(nrevs)
920 srevs = list(nrevs)
921 srevs.sort()
921 srevs.sort()
922 du = dui(ui)
922 du = dui(ui)
923 for rev in srevs:
923 for rev in srevs:
924 du.bump(rev)
924 du.bump(rev)
925 yield rev, du
925 yield rev, du
926 for rev in nrevs:
926 for rev in nrevs:
927 for args in du.hunk[rev]:
927 for args in du.hunk[rev]:
928 ui.write(*args)
928 ui.write(*args)
929
929
930 for rev, dui in changerevgen():
930 for rev, dui in changerevgen():
931 show_changeset(dui, repo, rev)
931 show_changeset(dui, repo, rev)
932 if opts['patch']:
932 if opts['patch']:
933 changenode = repo.changelog.node(rev)
933 changenode = repo.changelog.node(rev)
934 prev, other = repo.changelog.parents(changenode)
934 prev, other = repo.changelog.parents(changenode)
935 dodiff(dui, dui, repo, prev, changenode, files)
935 dodiff(dui, dui, repo, prev, changenode, files)
936 dui.write("\n\n")
936 dui.write("\n\n")
937
937
938 def manifest(ui, repo, rev=None):
938 def manifest(ui, repo, rev=None):
939 """output the latest or given revision of the project manifest"""
939 """output the latest or given revision of the project manifest"""
940 if rev:
940 if rev:
941 try:
941 try:
942 # assume all revision numbers are for changesets
942 # assume all revision numbers are for changesets
943 n = repo.lookup(rev)
943 n = repo.lookup(rev)
944 change = repo.changelog.read(n)
944 change = repo.changelog.read(n)
945 n = change[0]
945 n = change[0]
946 except hg.RepoError:
946 except hg.RepoError:
947 n = repo.manifest.lookup(rev)
947 n = repo.manifest.lookup(rev)
948 else:
948 else:
949 n = repo.manifest.tip()
949 n = repo.manifest.tip()
950 m = repo.manifest.read(n)
950 m = repo.manifest.read(n)
951 mf = repo.manifest.readflags(n)
951 mf = repo.manifest.readflags(n)
952 files = m.keys()
952 files = m.keys()
953 files.sort()
953 files.sort()
954
954
955 for f in files:
955 for f in files:
956 ui.write("%40s %3s %s\n" % (hg.hex(m[f]), mf[f] and "755" or "644", f))
956 ui.write("%40s %3s %s\n" % (hg.hex(m[f]), mf[f] and "755" or "644", f))
957
957
958 def outgoing(ui, repo, dest="default-push"):
958 def outgoing(ui, repo, dest="default-push"):
959 """show changesets not found in destination"""
959 """show changesets not found in destination"""
960 dest = ui.expandpath(dest)
960 dest = ui.expandpath(dest)
961 other = hg.repository(ui, dest)
961 other = hg.repository(ui, dest)
962 o = repo.findoutgoing(other)
962 o = repo.findoutgoing(other)
963 o = repo.newer(o)
963 o = repo.newer(o)
964 o.reverse()
964 o.reverse()
965 for n in o:
965 for n in o:
966 show_changeset(ui, repo, changenode=n)
966 show_changeset(ui, repo, changenode=n)
967
967
968 def parents(ui, repo, rev=None):
968 def parents(ui, repo, rev=None):
969 """show the parents of the working dir or revision"""
969 """show the parents of the working dir or revision"""
970 if rev:
970 if rev:
971 p = repo.changelog.parents(repo.lookup(rev))
971 p = repo.changelog.parents(repo.lookup(rev))
972 else:
972 else:
973 p = repo.dirstate.parents()
973 p = repo.dirstate.parents()
974
974
975 for n in p:
975 for n in p:
976 if n != hg.nullid:
976 if n != hg.nullid:
977 show_changeset(ui, repo, changenode=n)
977 show_changeset(ui, repo, changenode=n)
978
978
979 def paths(ui, search = None):
979 def paths(ui, search = None):
980 """show definition of symbolic path names"""
980 """show definition of symbolic path names"""
981 try:
981 try:
982 repo = hg.repository(ui=ui)
982 repo = hg.repository(ui=ui)
983 except:
983 except:
984 pass
984 pass
985
985
986 if search:
986 if search:
987 for name, path in ui.configitems("paths"):
987 for name, path in ui.configitems("paths"):
988 if name == search:
988 if name == search:
989 ui.write("%s\n" % path)
989 ui.write("%s\n" % path)
990 return
990 return
991 ui.warn("not found!\n")
991 ui.warn("not found!\n")
992 return 1
992 return 1
993 else:
993 else:
994 for name, path in ui.configitems("paths"):
994 for name, path in ui.configitems("paths"):
995 ui.write("%s = %s\n" % (name, path))
995 ui.write("%s = %s\n" % (name, path))
996
996
997 def pull(ui, repo, source="default", **opts):
997 def pull(ui, repo, source="default", **opts):
998 """pull changes from the specified source"""
998 """pull changes from the specified source"""
999 source = ui.expandpath(source)
999 source = ui.expandpath(source)
1000 ui.status('pulling from %s\n' % (source))
1000 ui.status('pulling from %s\n' % (source))
1001
1001
1002 if opts['ssh']:
1002 if opts['ssh']:
1003 ui.setconfig("ui", "ssh", opts['ssh'])
1003 ui.setconfig("ui", "ssh", opts['ssh'])
1004 if opts['remotecmd']:
1004 if opts['remotecmd']:
1005 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
1005 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
1006
1006
1007 other = hg.repository(ui, source)
1007 other = hg.repository(ui, source)
1008 r = repo.pull(other)
1008 r = repo.pull(other)
1009 if not r:
1009 if not r:
1010 if opts['update']:
1010 if opts['update']:
1011 return update(ui, repo)
1011 return update(ui, repo)
1012 else:
1012 else:
1013 ui.status("(run 'hg update' to get a working copy)\n")
1013 ui.status("(run 'hg update' to get a working copy)\n")
1014
1014
1015 return r
1015 return r
1016
1016
1017 def push(ui, repo, dest="default-push", force=False, ssh=None, remotecmd=None):
1017 def push(ui, repo, dest="default-push", force=False, ssh=None, remotecmd=None):
1018 """push changes to the specified destination"""
1018 """push changes to the specified destination"""
1019 dest = ui.expandpath(dest)
1019 dest = ui.expandpath(dest)
1020 ui.status('pushing to %s\n' % (dest))
1020 ui.status('pushing to %s\n' % (dest))
1021
1021
1022 if ssh:
1022 if ssh:
1023 ui.setconfig("ui", "ssh", ssh)
1023 ui.setconfig("ui", "ssh", ssh)
1024 if remotecmd:
1024 if remotecmd:
1025 ui.setconfig("ui", "remotecmd", remotecmd)
1025 ui.setconfig("ui", "remotecmd", remotecmd)
1026
1026
1027 other = hg.repository(ui, dest)
1027 other = hg.repository(ui, dest)
1028 r = repo.push(other, force)
1028 r = repo.push(other, force)
1029 return r
1029 return r
1030
1030
1031 def rawcommit(ui, repo, *flist, **rc):
1031 def rawcommit(ui, repo, *flist, **rc):
1032 "raw commit interface"
1032 "raw commit interface"
1033 if rc['text']:
1033 if rc['text']:
1034 ui.warn("Warning: -t and --text is deprecated,"
1034 ui.warn("Warning: -t and --text is deprecated,"
1035 " please use -m or --message instead.\n")
1035 " please use -m or --message instead.\n")
1036 message = rc['message'] or rc['text']
1036 message = rc['message'] or rc['text']
1037 if not message and rc['logfile']:
1037 if not message and rc['logfile']:
1038 try:
1038 try:
1039 message = open(rc['logfile']).read()
1039 message = open(rc['logfile']).read()
1040 except IOError:
1040 except IOError:
1041 pass
1041 pass
1042 if not message and not rc['logfile']:
1042 if not message and not rc['logfile']:
1043 ui.warn("abort: missing commit message\n")
1043 ui.warn("abort: missing commit message\n")
1044 return 1
1044 return 1
1045
1045
1046 files = relpath(repo, list(flist))
1046 files = relpath(repo, list(flist))
1047 if rc['files']:
1047 if rc['files']:
1048 files += open(rc['files']).read().splitlines()
1048 files += open(rc['files']).read().splitlines()
1049
1049
1050 rc['parent'] = map(repo.lookup, rc['parent'])
1050 rc['parent'] = map(repo.lookup, rc['parent'])
1051
1051
1052 repo.rawcommit(files, message, rc['user'], rc['date'], *rc['parent'])
1052 repo.rawcommit(files, message, rc['user'], rc['date'], *rc['parent'])
1053
1053
1054 def recover(ui, repo):
1054 def recover(ui, repo):
1055 """roll back an interrupted transaction"""
1055 """roll back an interrupted transaction"""
1056 repo.recover()
1056 repo.recover()
1057
1057
1058 def remove(ui, repo, file1, *files):
1058 def remove(ui, repo, file1, *files):
1059 """remove the specified files on the next commit"""
1059 """remove the specified files on the next commit"""
1060 repo.remove(relpath(repo, (file1,) + files))
1060 repo.remove(relpath(repo, (file1,) + files))
1061
1061
1062 def revert(ui, repo, *names, **opts):
1062 def revert(ui, repo, *names, **opts):
1063 """revert modified files or dirs back to their unmodified states"""
1063 """revert modified files or dirs back to their unmodified states"""
1064 node = opts['rev'] and repo.lookup(opts['rev']) or \
1064 node = opts['rev'] and repo.lookup(opts['rev']) or \
1065 repo.dirstate.parents()[0]
1065 repo.dirstate.parents()[0]
1066 root = os.path.realpath(repo.root)
1066 root = os.path.realpath(repo.root)
1067
1067
1068 def trimpath(p):
1068 def trimpath(p):
1069 p = os.path.realpath(p)
1069 p = os.path.realpath(p)
1070 if p.startswith(root):
1070 if p.startswith(root):
1071 rest = p[len(root):]
1071 rest = p[len(root):]
1072 if not rest:
1072 if not rest:
1073 return rest
1073 return rest
1074 if p.startswith(os.sep):
1074 if p.startswith(os.sep):
1075 return rest[1:]
1075 return rest[1:]
1076 return p
1076 return p
1077
1077
1078 relnames = map(trimpath, names or [os.getcwd()])
1078 relnames = map(trimpath, names or [os.getcwd()])
1079 chosen = {}
1079 chosen = {}
1080
1080
1081 def choose(name):
1081 def choose(name):
1082 def body(name):
1082 def body(name):
1083 for r in relnames:
1083 for r in relnames:
1084 if not name.startswith(r):
1084 if not name.startswith(r):
1085 continue
1085 continue
1086 rest = name[len(r):]
1086 rest = name[len(r):]
1087 if not rest:
1087 if not rest:
1088 return r, True
1088 return r, True
1089 depth = rest.count(os.sep)
1089 depth = rest.count(os.sep)
1090 if not r:
1090 if not r:
1091 if depth == 0 or not opts['nonrecursive']:
1091 if depth == 0 or not opts['nonrecursive']:
1092 return r, True
1092 return r, True
1093 elif rest[0] == os.sep:
1093 elif rest[0] == os.sep:
1094 if depth == 1 or not opts['nonrecursive']:
1094 if depth == 1 or not opts['nonrecursive']:
1095 return r, True
1095 return r, True
1096 return None, False
1096 return None, False
1097 relname, ret = body(name)
1097 relname, ret = body(name)
1098 if ret:
1098 if ret:
1099 chosen[relname] = 1
1099 chosen[relname] = 1
1100 return ret
1100 return ret
1101
1101
1102 r = repo.update(node, False, True, choose, False)
1102 r = repo.update(node, False, True, choose, False)
1103 for n in relnames:
1103 for n in relnames:
1104 if n not in chosen:
1104 if n not in chosen:
1105 ui.warn('error: no matches for %s\n' % n)
1105 ui.warn('error: no matches for %s\n' % n)
1106 r = 1
1106 r = 1
1107 sys.stdout.flush()
1107 sys.stdout.flush()
1108 return r
1108 return r
1109
1109
1110 def root(ui, repo):
1110 def root(ui, repo):
1111 """print the root (top) of the current working dir"""
1111 """print the root (top) of the current working dir"""
1112 ui.write(repo.root + "\n")
1112 ui.write(repo.root + "\n")
1113
1113
1114 def serve(ui, repo, **opts):
1114 def serve(ui, repo, **opts):
1115 """export the repository via HTTP"""
1115 """export the repository via HTTP"""
1116
1116
1117 if opts["stdio"]:
1117 if opts["stdio"]:
1118 fin, fout = sys.stdin, sys.stdout
1118 fin, fout = sys.stdin, sys.stdout
1119 sys.stdout = sys.stderr
1119 sys.stdout = sys.stderr
1120
1120
1121 def getarg():
1121 def getarg():
1122 argline = fin.readline()[:-1]
1122 argline = fin.readline()[:-1]
1123 arg, l = argline.split()
1123 arg, l = argline.split()
1124 val = fin.read(int(l))
1124 val = fin.read(int(l))
1125 return arg, val
1125 return arg, val
1126 def respond(v):
1126 def respond(v):
1127 fout.write("%d\n" % len(v))
1127 fout.write("%d\n" % len(v))
1128 fout.write(v)
1128 fout.write(v)
1129 fout.flush()
1129 fout.flush()
1130
1130
1131 lock = None
1131 lock = None
1132
1132
1133 while 1:
1133 while 1:
1134 cmd = fin.readline()[:-1]
1134 cmd = fin.readline()[:-1]
1135 if cmd == '':
1135 if cmd == '':
1136 return
1136 return
1137 if cmd == "heads":
1137 if cmd == "heads":
1138 h = repo.heads()
1138 h = repo.heads()
1139 respond(" ".join(map(hg.hex, h)) + "\n")
1139 respond(" ".join(map(hg.hex, h)) + "\n")
1140 if cmd == "lock":
1140 if cmd == "lock":
1141 lock = repo.lock()
1141 lock = repo.lock()
1142 respond("")
1142 respond("")
1143 if cmd == "unlock":
1143 if cmd == "unlock":
1144 if lock:
1144 if lock:
1145 lock.release()
1145 lock.release()
1146 lock = None
1146 lock = None
1147 respond("")
1147 respond("")
1148 elif cmd == "branches":
1148 elif cmd == "branches":
1149 arg, nodes = getarg()
1149 arg, nodes = getarg()
1150 nodes = map(hg.bin, nodes.split(" "))
1150 nodes = map(hg.bin, nodes.split(" "))
1151 r = []
1151 r = []
1152 for b in repo.branches(nodes):
1152 for b in repo.branches(nodes):
1153 r.append(" ".join(map(hg.hex, b)) + "\n")
1153 r.append(" ".join(map(hg.hex, b)) + "\n")
1154 respond("".join(r))
1154 respond("".join(r))
1155 elif cmd == "between":
1155 elif cmd == "between":
1156 arg, pairs = getarg()
1156 arg, pairs = getarg()
1157 pairs = [map(hg.bin, p.split("-")) for p in pairs.split(" ")]
1157 pairs = [map(hg.bin, p.split("-")) for p in pairs.split(" ")]
1158 r = []
1158 r = []
1159 for b in repo.between(pairs):
1159 for b in repo.between(pairs):
1160 r.append(" ".join(map(hg.hex, b)) + "\n")
1160 r.append(" ".join(map(hg.hex, b)) + "\n")
1161 respond("".join(r))
1161 respond("".join(r))
1162 elif cmd == "changegroup":
1162 elif cmd == "changegroup":
1163 nodes = []
1163 nodes = []
1164 arg, roots = getarg()
1164 arg, roots = getarg()
1165 nodes = map(hg.bin, roots.split(" "))
1165 nodes = map(hg.bin, roots.split(" "))
1166
1166
1167 cg = repo.changegroup(nodes)
1167 cg = repo.changegroup(nodes)
1168 while 1:
1168 while 1:
1169 d = cg.read(4096)
1169 d = cg.read(4096)
1170 if not d:
1170 if not d:
1171 break
1171 break
1172 fout.write(d)
1172 fout.write(d)
1173
1173
1174 fout.flush()
1174 fout.flush()
1175
1175
1176 elif cmd == "addchangegroup":
1176 elif cmd == "addchangegroup":
1177 if not lock:
1177 if not lock:
1178 respond("not locked")
1178 respond("not locked")
1179 continue
1179 continue
1180 respond("")
1180 respond("")
1181
1181
1182 r = repo.addchangegroup(fin)
1182 r = repo.addchangegroup(fin)
1183 respond("")
1183 respond("")
1184
1184
1185 optlist = "name templates style address port ipv6 accesslog errorlog"
1185 optlist = "name templates style address port ipv6 accesslog errorlog"
1186 for o in optlist.split():
1186 for o in optlist.split():
1187 if opts[o]:
1187 if opts[o]:
1188 ui.setconfig("web", o, opts[o])
1188 ui.setconfig("web", o, opts[o])
1189
1189
1190 httpd = hgweb.create_server(repo)
1190 httpd = hgweb.create_server(repo)
1191
1191
1192 if ui.verbose:
1192 if ui.verbose:
1193 addr, port = httpd.socket.getsockname()
1193 addr, port = httpd.socket.getsockname()
1194 if addr == '0.0.0.0':
1194 if addr == '0.0.0.0':
1195 addr = socket.gethostname()
1195 addr = socket.gethostname()
1196 else:
1196 else:
1197 try:
1197 try:
1198 addr = socket.gethostbyaddr(addr)[0]
1198 addr = socket.gethostbyaddr(addr)[0]
1199 except socket.error:
1199 except socket.error:
1200 pass
1200 pass
1201 if port != 80:
1201 if port != 80:
1202 ui.status('listening at http://%s:%d/\n' % (addr, port))
1202 ui.status('listening at http://%s:%d/\n' % (addr, port))
1203 else:
1203 else:
1204 ui.status('listening at http://%s/\n' % addr)
1204 ui.status('listening at http://%s/\n' % addr)
1205 httpd.serve_forever()
1205 httpd.serve_forever()
1206
1206
1207 def status(ui, repo, *pats, **opts):
1207 def status(ui, repo, *pats, **opts):
1208 '''show changed files in the working directory
1208 '''show changed files in the working directory
1209
1209
1210 M = modified
1210 M = modified
1211 A = added
1211 A = added
1212 R = removed
1212 R = removed
1213 ? = not tracked
1213 ? = not tracked
1214 '''
1214 '''
1215
1215
1216 cwd = repo.getcwd()
1216 cwd = repo.getcwd()
1217 files, matchfn, anypats = matchpats(repo, cwd, pats, opts)
1217 files, matchfn, anypats = matchpats(repo, cwd, pats, opts)
1218 (c, a, d, u) = [[util.pathto(cwd, x) for x in n]
1218 (c, a, d, u) = [[util.pathto(cwd, x) for x in n]
1219 for n in repo.changes(files=files, match=matchfn)]
1219 for n in repo.changes(files=files, match=matchfn)]
1220
1220
1221 changetypes = [('modified', 'M', c),
1221 changetypes = [('modified', 'M', c),
1222 ('added', 'A', a),
1222 ('added', 'A', a),
1223 ('removed', 'R', d),
1223 ('removed', 'R', d),
1224 ('unknown', '?', u)]
1224 ('unknown', '?', u)]
1225
1225
1226 for opt, char, changes in ([ct for ct in changetypes if opts[ct[0]]]
1226 for opt, char, changes in ([ct for ct in changetypes if opts[ct[0]]]
1227 or changetypes):
1227 or changetypes):
1228 for f in changes:
1228 for f in changes:
1229 ui.write("%s %s\n" % (char, f))
1229 ui.write("%s %s\n" % (char, f))
1230
1230
1231 def tag(ui, repo, name, rev=None, **opts):
1231 def tag(ui, repo, name, rev=None, **opts):
1232 """add a tag for the current tip or a given revision"""
1232 """add a tag for the current tip or a given revision"""
1233 if opts['text']:
1233 if opts['text']:
1234 ui.warn("Warning: -t and --text is deprecated,"
1234 ui.warn("Warning: -t and --text is deprecated,"
1235 " please use -m or --message instead.\n")
1235 " please use -m or --message instead.\n")
1236 if name == "tip":
1236 if name == "tip":
1237 ui.warn("abort: 'tip' is a reserved name!\n")
1237 ui.warn("abort: 'tip' is a reserved name!\n")
1238 return -1
1238 return -1
1239 if rev:
1239 if rev:
1240 r = hg.hex(repo.lookup(rev))
1240 r = hg.hex(repo.lookup(rev))
1241 else:
1241 else:
1242 r = hg.hex(repo.changelog.tip())
1242 r = hg.hex(repo.changelog.tip())
1243
1243
1244 if name.find(revrangesep) >= 0:
1244 if name.find(revrangesep) >= 0:
1245 ui.warn("abort: '%s' cannot be used in a tag name\n" % revrangesep)
1245 ui.warn("abort: '%s' cannot be used in a tag name\n" % revrangesep)
1246 return -1
1246 return -1
1247
1247
1248 if opts['local']:
1248 if opts['local']:
1249 repo.opener("localtags", "a").write("%s %s\n" % (r, name))
1249 repo.opener("localtags", "a").write("%s %s\n" % (r, name))
1250 return
1250 return
1251
1251
1252 (c, a, d, u) = repo.changes()
1252 (c, a, d, u) = repo.changes()
1253 for x in (c, a, d, u):
1253 for x in (c, a, d, u):
1254 if ".hgtags" in x:
1254 if ".hgtags" in x:
1255 ui.warn("abort: working copy of .hgtags is changed!\n")
1255 ui.warn("abort: working copy of .hgtags is changed!\n")
1256 ui.status("(please commit .hgtags manually)\n")
1256 ui.status("(please commit .hgtags manually)\n")
1257 return -1
1257 return -1
1258
1258
1259 repo.wfile(".hgtags", "ab").write("%s %s\n" % (r, name))
1259 repo.wfile(".hgtags", "ab").write("%s %s\n" % (r, name))
1260 if repo.dirstate.state(".hgtags") == '?':
1260 if repo.dirstate.state(".hgtags") == '?':
1261 repo.add([".hgtags"])
1261 repo.add([".hgtags"])
1262
1262
1263 message = (opts['message'] or opts['text'] or
1263 message = (opts['message'] or opts['text'] or
1264 "Added tag %s for changeset %s" % (name, r))
1264 "Added tag %s for changeset %s" % (name, r))
1265 repo.commit([".hgtags"], message, opts['user'], opts['date'])
1265 repo.commit([".hgtags"], message, opts['user'], opts['date'])
1266
1266
1267 def tags(ui, repo):
1267 def tags(ui, repo):
1268 """list repository tags"""
1268 """list repository tags"""
1269
1269
1270 l = repo.tagslist()
1270 l = repo.tagslist()
1271 l.reverse()
1271 l.reverse()
1272 for t, n in l:
1272 for t, n in l:
1273 try:
1273 try:
1274 r = "%5d:%s" % (repo.changelog.rev(n), hg.hex(n))
1274 r = "%5d:%s" % (repo.changelog.rev(n), hg.hex(n))
1275 except KeyError:
1275 except KeyError:
1276 r = " ?:?"
1276 r = " ?:?"
1277 ui.write("%-30s %s\n" % (t, r))
1277 ui.write("%-30s %s\n" % (t, r))
1278
1278
1279 def tip(ui, repo):
1279 def tip(ui, repo):
1280 """show the tip revision"""
1280 """show the tip revision"""
1281 n = repo.changelog.tip()
1281 n = repo.changelog.tip()
1282 show_changeset(ui, repo, changenode=n)
1282 show_changeset(ui, repo, changenode=n)
1283
1283
1284 def undo(ui, repo):
1284 def undo(ui, repo):
1285 """undo the last commit or pull
1285 """undo the last commit or pull
1286
1286
1287 Roll back the last pull or commit transaction on the
1287 Roll back the last pull or commit transaction on the
1288 repository, restoring the project to its earlier state.
1288 repository, restoring the project to its earlier state.
1289
1289
1290 This command should be used with care. There is only one level of
1290 This command should be used with care. There is only one level of
1291 undo and there is no redo.
1291 undo and there is no redo.
1292
1292
1293 This command is not intended for use on public repositories. Once
1293 This command is not intended for use on public repositories. Once
1294 a change is visible for pull by other users, undoing it locally is
1294 a change is visible for pull by other users, undoing it locally is
1295 ineffective.
1295 ineffective.
1296 """
1296 """
1297 repo.undo()
1297 repo.undo()
1298
1298
1299 def update(ui, repo, node=None, merge=False, clean=False, branch=None):
1299 def update(ui, repo, node=None, merge=False, clean=False, branch=None):
1300 '''update or merge working directory
1300 '''update or merge working directory
1301
1301
1302 If there are no outstanding changes in the working directory and
1302 If there are no outstanding changes in the working directory and
1303 there is a linear relationship between the current version and the
1303 there is a linear relationship between the current version and the
1304 requested version, the result is the requested version.
1304 requested version, the result is the requested version.
1305
1305
1306 Otherwise the result is a merge between the contents of the
1306 Otherwise the result is a merge between the contents of the
1307 current working directory and the requested version. Files that
1307 current working directory and the requested version. Files that
1308 changed between either parent are marked as changed for the next
1308 changed between either parent are marked as changed for the next
1309 commit and a commit must be performed before any further updates
1309 commit and a commit must be performed before any further updates
1310 are allowed.
1310 are allowed.
1311 '''
1311 '''
1312 if branch:
1312 if branch:
1313 br = repo.branchlookup(branch=branch)
1313 br = repo.branchlookup(branch=branch)
1314 found = []
1314 found = []
1315 for x in br:
1315 for x in br:
1316 if branch in br[x]:
1316 if branch in br[x]:
1317 found.append(x)
1317 found.append(x)
1318 if len(found) > 1:
1318 if len(found) > 1:
1319 ui.warn("Found multiple heads for %s\n" % branch)
1319 ui.warn("Found multiple heads for %s\n" % branch)
1320 for x in found:
1320 for x in found:
1321 show_changeset(ui, repo, changenode=x, brinfo=br)
1321 show_changeset(ui, repo, changenode=x, brinfo=br)
1322 return 1
1322 return 1
1323 if len(found) == 1:
1323 if len(found) == 1:
1324 node = found[0]
1324 node = found[0]
1325 ui.warn("Using head %s for branch %s\n" % (hg.short(node), branch))
1325 ui.warn("Using head %s for branch %s\n" % (hg.short(node), branch))
1326 else:
1326 else:
1327 ui.warn("branch %s not found\n" % (branch))
1327 ui.warn("branch %s not found\n" % (branch))
1328 return 1
1328 return 1
1329 else:
1329 else:
1330 node = node and repo.lookup(node) or repo.changelog.tip()
1330 node = node and repo.lookup(node) or repo.changelog.tip()
1331 return repo.update(node, allow=merge, force=clean)
1331 return repo.update(node, allow=merge, force=clean)
1332
1332
1333 def verify(ui, repo):
1333 def verify(ui, repo):
1334 """verify the integrity of the repository"""
1334 """verify the integrity of the repository"""
1335 return repo.verify()
1335 return repo.verify()
1336
1336
1337 # Command options and aliases are listed here, alphabetically
1337 # Command options and aliases are listed here, alphabetically
1338
1338
1339 table = {
1339 table = {
1340 "^add":
1340 "^add":
1341 (add,
1341 (add,
1342 [('I', 'include', [], 'include path in search'),
1342 [('I', 'include', [], 'include path in search'),
1343 ('X', 'exclude', [], 'exclude path from search')],
1343 ('X', 'exclude', [], 'exclude path from search')],
1344 "hg add [OPTION]... [FILE]..."),
1344 "hg add [OPTION]... [FILE]..."),
1345 "addremove":
1345 "addremove":
1346 (addremove,
1346 (addremove,
1347 [('I', 'include', [], 'include path in search'),
1347 [('I', 'include', [], 'include path in search'),
1348 ('X', 'exclude', [], 'exclude path from search')],
1348 ('X', 'exclude', [], 'exclude path from search')],
1349 "hg addremove [OPTION]... [FILE]..."),
1349 "hg addremove [OPTION]... [FILE]..."),
1350 "^annotate":
1350 "^annotate":
1351 (annotate,
1351 (annotate,
1352 [('r', 'rev', '', 'revision'),
1352 [('r', 'rev', '', 'revision'),
1353 ('a', 'text', None, 'treat all files as text'),
1353 ('a', 'text', None, 'treat all files as text'),
1354 ('u', 'user', None, 'show user'),
1354 ('u', 'user', None, 'show user'),
1355 ('n', 'number', None, 'show revision number'),
1355 ('n', 'number', None, 'show revision number'),
1356 ('c', 'changeset', None, 'show changeset'),
1356 ('c', 'changeset', None, 'show changeset'),
1357 ('I', 'include', [], 'include path in search'),
1357 ('I', 'include', [], 'include path in search'),
1358 ('X', 'exclude', [], 'exclude path from search')],
1358 ('X', 'exclude', [], 'exclude path from search')],
1359 'hg annotate [OPTION]... FILE...'),
1359 'hg annotate [OPTION]... FILE...'),
1360 "cat":
1360 "cat":
1361 (cat,
1361 (cat,
1362 [('o', 'output', "", 'output to file')],
1362 [('o', 'output', "", 'output to file')],
1363 'hg cat [-o OUTFILE] FILE [REV]'),
1363 'hg cat [-o OUTFILE] FILE [REV]'),
1364 "^clone":
1364 "^clone":
1365 (clone,
1365 (clone,
1366 [('U', 'noupdate', None, 'skip update after cloning'),
1366 [('U', 'noupdate', None, 'skip update after cloning'),
1367 ('e', 'ssh', "", 'ssh command'),
1367 ('e', 'ssh', "", 'ssh command'),
1368 ('', 'remotecmd', "", 'remote hg command')],
1368 ('', 'remotecmd', "", 'remote hg command')],
1369 'hg clone [OPTIONS] SOURCE [DEST]'),
1369 'hg clone [OPTIONS] SOURCE [DEST]'),
1370 "^commit|ci":
1370 "^commit|ci":
1371 (commit,
1371 (commit,
1372 [('A', 'addremove', None, 'run add/remove during commit'),
1372 [('A', 'addremove', None, 'run add/remove during commit'),
1373 ('I', 'include', [], 'include path in search'),
1373 ('I', 'include', [], 'include path in search'),
1374 ('X', 'exclude', [], 'exclude path from search'),
1374 ('X', 'exclude', [], 'exclude path from search'),
1375 ('m', 'message', "", 'commit message'),
1375 ('m', 'message', "", 'commit message'),
1376 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1376 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1377 ('l', 'logfile', "", 'commit message file'),
1377 ('l', 'logfile', "", 'commit message file'),
1378 ('d', 'date', "", 'date code'),
1378 ('d', 'date', "", 'date code'),
1379 ('u', 'user', "", 'user')],
1379 ('u', 'user', "", 'user')],
1380 'hg commit [OPTION]... [FILE]...'),
1380 'hg commit [OPTION]... [FILE]...'),
1381 "copy": (copy, [], 'hg copy SOURCE DEST'),
1381 "copy": (copy, [], 'hg copy SOURCE DEST'),
1382 "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'),
1382 "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'),
1383 "debugconfig": (debugconfig, [], 'debugconfig'),
1383 "debugconfig": (debugconfig, [], 'debugconfig'),
1384 "debugstate": (debugstate, [], 'debugstate'),
1384 "debugstate": (debugstate, [], 'debugstate'),
1385 "debugdata": (debugdata, [], 'debugdata FILE REV'),
1385 "debugdata": (debugdata, [], 'debugdata FILE REV'),
1386 "debugindex": (debugindex, [], 'debugindex FILE'),
1386 "debugindex": (debugindex, [], 'debugindex FILE'),
1387 "debugindexdot": (debugindexdot, [], 'debugindexdot FILE'),
1387 "debugindexdot": (debugindexdot, [], 'debugindexdot FILE'),
1388 "debugwalk":
1388 "debugwalk":
1389 (debugwalk,
1389 (debugwalk,
1390 [('I', 'include', [], 'include path in search'),
1390 [('I', 'include', [], 'include path in search'),
1391 ('X', 'exclude', [], 'exclude path from search')],
1391 ('X', 'exclude', [], 'exclude path from search')],
1392 'debugwalk [OPTION]... [FILE]...'),
1392 'debugwalk [OPTION]... [FILE]...'),
1393 "^diff":
1393 "^diff":
1394 (diff,
1394 (diff,
1395 [('r', 'rev', [], 'revision'),
1395 [('r', 'rev', [], 'revision'),
1396 ('a', 'text', None, 'treat all files as text'),
1396 ('a', 'text', None, 'treat all files as text'),
1397 ('I', 'include', [], 'include path in search'),
1397 ('I', 'include', [], 'include path in search'),
1398 ('X', 'exclude', [], 'exclude path from search')],
1398 ('X', 'exclude', [], 'exclude path from search')],
1399 'hg diff [-I] [-X] [-r REV1 [-r REV2]] [FILE]...'),
1399 'hg diff [-I] [-X] [-r REV1 [-r REV2]] [FILE]...'),
1400 "^export":
1400 "^export":
1401 (export,
1401 (export,
1402 [('o', 'output', "", 'output to file'),
1402 [('o', 'output', "", 'output to file'),
1403 ('a', 'text', None, 'treat all files as text')],
1403 ('a', 'text', None, 'treat all files as text')],
1404 "hg export [-o OUTFILE] REV..."),
1404 "hg export [-o OUTFILE] REV..."),
1405 "forget":
1405 "forget":
1406 (forget,
1406 (forget,
1407 [('I', 'include', [], 'include path in search'),
1407 [('I', 'include', [], 'include path in search'),
1408 ('X', 'exclude', [], 'exclude path from search')],
1408 ('X', 'exclude', [], 'exclude path from search')],
1409 "hg forget [OPTION]... FILE..."),
1409 "hg forget [OPTION]... FILE..."),
1410 "heads":
1410 "heads":
1411 (heads,
1411 (heads,
1412 [('b', 'branches', None, 'find branch info')],
1412 [('b', 'branches', None, 'find branch info')],
1413 'hg [-b] heads'),
1413 'hg [-b] heads'),
1414 "help": (help_, [], 'hg help [COMMAND]'),
1414 "help": (help_, [], 'hg help [COMMAND]'),
1415 "identify|id": (identify, [], 'hg identify'),
1415 "identify|id": (identify, [], 'hg identify'),
1416 "import|patch":
1416 "import|patch":
1417 (import_,
1417 (import_,
1418 [('p', 'strip', 1, 'path strip'),
1418 [('p', 'strip', 1, 'path strip'),
1419 ('f', 'force', None, 'skip check for outstanding changes'),
1419 ('f', 'force', None, 'skip check for outstanding changes'),
1420 ('b', 'base', "", 'base path')],
1420 ('b', 'base', "", 'base path')],
1421 "hg import [-p NUM] [-b BASE] PATCH..."),
1421 "hg import [-p NUM] [-b BASE] PATCH..."),
1422 "incoming|in": (incoming, [], 'hg incoming [SOURCE]'),
1422 "incoming|in": (incoming, [], 'hg incoming [SOURCE]'),
1423 "^init": (init, [], 'hg init [DEST]'),
1423 "^init": (init, [], 'hg init [DEST]'),
1424 "locate":
1424 "locate":
1425 (locate,
1425 (locate,
1426 [('r', 'rev', '', 'revision'),
1426 [('r', 'rev', '', 'revision'),
1427 ('0', 'print0', None, 'end records with NUL'),
1427 ('0', 'print0', None, 'end records with NUL'),
1428 ('f', 'fullpath', None, 'print complete paths'),
1428 ('f', 'fullpath', None, 'print complete paths'),
1429 ('I', 'include', [], 'include path in search'),
1429 ('I', 'include', [], 'include path in search'),
1430 ('X', 'exclude', [], 'exclude path from search')],
1430 ('X', 'exclude', [], 'exclude path from search')],
1431 'hg locate [OPTION]... [PATTERN]...'),
1431 'hg locate [OPTION]... [PATTERN]...'),
1432 "^log|history":
1432 "^log|history":
1433 (log,
1433 (log,
1434 [('I', 'include', [], 'include path in search'),
1434 [('I', 'include', [], 'include path in search'),
1435 ('X', 'exclude', [], 'exclude path from search'),
1435 ('X', 'exclude', [], 'exclude path from search'),
1436 ('r', 'rev', [], 'revision'),
1436 ('r', 'rev', [], 'revision'),
1437 ('p', 'patch', None, 'show patch')],
1437 ('p', 'patch', None, 'show patch')],
1438 'hg log [-r REV1 [-r REV2]] [-p] [FILE]'),
1438 'hg log [-r REV1 [-r REV2]] [-p] [FILE]'),
1439 "manifest": (manifest, [], 'hg manifest [REV]'),
1439 "manifest": (manifest, [], 'hg manifest [REV]'),
1440 "outgoing|out": (outgoing, [], 'hg outgoing [DEST]'),
1440 "outgoing|out": (outgoing, [], 'hg outgoing [DEST]'),
1441 "parents": (parents, [], 'hg parents [REV]'),
1441 "parents": (parents, [], 'hg parents [REV]'),
1442 "paths": (paths, [], 'hg paths [NAME]'),
1442 "paths": (paths, [], 'hg paths [NAME]'),
1443 "^pull":
1443 "^pull":
1444 (pull,
1444 (pull,
1445 [('u', 'update', None, 'update working directory'),
1445 [('u', 'update', None, 'update working directory'),
1446 ('e', 'ssh', "", 'ssh command'),
1446 ('e', 'ssh', "", 'ssh command'),
1447 ('', 'remotecmd', "", 'remote hg command')],
1447 ('', 'remotecmd', "", 'remote hg command')],
1448 'hg pull [OPTIONS] [SOURCE]'),
1448 'hg pull [OPTIONS] [SOURCE]'),
1449 "^push":
1449 "^push":
1450 (push,
1450 (push,
1451 [('f', 'force', None, 'force push'),
1451 [('f', 'force', None, 'force push'),
1452 ('e', 'ssh', "", 'ssh command'),
1452 ('e', 'ssh', "", 'ssh command'),
1453 ('', 'remotecmd', "", 'remote hg command')],
1453 ('', 'remotecmd', "", 'remote hg command')],
1454 'hg push [-f] [DEST]'),
1454 'hg push [-f] [DEST]'),
1455 "rawcommit":
1455 "rawcommit":
1456 (rawcommit,
1456 (rawcommit,
1457 [('p', 'parent', [], 'parent'),
1457 [('p', 'parent', [], 'parent'),
1458 ('d', 'date', "", 'date code'),
1458 ('d', 'date', "", 'date code'),
1459 ('u', 'user', "", 'user'),
1459 ('u', 'user', "", 'user'),
1460 ('F', 'files', "", 'file list'),
1460 ('F', 'files', "", 'file list'),
1461 ('m', 'message', "", 'commit message'),
1461 ('m', 'message', "", 'commit message'),
1462 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1462 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1463 ('l', 'logfile', "", 'commit message file')],
1463 ('l', 'logfile', "", 'commit message file')],
1464 'hg rawcommit [OPTION]... [FILE]...'),
1464 'hg rawcommit [OPTION]... [FILE]...'),
1465 "recover": (recover, [], "hg recover"),
1465 "recover": (recover, [], "hg recover"),
1466 "^remove|rm": (remove, [], "hg remove FILE..."),
1466 "^remove|rm": (remove, [], "hg remove FILE..."),
1467 "^revert":
1467 "^revert":
1468 (revert,
1468 (revert,
1469 [("n", "nonrecursive", None, "don't recurse into subdirs"),
1469 [("n", "nonrecursive", None, "don't recurse into subdirs"),
1470 ("r", "rev", "", "revision")],
1470 ("r", "rev", "", "revision")],
1471 "hg revert [-n] [-r REV] [NAME]..."),
1471 "hg revert [-n] [-r REV] [NAME]..."),
1472 "root": (root, [], "hg root"),
1472 "root": (root, [], "hg root"),
1473 "^serve":
1473 "^serve":
1474 (serve,
1474 (serve,
1475 [('A', 'accesslog', '', 'access log file'),
1475 [('A', 'accesslog', '', 'access log file'),
1476 ('E', 'errorlog', '', 'error log file'),
1476 ('E', 'errorlog', '', 'error log file'),
1477 ('p', 'port', 0, 'listen port'),
1477 ('p', 'port', 0, 'listen port'),
1478 ('a', 'address', '', 'interface address'),
1478 ('a', 'address', '', 'interface address'),
1479 ('n', 'name', "", 'repository name'),
1479 ('n', 'name', "", 'repository name'),
1480 ('', 'stdio', None, 'for remote clients'),
1480 ('', 'stdio', None, 'for remote clients'),
1481 ('t', 'templates', "", 'template directory'),
1481 ('t', 'templates', "", 'template directory'),
1482 ('', 'style', "", 'template style'),
1482 ('', 'style', "", 'template style'),
1483 ('6', 'ipv6', None, 'use IPv6 in addition to IPv4')],
1483 ('6', 'ipv6', None, 'use IPv6 in addition to IPv4')],
1484 "hg serve [OPTION]..."),
1484 "hg serve [OPTION]..."),
1485 "^status":
1485 "^status":
1486 (status,
1486 (status,
1487 [('m', 'modified', None, 'show only modified files'),
1487 [('m', 'modified', None, 'show only modified files'),
1488 ('a', 'added', None, 'show only added files'),
1488 ('a', 'added', None, 'show only added files'),
1489 ('r', 'removed', None, 'show only removed files'),
1489 ('r', 'removed', None, 'show only removed files'),
1490 ('u', 'unknown', None, 'show only unknown (not tracked) files'),
1490 ('u', 'unknown', None, 'show only unknown (not tracked) files'),
1491 ('I', 'include', [], 'include path in search'),
1491 ('I', 'include', [], 'include path in search'),
1492 ('X', 'exclude', [], 'exclude path from search')],
1492 ('X', 'exclude', [], 'exclude path from search')],
1493 "hg status [OPTION]... [FILE]..."),
1493 "hg status [OPTION]... [FILE]..."),
1494 "tag":
1494 "tag":
1495 (tag,
1495 (tag,
1496 [('l', 'local', None, 'make the tag local'),
1496 [('l', 'local', None, 'make the tag local'),
1497 ('m', 'message', "", 'commit message'),
1497 ('m', 'message', "", 'commit message'),
1498 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1498 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1499 ('d', 'date', "", 'date code'),
1499 ('d', 'date', "", 'date code'),
1500 ('u', 'user', "", 'user')],
1500 ('u', 'user', "", 'user')],
1501 'hg tag [OPTION]... NAME [REV]'),
1501 'hg tag [OPTION]... NAME [REV]'),
1502 "tags": (tags, [], 'hg tags'),
1502 "tags": (tags, [], 'hg tags'),
1503 "tip": (tip, [], 'hg tip'),
1503 "tip": (tip, [], 'hg tip'),
1504 "undo": (undo, [], 'hg undo'),
1504 "undo": (undo, [], 'hg undo'),
1505 "^update|up|checkout|co":
1505 "^update|up|checkout|co":
1506 (update,
1506 (update,
1507 [('b', 'branch', "", 'checkout the head of a specific branch'),
1507 [('b', 'branch', "", 'checkout the head of a specific branch'),
1508 ('m', 'merge', None, 'allow merging of conflicts'),
1508 ('m', 'merge', None, 'allow merging of conflicts'),
1509 ('C', 'clean', None, 'overwrite locally modified files')],
1509 ('C', 'clean', None, 'overwrite locally modified files')],
1510 'hg update [-b TAG] [-m] [-C] [REV]'),
1510 'hg update [-b TAG] [-m] [-C] [REV]'),
1511 "verify": (verify, [], 'hg verify'),
1511 "verify": (verify, [], 'hg verify'),
1512 "version": (show_version, [], 'hg version'),
1512 "version": (show_version, [], 'hg version'),
1513 }
1513 }
1514
1514
1515 globalopts = [
1515 globalopts = [
1516 ('R', 'repository', "", 'repository root directory'),
1516 ('R', 'repository', "", 'repository root directory'),
1517 ('', 'cwd', '', 'change working directory'),
1517 ('', 'cwd', '', 'change working directory'),
1518 ('y', 'noninteractive', None, 'run non-interactively'),
1518 ('y', 'noninteractive', None, 'run non-interactively'),
1519 ('q', 'quiet', None, 'quiet mode'),
1519 ('q', 'quiet', None, 'quiet mode'),
1520 ('v', 'verbose', None, 'verbose mode'),
1520 ('v', 'verbose', None, 'verbose mode'),
1521 ('', 'debug', None, 'debug mode'),
1521 ('', 'debug', None, 'debug mode'),
1522 ('', 'traceback', None, 'print traceback on exception'),
1522 ('', 'traceback', None, 'print traceback on exception'),
1523 ('', 'time', None, 'time how long the command takes'),
1523 ('', 'time', None, 'time how long the command takes'),
1524 ('', 'profile', None, 'profile'),
1524 ('', 'profile', None, 'profile'),
1525 ('', 'version', None, 'output version information and exit'),
1525 ('', 'version', None, 'output version information and exit'),
1526 ('h', 'help', None, 'display help and exit'),
1526 ]
1527 ]
1527
1528
1528 norepo = "clone init version help debugconfig debugdata" + \
1529 norepo = "clone init version help debugconfig debugdata" + \
1529 " debugindex debugindexdot paths"
1530 " debugindex debugindexdot paths"
1530
1531
1531 def find(cmd):
1532 def find(cmd):
1532 for e in table.keys():
1533 for e in table.keys():
1533 if re.match("(%s)$" % e, cmd):
1534 if re.match("(%s)$" % e, cmd):
1534 return e, table[e]
1535 return e, table[e]
1535
1536
1536 raise UnknownCommand(cmd)
1537 raise UnknownCommand(cmd)
1537
1538
1538 class SignalInterrupt(Exception):
1539 class SignalInterrupt(Exception):
1539 """Exception raised on SIGTERM and SIGHUP."""
1540 """Exception raised on SIGTERM and SIGHUP."""
1540
1541
1541 def catchterm(*args):
1542 def catchterm(*args):
1542 raise SignalInterrupt
1543 raise SignalInterrupt
1543
1544
1544 def run():
1545 def run():
1545 sys.exit(dispatch(sys.argv[1:]))
1546 sys.exit(dispatch(sys.argv[1:]))
1546
1547
1547 class ParseError(Exception):
1548 class ParseError(Exception):
1548 """Exception raised on errors in parsing the command line."""
1549 """Exception raised on errors in parsing the command line."""
1549
1550
1550 def parse(args):
1551 def parse(args):
1551 options = {}
1552 options = {}
1552 cmdoptions = {}
1553 cmdoptions = {}
1553
1554
1554 try:
1555 try:
1555 args = fancyopts.fancyopts(args, globalopts, options)
1556 args = fancyopts.fancyopts(args, globalopts, options)
1556 except fancyopts.getopt.GetoptError, inst:
1557 except fancyopts.getopt.GetoptError, inst:
1557 raise ParseError(None, inst)
1558 raise ParseError(None, inst)
1558
1559
1559 if args:
1560 if args:
1560 cmd, args = args[0], args[1:]
1561 cmd, args = args[0], args[1:]
1561 i = find(cmd)[1]
1562 i = find(cmd)[1]
1562 c = list(i[1])
1563 c = list(i[1])
1563 else:
1564 else:
1564 cmd = None
1565 cmd = None
1565 c = []
1566 c = []
1566
1567
1567 # combine global options into local
1568 # combine global options into local
1568 for o in globalopts:
1569 for o in globalopts:
1569 c.append((o[0], o[1], options[o[1]], o[3]))
1570 c.append((o[0], o[1], options[o[1]], o[3]))
1570
1571
1571 try:
1572 try:
1572 args = fancyopts.fancyopts(args, c, cmdoptions)
1573 args = fancyopts.fancyopts(args, c, cmdoptions)
1573 except fancyopts.getopt.GetoptError, inst:
1574 except fancyopts.getopt.GetoptError, inst:
1574 raise ParseError(cmd, inst)
1575 raise ParseError(cmd, inst)
1575
1576
1576 # separate global options back out
1577 # separate global options back out
1577 for o in globalopts:
1578 for o in globalopts:
1578 n = o[1]
1579 n = o[1]
1579 options[n] = cmdoptions[n]
1580 options[n] = cmdoptions[n]
1580 del cmdoptions[n]
1581 del cmdoptions[n]
1581
1582
1582 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
1583 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
1583
1584
1584 def dispatch(args):
1585 def dispatch(args):
1585 signal.signal(signal.SIGTERM, catchterm)
1586 signal.signal(signal.SIGTERM, catchterm)
1586 try:
1587 try:
1587 signal.signal(signal.SIGHUP, catchterm)
1588 signal.signal(signal.SIGHUP, catchterm)
1588 except AttributeError:
1589 except AttributeError:
1589 pass
1590 pass
1590
1591
1591 try:
1592 try:
1592 cmd, func, args, options, cmdoptions = parse(args)
1593 cmd, func, args, options, cmdoptions = parse(args)
1593 except ParseError, inst:
1594 except ParseError, inst:
1594 u = ui.ui()
1595 u = ui.ui()
1595 if inst.args[0]:
1596 if inst.args[0]:
1596 u.warn("hg %s: %s\n" % (inst.args[0], inst.args[1]))
1597 u.warn("hg %s: %s\n" % (inst.args[0], inst.args[1]))
1597 help_(u, inst.args[0])
1598 help_(u, inst.args[0])
1598 else:
1599 else:
1599 u.warn("hg: %s\n" % inst.args[1])
1600 u.warn("hg: %s\n" % inst.args[1])
1600 help_(u, 'shortlist')
1601 help_(u, 'shortlist')
1601 sys.exit(-1)
1602 sys.exit(-1)
1602 except UnknownCommand, inst:
1603 except UnknownCommand, inst:
1603 u = ui.ui()
1604 u = ui.ui()
1604 u.warn("hg: unknown command '%s'\n" % inst.args[0])
1605 u.warn("hg: unknown command '%s'\n" % inst.args[0])
1605 help_(u, 'shortlist')
1606 help_(u, 'shortlist')
1606 sys.exit(1)
1607 sys.exit(1)
1607
1608
1608 if options['cwd']:
1609 if options['cwd']:
1609 try:
1610 try:
1610 os.chdir(options['cwd'])
1611 os.chdir(options['cwd'])
1611 except OSError, inst:
1612 except OSError, inst:
1612 u = ui.ui()
1613 u = ui.ui()
1613 u.warn('abort: %s: %s\n' % (options['cwd'], inst.strerror))
1614 u.warn('abort: %s: %s\n' % (options['cwd'], inst.strerror))
1614 sys.exit(1)
1615 sys.exit(1)
1615
1616
1616 if options["time"]:
1617 if options["time"]:
1617 def get_times():
1618 def get_times():
1618 t = os.times()
1619 t = os.times()
1619 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
1620 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
1620 t = (t[0], t[1], t[2], t[3], time.clock())
1621 t = (t[0], t[1], t[2], t[3], time.clock())
1621 return t
1622 return t
1622 s = get_times()
1623 s = get_times()
1623 def print_time():
1624 def print_time():
1624 t = get_times()
1625 t = get_times()
1625 u = ui.ui()
1626 u = ui.ui()
1626 u.warn("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n" %
1627 u.warn("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n" %
1627 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
1628 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
1628 atexit.register(print_time)
1629 atexit.register(print_time)
1629
1630
1630 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
1631 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
1631 not options["noninteractive"])
1632 not options["noninteractive"])
1632
1633
1633 try:
1634 try:
1634 try:
1635 try:
1635 if options['version']:
1636 if options['help']:
1637 help_(u, cmd)
1638 sys.exit(0)
1639 elif options['version']:
1636 show_version(u)
1640 show_version(u)
1637 sys.exit(0)
1641 sys.exit(0)
1638 elif not cmd:
1642 elif not cmd:
1639 help_(u, 'shortlist')
1643 help_(u, 'shortlist')
1640 sys.exit(0)
1644 sys.exit(0)
1641
1645
1642 if cmd not in norepo.split():
1646 if cmd not in norepo.split():
1643 path = options["repository"] or ""
1647 path = options["repository"] or ""
1644 repo = hg.repository(ui=u, path=path)
1648 repo = hg.repository(ui=u, path=path)
1645 d = lambda: func(u, repo, *args, **cmdoptions)
1649 d = lambda: func(u, repo, *args, **cmdoptions)
1646 else:
1650 else:
1647 d = lambda: func(u, *args, **cmdoptions)
1651 d = lambda: func(u, *args, **cmdoptions)
1648
1652
1649 if options['profile']:
1653 if options['profile']:
1650 import hotshot, hotshot.stats
1654 import hotshot, hotshot.stats
1651 prof = hotshot.Profile("hg.prof")
1655 prof = hotshot.Profile("hg.prof")
1652 r = prof.runcall(d)
1656 r = prof.runcall(d)
1653 prof.close()
1657 prof.close()
1654 stats = hotshot.stats.load("hg.prof")
1658 stats = hotshot.stats.load("hg.prof")
1655 stats.strip_dirs()
1659 stats.strip_dirs()
1656 stats.sort_stats('time', 'calls')
1660 stats.sort_stats('time', 'calls')
1657 stats.print_stats(40)
1661 stats.print_stats(40)
1658 return r
1662 return r
1659 else:
1663 else:
1660 return d()
1664 return d()
1661 except:
1665 except:
1662 if options['traceback']:
1666 if options['traceback']:
1663 traceback.print_exc()
1667 traceback.print_exc()
1664 raise
1668 raise
1665 except hg.RepoError, inst:
1669 except hg.RepoError, inst:
1666 u.warn("abort: ", inst, "!\n")
1670 u.warn("abort: ", inst, "!\n")
1667 except SignalInterrupt:
1671 except SignalInterrupt:
1668 u.warn("killed!\n")
1672 u.warn("killed!\n")
1669 except KeyboardInterrupt:
1673 except KeyboardInterrupt:
1670 try:
1674 try:
1671 u.warn("interrupted!\n")
1675 u.warn("interrupted!\n")
1672 except IOError, inst:
1676 except IOError, inst:
1673 if inst.errno == errno.EPIPE:
1677 if inst.errno == errno.EPIPE:
1674 if u.debugflag:
1678 if u.debugflag:
1675 u.warn("\nbroken pipe\n")
1679 u.warn("\nbroken pipe\n")
1676 else:
1680 else:
1677 raise
1681 raise
1678 except IOError, inst:
1682 except IOError, inst:
1679 if hasattr(inst, "code"):
1683 if hasattr(inst, "code"):
1680 u.warn("abort: %s\n" % inst)
1684 u.warn("abort: %s\n" % inst)
1681 elif hasattr(inst, "reason"):
1685 elif hasattr(inst, "reason"):
1682 u.warn("abort: error: %s\n" % inst.reason[1])
1686 u.warn("abort: error: %s\n" % inst.reason[1])
1683 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
1687 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
1684 if u.debugflag: u.warn("broken pipe\n")
1688 if u.debugflag: u.warn("broken pipe\n")
1685 else:
1689 else:
1686 raise
1690 raise
1687 except OSError, inst:
1691 except OSError, inst:
1688 if hasattr(inst, "filename"):
1692 if hasattr(inst, "filename"):
1689 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename))
1693 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename))
1690 else:
1694 else:
1691 u.warn("abort: %s\n" % inst.strerror)
1695 u.warn("abort: %s\n" % inst.strerror)
1692 except util.Abort, inst:
1696 except util.Abort, inst:
1693 u.warn('abort: ', inst.args[0] % inst.args[1:], '\n')
1697 u.warn('abort: ', inst.args[0] % inst.args[1:], '\n')
1694 sys.exit(1)
1698 sys.exit(1)
1695 except TypeError, inst:
1699 except TypeError, inst:
1696 # was this an argument error?
1700 # was this an argument error?
1697 tb = traceback.extract_tb(sys.exc_info()[2])
1701 tb = traceback.extract_tb(sys.exc_info()[2])
1698 if len(tb) > 2: # no
1702 if len(tb) > 2: # no
1699 raise
1703 raise
1700 u.debug(inst, "\n")
1704 u.debug(inst, "\n")
1701 u.warn("%s: invalid arguments\n" % cmd)
1705 u.warn("%s: invalid arguments\n" % cmd)
1702 help_(u, cmd)
1706 help_(u, cmd)
1703 except UnknownCommand, inst:
1707 except UnknownCommand, inst:
1704 u.warn("hg: unknown command '%s'\n" % inst.args[0])
1708 u.warn("hg: unknown command '%s'\n" % inst.args[0])
1705 help_(u, 'shortlist')
1709 help_(u, 'shortlist')
1706
1710
1707 sys.exit(-1)
1711 sys.exit(-1)
@@ -1,216 +1,215 b''
1 Mercurial Distributed SCM
1 Mercurial Distributed SCM
2
2
3 basic commands (use "hg help" for the full list or option "-v" for details):
3 basic commands (use "hg help" for the full list or option "-v" for details):
4
4
5 add add the specified files on the next commit
5 add add the specified files on the next commit
6 annotate show changeset information per file line
6 annotate show changeset information per file line
7 clone make a copy of an existing repository
7 clone make a copy of an existing repository
8 commit commit the specified files or all outstanding changes
8 commit commit the specified files or all outstanding changes
9 diff diff working directory (or selected files)
9 diff diff working directory (or selected files)
10 export dump the header and diffs for one or more changesets
10 export dump the header and diffs for one or more changesets
11 init create a new repository in the given directory
11 init create a new repository in the given directory
12 log show revision history of entire repository or files
12 log show revision history of entire repository or files
13 pull pull changes from the specified source
13 pull pull changes from the specified source
14 push push changes to the specified destination
14 push push changes to the specified destination
15 remove remove the specified files on the next commit
15 remove remove the specified files on the next commit
16 revert revert modified files or dirs back to their unmodified states
16 revert revert modified files or dirs back to their unmodified states
17 serve export the repository via HTTP
17 serve export the repository via HTTP
18 status show changed files in the working directory
18 status show changed files in the working directory
19 update update or merge working directory
19 update update or merge working directory
20 add add the specified files on the next commit
20 add add the specified files on the next commit
21 annotate show changeset information per file line
21 annotate show changeset information per file line
22 clone make a copy of an existing repository
22 clone make a copy of an existing repository
23 commit commit the specified files or all outstanding changes
23 commit commit the specified files or all outstanding changes
24 diff diff working directory (or selected files)
24 diff diff working directory (or selected files)
25 export dump the header and diffs for one or more changesets
25 export dump the header and diffs for one or more changesets
26 init create a new repository in the given directory
26 init create a new repository in the given directory
27 log show revision history of entire repository or files
27 log show revision history of entire repository or files
28 pull pull changes from the specified source
28 pull pull changes from the specified source
29 push push changes to the specified destination
29 push push changes to the specified destination
30 remove remove the specified files on the next commit
30 remove remove the specified files on the next commit
31 revert revert modified files or dirs back to their unmodified states
31 revert revert modified files or dirs back to their unmodified states
32 serve export the repository via HTTP
32 serve export the repository via HTTP
33 status show changed files in the working directory
33 status show changed files in the working directory
34 update update or merge working directory
34 update update or merge working directory
35 Mercurial Distributed SCM
35 Mercurial Distributed SCM
36
36
37 list of commands (use "hg help -v" to show aliases and global options):
37 list of commands (use "hg help -v" to show aliases and global options):
38
38
39 add add the specified files on the next commit
39 add add the specified files on the next commit
40 addremove add all new files, delete all missing files
40 addremove add all new files, delete all missing files
41 annotate show changeset information per file line
41 annotate show changeset information per file line
42 cat output the latest or given revision of a file
42 cat output the latest or given revision of a file
43 clone make a copy of an existing repository
43 clone make a copy of an existing repository
44 commit commit the specified files or all outstanding changes
44 commit commit the specified files or all outstanding changes
45 copy mark a file as copied or renamed for the next commit
45 copy mark a file as copied or renamed for the next commit
46 diff diff working directory (or selected files)
46 diff diff working directory (or selected files)
47 export dump the header and diffs for one or more changesets
47 export dump the header and diffs for one or more changesets
48 forget don't add the specified files on the next commit
48 forget don't add the specified files on the next commit
49 heads show current repository heads
49 heads show current repository heads
50 help show help for a given command or all commands
50 help show help for a given command or all commands
51 identify print information about the working copy
51 identify print information about the working copy
52 import import an ordered set of patches
52 import import an ordered set of patches
53 incoming show new changesets found in source
53 incoming show new changesets found in source
54 init create a new repository in the given directory
54 init create a new repository in the given directory
55 locate locate files matching specific patterns
55 locate locate files matching specific patterns
56 log show revision history of entire repository or files
56 log show revision history of entire repository or files
57 manifest output the latest or given revision of the project manifest
57 manifest output the latest or given revision of the project manifest
58 outgoing show changesets not found in destination
58 outgoing show changesets not found in destination
59 parents show the parents of the working dir or revision
59 parents show the parents of the working dir or revision
60 paths show definition of symbolic path names
60 paths show definition of symbolic path names
61 pull pull changes from the specified source
61 pull pull changes from the specified source
62 push push changes to the specified destination
62 push push changes to the specified destination
63 rawcommit raw commit interface
63 rawcommit raw commit interface
64 recover roll back an interrupted transaction
64 recover roll back an interrupted transaction
65 remove remove the specified files on the next commit
65 remove remove the specified files on the next commit
66 revert revert modified files or dirs back to their unmodified states
66 revert revert modified files or dirs back to their unmodified states
67 root print the root (top) of the current working dir
67 root print the root (top) of the current working dir
68 serve export the repository via HTTP
68 serve export the repository via HTTP
69 status show changed files in the working directory
69 status show changed files in the working directory
70 tag add a tag for the current tip or a given revision
70 tag add a tag for the current tip or a given revision
71 tags list repository tags
71 tags list repository tags
72 tip show the tip revision
72 tip show the tip revision
73 undo undo the last commit or pull
73 undo undo the last commit or pull
74 update update or merge working directory
74 update update or merge working directory
75 verify verify the integrity of the repository
75 verify verify the integrity of the repository
76 version output version and copyright information
76 version output version and copyright information
77 add add the specified files on the next commit
77 add add the specified files on the next commit
78 addremove add all new files, delete all missing files
78 addremove add all new files, delete all missing files
79 annotate show changeset information per file line
79 annotate show changeset information per file line
80 cat output the latest or given revision of a file
80 cat output the latest or given revision of a file
81 clone make a copy of an existing repository
81 clone make a copy of an existing repository
82 commit commit the specified files or all outstanding changes
82 commit commit the specified files or all outstanding changes
83 copy mark a file as copied or renamed for the next commit
83 copy mark a file as copied or renamed for the next commit
84 diff diff working directory (or selected files)
84 diff diff working directory (or selected files)
85 export dump the header and diffs for one or more changesets
85 export dump the header and diffs for one or more changesets
86 forget don't add the specified files on the next commit
86 forget don't add the specified files on the next commit
87 heads show current repository heads
87 heads show current repository heads
88 help show help for a given command or all commands
88 help show help for a given command or all commands
89 identify print information about the working copy
89 identify print information about the working copy
90 import import an ordered set of patches
90 import import an ordered set of patches
91 incoming show new changesets found in source
91 incoming show new changesets found in source
92 init create a new repository in the given directory
92 init create a new repository in the given directory
93 locate locate files matching specific patterns
93 locate locate files matching specific patterns
94 log show revision history of entire repository or files
94 log show revision history of entire repository or files
95 manifest output the latest or given revision of the project manifest
95 manifest output the latest or given revision of the project manifest
96 outgoing show changesets not found in destination
96 outgoing show changesets not found in destination
97 parents show the parents of the working dir or revision
97 parents show the parents of the working dir or revision
98 paths show definition of symbolic path names
98 paths show definition of symbolic path names
99 pull pull changes from the specified source
99 pull pull changes from the specified source
100 push push changes to the specified destination
100 push push changes to the specified destination
101 rawcommit raw commit interface
101 rawcommit raw commit interface
102 recover roll back an interrupted transaction
102 recover roll back an interrupted transaction
103 remove remove the specified files on the next commit
103 remove remove the specified files on the next commit
104 revert revert modified files or dirs back to their unmodified states
104 revert revert modified files or dirs back to their unmodified states
105 root print the root (top) of the current working dir
105 root print the root (top) of the current working dir
106 serve export the repository via HTTP
106 serve export the repository via HTTP
107 status show changed files in the working directory
107 status show changed files in the working directory
108 tag add a tag for the current tip or a given revision
108 tag add a tag for the current tip or a given revision
109 tags list repository tags
109 tags list repository tags
110 tip show the tip revision
110 tip show the tip revision
111 undo undo the last commit or pull
111 undo undo the last commit or pull
112 update update or merge working directory
112 update update or merge working directory
113 verify verify the integrity of the repository
113 verify verify the integrity of the repository
114 version output version and copyright information
114 version output version and copyright information
115 hg add: option -h not recognized
116 hg add [OPTION]... [FILE]...
115 hg add [OPTION]... [FILE]...
117
116
118 add the specified files on the next commit
117 add the specified files on the next commit
119
118
120 options:
119 options:
121
120
122 -I --include
121 -I --include
123 include path in search
122 include path in search
124 -X --exclude
123 -X --exclude
125 exclude path from search
124 exclude path from search
126 hg add: option --skjdfks not recognized
125 hg add: option --skjdfks not recognized
127 hg add [OPTION]... [FILE]...
126 hg add [OPTION]... [FILE]...
128
127
129 add the specified files on the next commit
128 add the specified files on the next commit
130
129
131 options:
130 options:
132
131
133 -I --include
132 -I --include
134 include path in search
133 include path in search
135 -X --exclude
134 -X --exclude
136 exclude path from search
135 exclude path from search
137 hg diff [-I] [-X] [-r REV1 [-r REV2]] [FILE]...
136 hg diff [-I] [-X] [-r REV1 [-r REV2]] [FILE]...
138
137
139 diff working directory (or selected files)
138 diff working directory (or selected files)
140
139
141 options:
140 options:
142
141
143 -r --rev
142 -r --rev
144 revision
143 revision
145 -a --text
144 -a --text
146 treat all files as text
145 treat all files as text
147 -I --include
146 -I --include
148 include path in search
147 include path in search
149 -X --exclude
148 -X --exclude
150 exclude path from search
149 exclude path from search
151 hg status [OPTION]... [FILE]...
150 hg status [OPTION]... [FILE]...
152
151
153 show changed files in the working directory
152 show changed files in the working directory
154
153
155 M = modified
154 M = modified
156 A = added
155 A = added
157 R = removed
156 R = removed
158 ? = not tracked
157 ? = not tracked
159
158
160 options:
159 options:
161
160
162 -m --modified
161 -m --modified
163 show only modified files
162 show only modified files
164 -a --added
163 -a --added
165 show only added files
164 show only added files
166 -r --removed
165 -r --removed
167 show only removed files
166 show only removed files
168 -u --unknown
167 -u --unknown
169 show only unknown (not tracked) files
168 show only unknown (not tracked) files
170 -I --include
169 -I --include
171 include path in search
170 include path in search
172 -X --exclude
171 -X --exclude
173 exclude path from search
172 exclude path from search
174 hg status [OPTION]... [FILE]...
173 hg status [OPTION]... [FILE]...
175
174
176 show changed files in the working directory
175 show changed files in the working directory
177 hg: unknown command 'foo'
176 hg: unknown command 'foo'
178 Mercurial Distributed SCM
177 Mercurial Distributed SCM
179
178
180 basic commands (use "hg help" for the full list or option "-v" for details):
179 basic commands (use "hg help" for the full list or option "-v" for details):
181
180
182 add add the specified files on the next commit
181 add add the specified files on the next commit
183 annotate show changeset information per file line
182 annotate show changeset information per file line
184 clone make a copy of an existing repository
183 clone make a copy of an existing repository
185 commit commit the specified files or all outstanding changes
184 commit commit the specified files or all outstanding changes
186 diff diff working directory (or selected files)
185 diff diff working directory (or selected files)
187 export dump the header and diffs for one or more changesets
186 export dump the header and diffs for one or more changesets
188 init create a new repository in the given directory
187 init create a new repository in the given directory
189 log show revision history of entire repository or files
188 log show revision history of entire repository or files
190 pull pull changes from the specified source
189 pull pull changes from the specified source
191 push push changes to the specified destination
190 push push changes to the specified destination
192 remove remove the specified files on the next commit
191 remove remove the specified files on the next commit
193 revert revert modified files or dirs back to their unmodified states
192 revert revert modified files or dirs back to their unmodified states
194 serve export the repository via HTTP
193 serve export the repository via HTTP
195 status show changed files in the working directory
194 status show changed files in the working directory
196 update update or merge working directory
195 update update or merge working directory
197 hg: unknown command 'skjdfks'
196 hg: unknown command 'skjdfks'
198 Mercurial Distributed SCM
197 Mercurial Distributed SCM
199
198
200 basic commands (use "hg help" for the full list or option "-v" for details):
199 basic commands (use "hg help" for the full list or option "-v" for details):
201
200
202 add add the specified files on the next commit
201 add add the specified files on the next commit
203 annotate show changeset information per file line
202 annotate show changeset information per file line
204 clone make a copy of an existing repository
203 clone make a copy of an existing repository
205 commit commit the specified files or all outstanding changes
204 commit commit the specified files or all outstanding changes
206 diff diff working directory (or selected files)
205 diff diff working directory (or selected files)
207 export dump the header and diffs for one or more changesets
206 export dump the header and diffs for one or more changesets
208 init create a new repository in the given directory
207 init create a new repository in the given directory
209 log show revision history of entire repository or files
208 log show revision history of entire repository or files
210 pull pull changes from the specified source
209 pull pull changes from the specified source
211 push push changes to the specified destination
210 push push changes to the specified destination
212 remove remove the specified files on the next commit
211 remove remove the specified files on the next commit
213 revert revert modified files or dirs back to their unmodified states
212 revert revert modified files or dirs back to their unmodified states
214 serve export the repository via HTTP
213 serve export the repository via HTTP
215 status show changed files in the working directory
214 status show changed files in the working directory
216 update update or merge working directory
215 update update or merge working directory
General Comments 0
You need to be logged in to leave comments. Login now