##// END OF EJS Templates
Fix help output, and a few broken tests.
Bryan O'Sullivan -
r1034:8dbbea5b default
parent child Browse files
Show More
@@ -1,1687 +1,1689 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 debugindex(ui, file_):
615 def debugindex(ui, file_):
616 """dump the contents of an index file"""
616 """dump the contents of an index file"""
617 r = hg.revlog(hg.opener(""), file_, "")
617 r = hg.revlog(hg.opener(""), file_, "")
618 ui.write(" rev offset length base linkrev" +
618 ui.write(" rev offset length base linkrev" +
619 " nodeid p1 p2\n")
619 " nodeid p1 p2\n")
620 for i in range(r.count()):
620 for i in range(r.count()):
621 e = r.index[i]
621 e = r.index[i]
622 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
622 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
623 i, e[0], e[1], e[2], e[3],
623 i, e[0], e[1], e[2], e[3],
624 hg.short(e[6]), hg.short(e[4]), hg.short(e[5])))
624 hg.short(e[6]), hg.short(e[4]), hg.short(e[5])))
625
625
626 def debugindexdot(ui, file_):
626 def debugindexdot(ui, file_):
627 """dump an index DAG as a .dot file"""
627 """dump an index DAG as a .dot file"""
628 r = hg.revlog(hg.opener(""), file_, "")
628 r = hg.revlog(hg.opener(""), file_, "")
629 ui.write("digraph G {\n")
629 ui.write("digraph G {\n")
630 for i in range(r.count()):
630 for i in range(r.count()):
631 e = r.index[i]
631 e = r.index[i]
632 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i))
632 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i))
633 if e[5] != hg.nullid:
633 if e[5] != hg.nullid:
634 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i))
634 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i))
635 ui.write("}\n")
635 ui.write("}\n")
636
636
637 def debugwalk(ui, repo, *pats, **opts):
637 def debugwalk(ui, repo, *pats, **opts):
638 items = list(walk(repo, pats, opts))
638 items = list(walk(repo, pats, opts))
639 if not items: return
639 if not items: return
640 fmt = '%%s %%-%ds %%-%ds %%s' % (
640 fmt = '%%s %%-%ds %%-%ds %%s' % (
641 max([len(abs) for (src, abs, rel, exact) in items]),
641 max([len(abs) for (src, abs, rel, exact) in items]),
642 max([len(rel) for (src, abs, rel, exact) in items]))
642 max([len(rel) for (src, abs, rel, exact) in items]))
643 exactly = {True: 'exact', False: ''}
643 exactly = {True: 'exact', False: ''}
644 for src, abs, rel, exact in items:
644 for src, abs, rel, exact in items:
645 print fmt % (src, abs, rel, exactly[exact])
645 print fmt % (src, abs, rel, exactly[exact])
646
646
647 def diff(ui, repo, *pats, **opts):
647 def diff(ui, repo, *pats, **opts):
648 """diff working directory (or selected files)"""
648 """diff working directory (or selected files)"""
649 node1, node2 = None, None
649 node1, node2 = None, None
650 revs = [repo.lookup(x) for x in opts['rev']]
650 revs = [repo.lookup(x) for x in opts['rev']]
651
651
652 if len(revs) > 0:
652 if len(revs) > 0:
653 node1 = revs[0]
653 node1 = revs[0]
654 if len(revs) > 1:
654 if len(revs) > 1:
655 node2 = revs[1]
655 node2 = revs[1]
656 if len(revs) > 2:
656 if len(revs) > 2:
657 raise util.Abort("too many revisions to diff")
657 raise util.Abort("too many revisions to diff")
658
658
659 files = []
659 files = []
660 match = util.always
660 match = util.always
661 if pats:
661 if pats:
662 roots, match, results = makewalk(repo, pats, opts)
662 roots, match, results = makewalk(repo, pats, opts)
663 for src, abs, rel, exact in results:
663 for src, abs, rel, exact in results:
664 files.append(abs)
664 files.append(abs)
665
665
666 dodiff(sys.stdout, ui, repo, node1, node2, files, match=match,
666 dodiff(sys.stdout, ui, repo, node1, node2, files, match=match,
667 text=opts['text'])
667 text=opts['text'])
668
668
669 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
669 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
670 node = repo.lookup(changeset)
670 node = repo.lookup(changeset)
671 prev, other = repo.changelog.parents(node)
671 prev, other = repo.changelog.parents(node)
672 change = repo.changelog.read(node)
672 change = repo.changelog.read(node)
673
673
674 fp = make_file(repo, repo.changelog, opts['output'],
674 fp = make_file(repo, repo.changelog, opts['output'],
675 node=node, total=total, seqno=seqno,
675 node=node, total=total, seqno=seqno,
676 revwidth=revwidth)
676 revwidth=revwidth)
677 if fp != sys.stdout:
677 if fp != sys.stdout:
678 ui.note("%s\n" % fp.name)
678 ui.note("%s\n" % fp.name)
679
679
680 fp.write("# HG changeset patch\n")
680 fp.write("# HG changeset patch\n")
681 fp.write("# User %s\n" % change[1])
681 fp.write("# User %s\n" % change[1])
682 fp.write("# Node ID %s\n" % hg.hex(node))
682 fp.write("# Node ID %s\n" % hg.hex(node))
683 fp.write("# Parent %s\n" % hg.hex(prev))
683 fp.write("# Parent %s\n" % hg.hex(prev))
684 if other != hg.nullid:
684 if other != hg.nullid:
685 fp.write("# Parent %s\n" % hg.hex(other))
685 fp.write("# Parent %s\n" % hg.hex(other))
686 fp.write(change[4].rstrip())
686 fp.write(change[4].rstrip())
687 fp.write("\n\n")
687 fp.write("\n\n")
688
688
689 dodiff(fp, ui, repo, prev, node, text=opts['text'])
689 dodiff(fp, ui, repo, prev, node, text=opts['text'])
690 if fp != sys.stdout: fp.close()
690 if fp != sys.stdout: fp.close()
691
691
692 def export(ui, repo, *changesets, **opts):
692 def export(ui, repo, *changesets, **opts):
693 """dump the header and diffs for one or more changesets"""
693 """dump the header and diffs for one or more changesets"""
694 if not changesets:
694 if not changesets:
695 raise util.Abort("export requires at least one changeset")
695 raise util.Abort("export requires at least one changeset")
696 seqno = 0
696 seqno = 0
697 revs = list(revrange(ui, repo, changesets))
697 revs = list(revrange(ui, repo, changesets))
698 total = len(revs)
698 total = len(revs)
699 revwidth = max(len(revs[0]), len(revs[-1]))
699 revwidth = max(len(revs[0]), len(revs[-1]))
700 ui.note(len(revs) > 1 and "Exporting patches:\n" or "Exporting patch:\n")
700 ui.note(len(revs) > 1 and "Exporting patches:\n" or "Exporting patch:\n")
701 for cset in revs:
701 for cset in revs:
702 seqno += 1
702 seqno += 1
703 doexport(ui, repo, cset, seqno, total, revwidth, opts)
703 doexport(ui, repo, cset, seqno, total, revwidth, opts)
704
704
705 def forget(ui, repo, *pats, **opts):
705 def forget(ui, repo, *pats, **opts):
706 """don't add the specified files on the next commit"""
706 """don't add the specified files on the next commit"""
707 forget = []
707 forget = []
708 for src, abs, rel, exact in walk(repo, pats, opts):
708 for src, abs, rel, exact in walk(repo, pats, opts):
709 if repo.dirstate.state(abs) == 'a':
709 if repo.dirstate.state(abs) == 'a':
710 forget.append(abs)
710 forget.append(abs)
711 if not exact: ui.status('forgetting ', rel, '\n')
711 if not exact: ui.status('forgetting ', rel, '\n')
712 repo.forget(forget)
712 repo.forget(forget)
713
713
714 def heads(ui, repo, **opts):
714 def heads(ui, repo, **opts):
715 """show current repository heads"""
715 """show current repository heads"""
716 heads = repo.changelog.heads()
716 heads = repo.changelog.heads()
717 br = None
717 br = None
718 if opts['branches']:
718 if opts['branches']:
719 br = repo.branchlookup(heads)
719 br = repo.branchlookup(heads)
720 for n in repo.changelog.heads():
720 for n in repo.changelog.heads():
721 show_changeset(ui, repo, changenode=n, brinfo=br)
721 show_changeset(ui, repo, changenode=n, brinfo=br)
722
722
723 def identify(ui, repo):
723 def identify(ui, repo):
724 """print information about the working copy"""
724 """print information about the working copy"""
725 parents = [p for p in repo.dirstate.parents() if p != hg.nullid]
725 parents = [p for p in repo.dirstate.parents() if p != hg.nullid]
726 if not parents:
726 if not parents:
727 ui.write("unknown\n")
727 ui.write("unknown\n")
728 return
728 return
729
729
730 hexfunc = ui.verbose and hg.hex or hg.short
730 hexfunc = ui.verbose and hg.hex or hg.short
731 (c, a, d, u) = repo.changes()
731 (c, a, d, u) = repo.changes()
732 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
732 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
733 (c or a or d) and "+" or "")]
733 (c or a or d) and "+" or "")]
734
734
735 if not ui.quiet:
735 if not ui.quiet:
736 # multiple tags for a single parent separated by '/'
736 # multiple tags for a single parent separated by '/'
737 parenttags = ['/'.join(tags)
737 parenttags = ['/'.join(tags)
738 for tags in map(repo.nodetags, parents) if tags]
738 for tags in map(repo.nodetags, parents) if tags]
739 # tags for multiple parents separated by ' + '
739 # tags for multiple parents separated by ' + '
740 if parenttags:
740 if parenttags:
741 output.append(' + '.join(parenttags))
741 output.append(' + '.join(parenttags))
742
742
743 ui.write("%s\n" % ' '.join(output))
743 ui.write("%s\n" % ' '.join(output))
744
744
745 def import_(ui, repo, patch1, *patches, **opts):
745 def import_(ui, repo, patch1, *patches, **opts):
746 """import an ordered set of patches"""
746 """import an ordered set of patches"""
747 patches = (patch1,) + patches
747 patches = (patch1,) + patches
748
748
749 if not opts['force']:
749 if not opts['force']:
750 (c, a, d, u) = repo.changes()
750 (c, a, d, u) = repo.changes()
751 if c or a or d:
751 if c or a or d:
752 ui.warn("abort: outstanding uncommitted changes!\n")
752 ui.warn("abort: outstanding uncommitted changes!\n")
753 return 1
753 return 1
754
754
755 d = opts["base"]
755 d = opts["base"]
756 strip = opts["strip"]
756 strip = opts["strip"]
757
757
758 for patch in patches:
758 for patch in patches:
759 ui.status("applying %s\n" % patch)
759 ui.status("applying %s\n" % patch)
760 pf = os.path.join(d, patch)
760 pf = os.path.join(d, patch)
761
761
762 message = []
762 message = []
763 user = None
763 user = None
764 hgpatch = False
764 hgpatch = False
765 for line in file(pf):
765 for line in file(pf):
766 line = line.rstrip()
766 line = line.rstrip()
767 if line.startswith("--- ") or line.startswith("diff -r"):
767 if line.startswith("--- ") or line.startswith("diff -r"):
768 break
768 break
769 elif hgpatch:
769 elif hgpatch:
770 # parse values when importing the result of an hg export
770 # parse values when importing the result of an hg export
771 if line.startswith("# User "):
771 if line.startswith("# User "):
772 user = line[7:]
772 user = line[7:]
773 ui.debug('User: %s\n' % user)
773 ui.debug('User: %s\n' % user)
774 elif not line.startswith("# ") and line:
774 elif not line.startswith("# ") and line:
775 message.append(line)
775 message.append(line)
776 hgpatch = False
776 hgpatch = False
777 elif line == '# HG changeset patch':
777 elif line == '# HG changeset patch':
778 hgpatch = True
778 hgpatch = True
779 message = [] # We may have collected garbage
779 message = [] # We may have collected garbage
780 else:
780 else:
781 message.append(line)
781 message.append(line)
782
782
783 # make sure message isn't empty
783 # make sure message isn't empty
784 if not message:
784 if not message:
785 message = "imported patch %s\n" % patch
785 message = "imported patch %s\n" % patch
786 else:
786 else:
787 message = "%s\n" % '\n'.join(message)
787 message = "%s\n" % '\n'.join(message)
788 ui.debug('message:\n%s\n' % message)
788 ui.debug('message:\n%s\n' % message)
789
789
790 f = os.popen("patch -p%d < '%s'" % (strip, pf))
790 f = os.popen("patch -p%d < '%s'" % (strip, pf))
791 files = []
791 files = []
792 for l in f.read().splitlines():
792 for l in f.read().splitlines():
793 l.rstrip('\r\n');
793 l.rstrip('\r\n');
794 ui.status("%s\n" % l)
794 ui.status("%s\n" % l)
795 if l.startswith('patching file '):
795 if l.startswith('patching file '):
796 pf = l[14:]
796 pf = l[14:]
797 if pf not in files:
797 if pf not in files:
798 files.append(pf)
798 files.append(pf)
799 patcherr = f.close()
799 patcherr = f.close()
800 if patcherr:
800 if patcherr:
801 raise util.Abort("patch failed")
801 raise util.Abort("patch failed")
802
802
803 if len(files) > 0:
803 if len(files) > 0:
804 addremove(ui, repo, *files)
804 addremove(ui, repo, *files)
805 repo.commit(files, message, user)
805 repo.commit(files, message, user)
806
806
807 def incoming(ui, repo, source="default"):
807 def incoming(ui, repo, source="default"):
808 """show new changesets found in source"""
808 """show new changesets found in source"""
809 source = ui.expandpath(source)
809 source = ui.expandpath(source)
810 other = hg.repository(ui, source)
810 other = hg.repository(ui, source)
811 if not other.local():
811 if not other.local():
812 ui.warn("abort: incoming doesn't work for remote"
812 ui.warn("abort: incoming doesn't work for remote"
813 + " repositories yet, sorry!\n")
813 + " repositories yet, sorry!\n")
814 return 1
814 return 1
815 o = repo.findincoming(other)
815 o = repo.findincoming(other)
816 if not o:
816 if not o:
817 return
817 return
818 o = other.newer(o)
818 o = other.newer(o)
819 o.reverse()
819 o.reverse()
820 for n in o:
820 for n in o:
821 show_changeset(ui, other, changenode=n)
821 show_changeset(ui, other, changenode=n)
822
822
823 def init(ui, dest="."):
823 def init(ui, dest="."):
824 """create a new repository in the given directory"""
824 """create a new repository in the given directory"""
825 if not os.path.exists(dest):
825 if not os.path.exists(dest):
826 os.mkdir(dest)
826 os.mkdir(dest)
827 hg.repository(ui, dest, create=1)
827 hg.repository(ui, dest, create=1)
828
828
829 def locate(ui, repo, *pats, **opts):
829 def locate(ui, repo, *pats, **opts):
830 """locate files matching specific patterns"""
830 """locate files matching specific patterns"""
831 end = '\n'
831 end = '\n'
832 if opts['print0']: end = '\0'
832 if opts['print0']: end = '\0'
833
833
834 for src, abs, rel, exact in walk(repo, pats, opts, '(?:.*/|)'):
834 for src, abs, rel, exact in walk(repo, pats, opts, '(?:.*/|)'):
835 if repo.dirstate.state(abs) == '?': continue
835 if repo.dirstate.state(abs) == '?': continue
836 if opts['fullpath']:
836 if opts['fullpath']:
837 ui.write(os.path.join(repo.root, abs), end)
837 ui.write(os.path.join(repo.root, abs), end)
838 else:
838 else:
839 ui.write(rel, end)
839 ui.write(rel, end)
840
840
841 def log(ui, repo, *pats, **opts):
841 def log(ui, repo, *pats, **opts):
842 """show revision history of entire repository or files"""
842 """show revision history of entire repository or files"""
843 # This code most commonly needs to iterate backwards over the
843 # This code most commonly needs to iterate backwards over the
844 # history it is interested in. This has awful (quadratic-looking)
844 # history it is interested in. This has awful (quadratic-looking)
845 # performance, so we use iterators that walk forwards through
845 # performance, so we use iterators that walk forwards through
846 # windows of revisions, yielding revisions in reverse order, while
846 # windows of revisions, yielding revisions in reverse order, while
847 # walking the windows backwards.
847 # walking the windows backwards.
848 files, matchfn, anypats = matchpats(repo, repo.getcwd(), pats, opts)
848 files, matchfn, anypats = matchpats(repo, repo.getcwd(), pats, opts)
849 revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
849 revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
850 wanted = {}
850 wanted = {}
851 slowpath = anypats
851 slowpath = anypats
852 window = 300
852 window = 300
853 if not slowpath and not files:
853 if not slowpath and not files:
854 # No files, no patterns. Display all revs.
854 # No files, no patterns. Display all revs.
855 wanted = dict(zip(revs, revs))
855 wanted = dict(zip(revs, revs))
856 if not slowpath:
856 if not slowpath:
857 # Only files, no patterns. Check the history of each file.
857 # Only files, no patterns. Check the history of each file.
858 def filerevgen(filelog):
858 def filerevgen(filelog):
859 for i in xrange(filelog.count() - 1, 0, -window):
859 for i in xrange(filelog.count() - 1, 0, -window):
860 revs = []
860 revs = []
861 for j in xrange(max(0, i - window), i):
861 for j in xrange(max(0, i - window), i):
862 revs.append(filelog.linkrev(filelog.node(j)))
862 revs.append(filelog.linkrev(filelog.node(j)))
863 revs.reverse()
863 revs.reverse()
864 for rev in revs:
864 for rev in revs:
865 yield rev
865 yield rev
866
866
867 minrev, maxrev = min(revs), max(revs)
867 minrev, maxrev = min(revs), max(revs)
868 for filelog in map(repo.file, files):
868 for filelog in map(repo.file, files):
869 # A zero count may be a directory or deleted file, so
869 # A zero count may be a directory or deleted file, so
870 # try to find matching entries on the slow path.
870 # try to find matching entries on the slow path.
871 if filelog.count() == 0:
871 if filelog.count() == 0:
872 slowpath = True
872 slowpath = True
873 break
873 break
874 for rev in filerevgen(filelog):
874 for rev in filerevgen(filelog):
875 if rev <= maxrev:
875 if rev <= maxrev:
876 if rev < minrev: break
876 if rev < minrev: break
877 wanted[rev] = 1
877 wanted[rev] = 1
878 if slowpath:
878 if slowpath:
879 # The slow path checks files modified in every changeset.
879 # The slow path checks files modified in every changeset.
880 def mfrevgen():
880 def mfrevgen():
881 for i in xrange(repo.changelog.count() - 1, 0, -window):
881 for i in xrange(repo.changelog.count() - 1, 0, -window):
882 for j in xrange(max(0, i - window), i):
882 for j in xrange(max(0, i - window), i):
883 yield j, repo.changelog.read(repo.lookup(str(j)))[3]
883 yield j, repo.changelog.read(repo.lookup(str(j)))[3]
884
884
885 for rev, mf in mfrevgen():
885 for rev, mf in mfrevgen():
886 if filter(matchfn, mf):
886 if filter(matchfn, mf):
887 wanted[rev] = 1
887 wanted[rev] = 1
888
888
889 def changerevgen():
889 def changerevgen():
890 class dui:
890 class dui:
891 # Implement and delegate some ui protocol. Save hunks of
891 # Implement and delegate some ui protocol. Save hunks of
892 # output for later display in the desired order.
892 # output for later display in the desired order.
893 def __init__(self, ui):
893 def __init__(self, ui):
894 self.ui = ui
894 self.ui = ui
895 self.hunk = {}
895 self.hunk = {}
896 def bump(self, rev):
896 def bump(self, rev):
897 self.rev = rev
897 self.rev = rev
898 self.hunk[rev] = []
898 self.hunk[rev] = []
899 def note(self, *args):
900 if self.verbose: self.write(*args)
899 def status(self, *args):
901 def status(self, *args):
900 if not self.quiet: self.write(*args)
902 if not self.quiet: self.write(*args)
901 def write(self, *args):
903 def write(self, *args):
902 self.hunk[self.rev].append(args)
904 self.hunk[self.rev].append(args)
903 def __getattr__(self, key):
905 def __getattr__(self, key):
904 return getattr(self.ui, key)
906 return getattr(self.ui, key)
905 for i in xrange(0, len(revs), window):
907 for i in xrange(0, len(revs), window):
906 nrevs = [rev for rev in revs[i : min(i + window, len(revs))]
908 nrevs = [rev for rev in revs[i : min(i + window, len(revs))]
907 if rev in wanted]
909 if rev in wanted]
908 srevs = list(nrevs)
910 srevs = list(nrevs)
909 srevs.sort()
911 srevs.sort()
910 du = dui(ui)
912 du = dui(ui)
911 for rev in srevs:
913 for rev in srevs:
912 du.bump(rev)
914 du.bump(rev)
913 yield rev, du
915 yield rev, du
914 for rev in nrevs:
916 for rev in nrevs:
915 for args in du.hunk[rev]:
917 for args in du.hunk[rev]:
916 ui.write(*args)
918 ui.write(*args)
917
919
918 for rev, dui in changerevgen():
920 for rev, dui in changerevgen():
919 show_changeset(dui, repo, rev)
921 show_changeset(dui, repo, rev)
920 if opts['patch']:
922 if opts['patch']:
921 changenode = repo.changelog.node(rev)
923 changenode = repo.changelog.node(rev)
922 prev, other = repo.changelog.parents(changenode)
924 prev, other = repo.changelog.parents(changenode)
923 dodiff(dui, dui, repo, prev, changenode, files)
925 dodiff(dui, dui, repo, prev, changenode, files)
924 du.write("\n\n")
926 du.write("\n\n")
925
927
926 def manifest(ui, repo, rev=None):
928 def manifest(ui, repo, rev=None):
927 """output the latest or given revision of the project manifest"""
929 """output the latest or given revision of the project manifest"""
928 if rev:
930 if rev:
929 try:
931 try:
930 # assume all revision numbers are for changesets
932 # assume all revision numbers are for changesets
931 n = repo.lookup(rev)
933 n = repo.lookup(rev)
932 change = repo.changelog.read(n)
934 change = repo.changelog.read(n)
933 n = change[0]
935 n = change[0]
934 except hg.RepoError:
936 except hg.RepoError:
935 n = repo.manifest.lookup(rev)
937 n = repo.manifest.lookup(rev)
936 else:
938 else:
937 n = repo.manifest.tip()
939 n = repo.manifest.tip()
938 m = repo.manifest.read(n)
940 m = repo.manifest.read(n)
939 mf = repo.manifest.readflags(n)
941 mf = repo.manifest.readflags(n)
940 files = m.keys()
942 files = m.keys()
941 files.sort()
943 files.sort()
942
944
943 for f in files:
945 for f in files:
944 ui.write("%40s %3s %s\n" % (hg.hex(m[f]), mf[f] and "755" or "644", f))
946 ui.write("%40s %3s %s\n" % (hg.hex(m[f]), mf[f] and "755" or "644", f))
945
947
946 def outgoing(ui, repo, dest="default-push"):
948 def outgoing(ui, repo, dest="default-push"):
947 """show changesets not found in destination"""
949 """show changesets not found in destination"""
948 dest = ui.expandpath(dest)
950 dest = ui.expandpath(dest)
949 other = hg.repository(ui, dest)
951 other = hg.repository(ui, dest)
950 o = repo.findoutgoing(other)
952 o = repo.findoutgoing(other)
951 o = repo.newer(o)
953 o = repo.newer(o)
952 o.reverse()
954 o.reverse()
953 for n in o:
955 for n in o:
954 show_changeset(ui, repo, changenode=n)
956 show_changeset(ui, repo, changenode=n)
955
957
956 def parents(ui, repo, rev=None):
958 def parents(ui, repo, rev=None):
957 """show the parents of the working dir or revision"""
959 """show the parents of the working dir or revision"""
958 if rev:
960 if rev:
959 p = repo.changelog.parents(repo.lookup(rev))
961 p = repo.changelog.parents(repo.lookup(rev))
960 else:
962 else:
961 p = repo.dirstate.parents()
963 p = repo.dirstate.parents()
962
964
963 for n in p:
965 for n in p:
964 if n != hg.nullid:
966 if n != hg.nullid:
965 show_changeset(ui, repo, changenode=n)
967 show_changeset(ui, repo, changenode=n)
966
968
967 def paths(ui, search = None):
969 def paths(ui, search = None):
968 """show definition of symbolic path names"""
970 """show definition of symbolic path names"""
969 try:
971 try:
970 repo = hg.repository(ui=ui)
972 repo = hg.repository(ui=ui)
971 except:
973 except:
972 pass
974 pass
973
975
974 if search:
976 if search:
975 for name, path in ui.configitems("paths"):
977 for name, path in ui.configitems("paths"):
976 if name == search:
978 if name == search:
977 ui.write("%s\n" % path)
979 ui.write("%s\n" % path)
978 return
980 return
979 ui.warn("not found!\n")
981 ui.warn("not found!\n")
980 return 1
982 return 1
981 else:
983 else:
982 for name, path in ui.configitems("paths"):
984 for name, path in ui.configitems("paths"):
983 ui.write("%s = %s\n" % (name, path))
985 ui.write("%s = %s\n" % (name, path))
984
986
985 def pull(ui, repo, source="default", **opts):
987 def pull(ui, repo, source="default", **opts):
986 """pull changes from the specified source"""
988 """pull changes from the specified source"""
987 source = ui.expandpath(source)
989 source = ui.expandpath(source)
988 ui.status('pulling from %s\n' % (source))
990 ui.status('pulling from %s\n' % (source))
989
991
990 if opts['ssh']:
992 if opts['ssh']:
991 ui.setconfig("ui", "ssh", opts['ssh'])
993 ui.setconfig("ui", "ssh", opts['ssh'])
992 if opts['remotecmd']:
994 if opts['remotecmd']:
993 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
995 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
994
996
995 other = hg.repository(ui, source)
997 other = hg.repository(ui, source)
996 r = repo.pull(other)
998 r = repo.pull(other)
997 if not r:
999 if not r:
998 if opts['update']:
1000 if opts['update']:
999 return update(ui, repo)
1001 return update(ui, repo)
1000 else:
1002 else:
1001 ui.status("(run 'hg update' to get a working copy)\n")
1003 ui.status("(run 'hg update' to get a working copy)\n")
1002
1004
1003 return r
1005 return r
1004
1006
1005 def push(ui, repo, dest="default-push", force=False, ssh=None, remotecmd=None):
1007 def push(ui, repo, dest="default-push", force=False, ssh=None, remotecmd=None):
1006 """push changes to the specified destination"""
1008 """push changes to the specified destination"""
1007 dest = ui.expandpath(dest)
1009 dest = ui.expandpath(dest)
1008 ui.status('pushing to %s\n' % (dest))
1010 ui.status('pushing to %s\n' % (dest))
1009
1011
1010 if ssh:
1012 if ssh:
1011 ui.setconfig("ui", "ssh", ssh)
1013 ui.setconfig("ui", "ssh", ssh)
1012 if remotecmd:
1014 if remotecmd:
1013 ui.setconfig("ui", "remotecmd", remotecmd)
1015 ui.setconfig("ui", "remotecmd", remotecmd)
1014
1016
1015 other = hg.repository(ui, dest)
1017 other = hg.repository(ui, dest)
1016 r = repo.push(other, force)
1018 r = repo.push(other, force)
1017 return r
1019 return r
1018
1020
1019 def rawcommit(ui, repo, *flist, **rc):
1021 def rawcommit(ui, repo, *flist, **rc):
1020 "raw commit interface"
1022 "raw commit interface"
1021 if rc['text']:
1023 if rc['text']:
1022 ui.warn("Warning: -t and --text is deprecated,"
1024 ui.warn("Warning: -t and --text is deprecated,"
1023 " please use -m or --message instead.\n")
1025 " please use -m or --message instead.\n")
1024 message = rc['message'] or rc['text']
1026 message = rc['message'] or rc['text']
1025 if not message and rc['logfile']:
1027 if not message and rc['logfile']:
1026 try:
1028 try:
1027 message = open(rc['logfile']).read()
1029 message = open(rc['logfile']).read()
1028 except IOError:
1030 except IOError:
1029 pass
1031 pass
1030 if not message and not rc['logfile']:
1032 if not message and not rc['logfile']:
1031 ui.warn("abort: missing commit message\n")
1033 ui.warn("abort: missing commit message\n")
1032 return 1
1034 return 1
1033
1035
1034 files = relpath(repo, list(flist))
1036 files = relpath(repo, list(flist))
1035 if rc['files']:
1037 if rc['files']:
1036 files += open(rc['files']).read().splitlines()
1038 files += open(rc['files']).read().splitlines()
1037
1039
1038 rc['parent'] = map(repo.lookup, rc['parent'])
1040 rc['parent'] = map(repo.lookup, rc['parent'])
1039
1041
1040 repo.rawcommit(files, message, rc['user'], rc['date'], *rc['parent'])
1042 repo.rawcommit(files, message, rc['user'], rc['date'], *rc['parent'])
1041
1043
1042 def recover(ui, repo):
1044 def recover(ui, repo):
1043 """roll back an interrupted transaction"""
1045 """roll back an interrupted transaction"""
1044 repo.recover()
1046 repo.recover()
1045
1047
1046 def remove(ui, repo, file1, *files):
1048 def remove(ui, repo, file1, *files):
1047 """remove the specified files on the next commit"""
1049 """remove the specified files on the next commit"""
1048 repo.remove(relpath(repo, (file1,) + files))
1050 repo.remove(relpath(repo, (file1,) + files))
1049
1051
1050 def revert(ui, repo, *names, **opts):
1052 def revert(ui, repo, *names, **opts):
1051 """revert modified files or dirs back to their unmodified states"""
1053 """revert modified files or dirs back to their unmodified states"""
1052 node = opts['rev'] and repo.lookup(opts['rev']) or \
1054 node = opts['rev'] and repo.lookup(opts['rev']) or \
1053 repo.dirstate.parents()[0]
1055 repo.dirstate.parents()[0]
1054 root = os.path.realpath(repo.root)
1056 root = os.path.realpath(repo.root)
1055
1057
1056 def trimpath(p):
1058 def trimpath(p):
1057 p = os.path.realpath(p)
1059 p = os.path.realpath(p)
1058 if p.startswith(root):
1060 if p.startswith(root):
1059 rest = p[len(root):]
1061 rest = p[len(root):]
1060 if not rest:
1062 if not rest:
1061 return rest
1063 return rest
1062 if p.startswith(os.sep):
1064 if p.startswith(os.sep):
1063 return rest[1:]
1065 return rest[1:]
1064 return p
1066 return p
1065
1067
1066 relnames = map(trimpath, names or [os.getcwd()])
1068 relnames = map(trimpath, names or [os.getcwd()])
1067 chosen = {}
1069 chosen = {}
1068
1070
1069 def choose(name):
1071 def choose(name):
1070 def body(name):
1072 def body(name):
1071 for r in relnames:
1073 for r in relnames:
1072 if not name.startswith(r):
1074 if not name.startswith(r):
1073 continue
1075 continue
1074 rest = name[len(r):]
1076 rest = name[len(r):]
1075 if not rest:
1077 if not rest:
1076 return r, True
1078 return r, True
1077 depth = rest.count(os.sep)
1079 depth = rest.count(os.sep)
1078 if not r:
1080 if not r:
1079 if depth == 0 or not opts['nonrecursive']:
1081 if depth == 0 or not opts['nonrecursive']:
1080 return r, True
1082 return r, True
1081 elif rest[0] == os.sep:
1083 elif rest[0] == os.sep:
1082 if depth == 1 or not opts['nonrecursive']:
1084 if depth == 1 or not opts['nonrecursive']:
1083 return r, True
1085 return r, True
1084 return None, False
1086 return None, False
1085 relname, ret = body(name)
1087 relname, ret = body(name)
1086 if ret:
1088 if ret:
1087 chosen[relname] = 1
1089 chosen[relname] = 1
1088 return ret
1090 return ret
1089
1091
1090 r = repo.update(node, False, True, choose, False)
1092 r = repo.update(node, False, True, choose, False)
1091 for n in relnames:
1093 for n in relnames:
1092 if n not in chosen:
1094 if n not in chosen:
1093 ui.warn('error: no matches for %s\n' % n)
1095 ui.warn('error: no matches for %s\n' % n)
1094 r = 1
1096 r = 1
1095 sys.stdout.flush()
1097 sys.stdout.flush()
1096 return r
1098 return r
1097
1099
1098 def root(ui, repo):
1100 def root(ui, repo):
1099 """print the root (top) of the current working dir"""
1101 """print the root (top) of the current working dir"""
1100 ui.write(repo.root + "\n")
1102 ui.write(repo.root + "\n")
1101
1103
1102 def serve(ui, repo, **opts):
1104 def serve(ui, repo, **opts):
1103 """export the repository via HTTP"""
1105 """export the repository via HTTP"""
1104
1106
1105 if opts["stdio"]:
1107 if opts["stdio"]:
1106 fin, fout = sys.stdin, sys.stdout
1108 fin, fout = sys.stdin, sys.stdout
1107 sys.stdout = sys.stderr
1109 sys.stdout = sys.stderr
1108
1110
1109 def getarg():
1111 def getarg():
1110 argline = fin.readline()[:-1]
1112 argline = fin.readline()[:-1]
1111 arg, l = argline.split()
1113 arg, l = argline.split()
1112 val = fin.read(int(l))
1114 val = fin.read(int(l))
1113 return arg, val
1115 return arg, val
1114 def respond(v):
1116 def respond(v):
1115 fout.write("%d\n" % len(v))
1117 fout.write("%d\n" % len(v))
1116 fout.write(v)
1118 fout.write(v)
1117 fout.flush()
1119 fout.flush()
1118
1120
1119 lock = None
1121 lock = None
1120
1122
1121 while 1:
1123 while 1:
1122 cmd = fin.readline()[:-1]
1124 cmd = fin.readline()[:-1]
1123 if cmd == '':
1125 if cmd == '':
1124 return
1126 return
1125 if cmd == "heads":
1127 if cmd == "heads":
1126 h = repo.heads()
1128 h = repo.heads()
1127 respond(" ".join(map(hg.hex, h)) + "\n")
1129 respond(" ".join(map(hg.hex, h)) + "\n")
1128 if cmd == "lock":
1130 if cmd == "lock":
1129 lock = repo.lock()
1131 lock = repo.lock()
1130 respond("")
1132 respond("")
1131 if cmd == "unlock":
1133 if cmd == "unlock":
1132 if lock:
1134 if lock:
1133 lock.release()
1135 lock.release()
1134 lock = None
1136 lock = None
1135 respond("")
1137 respond("")
1136 elif cmd == "branches":
1138 elif cmd == "branches":
1137 arg, nodes = getarg()
1139 arg, nodes = getarg()
1138 nodes = map(hg.bin, nodes.split(" "))
1140 nodes = map(hg.bin, nodes.split(" "))
1139 r = []
1141 r = []
1140 for b in repo.branches(nodes):
1142 for b in repo.branches(nodes):
1141 r.append(" ".join(map(hg.hex, b)) + "\n")
1143 r.append(" ".join(map(hg.hex, b)) + "\n")
1142 respond("".join(r))
1144 respond("".join(r))
1143 elif cmd == "between":
1145 elif cmd == "between":
1144 arg, pairs = getarg()
1146 arg, pairs = getarg()
1145 pairs = [map(hg.bin, p.split("-")) for p in pairs.split(" ")]
1147 pairs = [map(hg.bin, p.split("-")) for p in pairs.split(" ")]
1146 r = []
1148 r = []
1147 for b in repo.between(pairs):
1149 for b in repo.between(pairs):
1148 r.append(" ".join(map(hg.hex, b)) + "\n")
1150 r.append(" ".join(map(hg.hex, b)) + "\n")
1149 respond("".join(r))
1151 respond("".join(r))
1150 elif cmd == "changegroup":
1152 elif cmd == "changegroup":
1151 nodes = []
1153 nodes = []
1152 arg, roots = getarg()
1154 arg, roots = getarg()
1153 nodes = map(hg.bin, roots.split(" "))
1155 nodes = map(hg.bin, roots.split(" "))
1154
1156
1155 cg = repo.changegroup(nodes)
1157 cg = repo.changegroup(nodes)
1156 while 1:
1158 while 1:
1157 d = cg.read(4096)
1159 d = cg.read(4096)
1158 if not d:
1160 if not d:
1159 break
1161 break
1160 fout.write(d)
1162 fout.write(d)
1161
1163
1162 fout.flush()
1164 fout.flush()
1163
1165
1164 elif cmd == "addchangegroup":
1166 elif cmd == "addchangegroup":
1165 if not lock:
1167 if not lock:
1166 respond("not locked")
1168 respond("not locked")
1167 continue
1169 continue
1168 respond("")
1170 respond("")
1169
1171
1170 r = repo.addchangegroup(fin)
1172 r = repo.addchangegroup(fin)
1171 respond("")
1173 respond("")
1172
1174
1173 optlist = "name templates style address port ipv6 accesslog errorlog"
1175 optlist = "name templates style address port ipv6 accesslog errorlog"
1174 for o in optlist.split():
1176 for o in optlist.split():
1175 if opts[o]:
1177 if opts[o]:
1176 ui.setconfig("web", o, opts[o])
1178 ui.setconfig("web", o, opts[o])
1177
1179
1178 httpd = hgweb.create_server(repo)
1180 httpd = hgweb.create_server(repo)
1179
1181
1180 if ui.verbose:
1182 if ui.verbose:
1181 addr, port = httpd.socket.getsockname()
1183 addr, port = httpd.socket.getsockname()
1182 if addr == '0.0.0.0':
1184 if addr == '0.0.0.0':
1183 addr = socket.gethostname()
1185 addr = socket.gethostname()
1184 else:
1186 else:
1185 try:
1187 try:
1186 addr = socket.gethostbyaddr(addr)[0]
1188 addr = socket.gethostbyaddr(addr)[0]
1187 except socket.error:
1189 except socket.error:
1188 pass
1190 pass
1189 if port != 80:
1191 if port != 80:
1190 ui.status('listening at http://%s:%d/\n' % (addr, port))
1192 ui.status('listening at http://%s:%d/\n' % (addr, port))
1191 else:
1193 else:
1192 ui.status('listening at http://%s/\n' % addr)
1194 ui.status('listening at http://%s/\n' % addr)
1193 httpd.serve_forever()
1195 httpd.serve_forever()
1194
1196
1195 def status(ui, repo, *pats, **opts):
1197 def status(ui, repo, *pats, **opts):
1196 '''show changed files in the working directory
1198 '''show changed files in the working directory
1197
1199
1198 M = modified
1200 M = modified
1199 A = added
1201 A = added
1200 R = removed
1202 R = removed
1201 ? = not tracked
1203 ? = not tracked
1202 '''
1204 '''
1203
1205
1204 cwd = repo.getcwd()
1206 cwd = repo.getcwd()
1205 files, matchfn, anypats = matchpats(repo, cwd, pats, opts)
1207 files, matchfn, anypats = matchpats(repo, cwd, pats, opts)
1206 (c, a, d, u) = [[util.pathto(cwd, x) for x in n]
1208 (c, a, d, u) = [[util.pathto(cwd, x) for x in n]
1207 for n in repo.changes(files=files, match=matchfn)]
1209 for n in repo.changes(files=files, match=matchfn)]
1208
1210
1209 changetypes = [('modified', 'M', c),
1211 changetypes = [('modified', 'M', c),
1210 ('added', 'A', a),
1212 ('added', 'A', a),
1211 ('removed', 'R', d),
1213 ('removed', 'R', d),
1212 ('unknown', '?', u)]
1214 ('unknown', '?', u)]
1213
1215
1214 for opt, char, changes in ([ct for ct in changetypes if opts[ct[0]]]
1216 for opt, char, changes in ([ct for ct in changetypes if opts[ct[0]]]
1215 or changetypes):
1217 or changetypes):
1216 for f in changes:
1218 for f in changes:
1217 ui.write("%s %s\n" % (char, f))
1219 ui.write("%s %s\n" % (char, f))
1218
1220
1219 def tag(ui, repo, name, rev=None, **opts):
1221 def tag(ui, repo, name, rev=None, **opts):
1220 """add a tag for the current tip or a given revision"""
1222 """add a tag for the current tip or a given revision"""
1221 if opts['text']:
1223 if opts['text']:
1222 ui.warn("Warning: -t and --text is deprecated,"
1224 ui.warn("Warning: -t and --text is deprecated,"
1223 " please use -m or --message instead.\n")
1225 " please use -m or --message instead.\n")
1224 if name == "tip":
1226 if name == "tip":
1225 ui.warn("abort: 'tip' is a reserved name!\n")
1227 ui.warn("abort: 'tip' is a reserved name!\n")
1226 return -1
1228 return -1
1227 if rev:
1229 if rev:
1228 r = hg.hex(repo.lookup(rev))
1230 r = hg.hex(repo.lookup(rev))
1229 else:
1231 else:
1230 r = hg.hex(repo.changelog.tip())
1232 r = hg.hex(repo.changelog.tip())
1231
1233
1232 if name.find(revrangesep) >= 0:
1234 if name.find(revrangesep) >= 0:
1233 ui.warn("abort: '%s' cannot be used in a tag name\n" % revrangesep)
1235 ui.warn("abort: '%s' cannot be used in a tag name\n" % revrangesep)
1234 return -1
1236 return -1
1235
1237
1236 if opts['local']:
1238 if opts['local']:
1237 repo.opener("localtags", "a").write("%s %s\n" % (r, name))
1239 repo.opener("localtags", "a").write("%s %s\n" % (r, name))
1238 return
1240 return
1239
1241
1240 (c, a, d, u) = repo.changes()
1242 (c, a, d, u) = repo.changes()
1241 for x in (c, a, d, u):
1243 for x in (c, a, d, u):
1242 if ".hgtags" in x:
1244 if ".hgtags" in x:
1243 ui.warn("abort: working copy of .hgtags is changed!\n")
1245 ui.warn("abort: working copy of .hgtags is changed!\n")
1244 ui.status("(please commit .hgtags manually)\n")
1246 ui.status("(please commit .hgtags manually)\n")
1245 return -1
1247 return -1
1246
1248
1247 repo.wfile(".hgtags", "ab").write("%s %s\n" % (r, name))
1249 repo.wfile(".hgtags", "ab").write("%s %s\n" % (r, name))
1248 if repo.dirstate.state(".hgtags") == '?':
1250 if repo.dirstate.state(".hgtags") == '?':
1249 repo.add([".hgtags"])
1251 repo.add([".hgtags"])
1250
1252
1251 message = (opts['message'] or opts['text'] or
1253 message = (opts['message'] or opts['text'] or
1252 "Added tag %s for changeset %s" % (name, r))
1254 "Added tag %s for changeset %s" % (name, r))
1253 repo.commit([".hgtags"], message, opts['user'], opts['date'])
1255 repo.commit([".hgtags"], message, opts['user'], opts['date'])
1254
1256
1255 def tags(ui, repo):
1257 def tags(ui, repo):
1256 """list repository tags"""
1258 """list repository tags"""
1257
1259
1258 l = repo.tagslist()
1260 l = repo.tagslist()
1259 l.reverse()
1261 l.reverse()
1260 for t, n in l:
1262 for t, n in l:
1261 try:
1263 try:
1262 r = "%5d:%s" % (repo.changelog.rev(n), hg.hex(n))
1264 r = "%5d:%s" % (repo.changelog.rev(n), hg.hex(n))
1263 except KeyError:
1265 except KeyError:
1264 r = " ?:?"
1266 r = " ?:?"
1265 ui.write("%-30s %s\n" % (t, r))
1267 ui.write("%-30s %s\n" % (t, r))
1266
1268
1267 def tip(ui, repo):
1269 def tip(ui, repo):
1268 """show the tip revision"""
1270 """show the tip revision"""
1269 n = repo.changelog.tip()
1271 n = repo.changelog.tip()
1270 show_changeset(ui, repo, changenode=n)
1272 show_changeset(ui, repo, changenode=n)
1271
1273
1272 def undo(ui, repo):
1274 def undo(ui, repo):
1273 """undo the last commit or pull
1275 """undo the last commit or pull
1274
1276
1275 Roll back the last pull or commit transaction on the
1277 Roll back the last pull or commit transaction on the
1276 repository, restoring the project to its earlier state.
1278 repository, restoring the project to its earlier state.
1277
1279
1278 This command should be used with care. There is only one level of
1280 This command should be used with care. There is only one level of
1279 undo and there is no redo.
1281 undo and there is no redo.
1280
1282
1281 This command is not intended for use on public repositories. Once
1283 This command is not intended for use on public repositories. Once
1282 a change is visible for pull by other users, undoing it locally is
1284 a change is visible for pull by other users, undoing it locally is
1283 ineffective.
1285 ineffective.
1284 """
1286 """
1285 repo.undo()
1287 repo.undo()
1286
1288
1287 def update(ui, repo, node=None, merge=False, clean=False, branch=None):
1289 def update(ui, repo, node=None, merge=False, clean=False, branch=None):
1288 '''update or merge working directory
1290 '''update or merge working directory
1289
1291
1290 If there are no outstanding changes in the working directory and
1292 If there are no outstanding changes in the working directory and
1291 there is a linear relationship between the current version and the
1293 there is a linear relationship between the current version and the
1292 requested version, the result is the requested version.
1294 requested version, the result is the requested version.
1293
1295
1294 Otherwise the result is a merge between the contents of the
1296 Otherwise the result is a merge between the contents of the
1295 current working directory and the requested version. Files that
1297 current working directory and the requested version. Files that
1296 changed between either parent are marked as changed for the next
1298 changed between either parent are marked as changed for the next
1297 commit and a commit must be performed before any further updates
1299 commit and a commit must be performed before any further updates
1298 are allowed.
1300 are allowed.
1299 '''
1301 '''
1300 if branch:
1302 if branch:
1301 br = repo.branchlookup(branch=branch)
1303 br = repo.branchlookup(branch=branch)
1302 found = []
1304 found = []
1303 for x in br:
1305 for x in br:
1304 if branch in br[x]:
1306 if branch in br[x]:
1305 found.append(x)
1307 found.append(x)
1306 if len(found) > 1:
1308 if len(found) > 1:
1307 ui.warn("Found multiple heads for %s\n" % branch)
1309 ui.warn("Found multiple heads for %s\n" % branch)
1308 for x in found:
1310 for x in found:
1309 show_changeset(ui, repo, changenode=x, brinfo=br)
1311 show_changeset(ui, repo, changenode=x, brinfo=br)
1310 return 1
1312 return 1
1311 if len(found) == 1:
1313 if len(found) == 1:
1312 node = found[0]
1314 node = found[0]
1313 ui.warn("Using head %s for branch %s\n" % (hg.short(node), branch))
1315 ui.warn("Using head %s for branch %s\n" % (hg.short(node), branch))
1314 else:
1316 else:
1315 ui.warn("branch %s not found\n" % (branch))
1317 ui.warn("branch %s not found\n" % (branch))
1316 return 1
1318 return 1
1317 else:
1319 else:
1318 node = node and repo.lookup(node) or repo.changelog.tip()
1320 node = node and repo.lookup(node) or repo.changelog.tip()
1319 return repo.update(node, allow=merge, force=clean)
1321 return repo.update(node, allow=merge, force=clean)
1320
1322
1321 def verify(ui, repo):
1323 def verify(ui, repo):
1322 """verify the integrity of the repository"""
1324 """verify the integrity of the repository"""
1323 return repo.verify()
1325 return repo.verify()
1324
1326
1325 # Command options and aliases are listed here, alphabetically
1327 # Command options and aliases are listed here, alphabetically
1326
1328
1327 table = {
1329 table = {
1328 "^add":
1330 "^add":
1329 (add,
1331 (add,
1330 [('I', 'include', [], 'include path in search'),
1332 [('I', 'include', [], 'include path in search'),
1331 ('X', 'exclude', [], 'exclude path from search')],
1333 ('X', 'exclude', [], 'exclude path from search')],
1332 "hg add [OPTION]... [FILE]..."),
1334 "hg add [OPTION]... [FILE]..."),
1333 "addremove":
1335 "addremove":
1334 (addremove,
1336 (addremove,
1335 [('I', 'include', [], 'include path in search'),
1337 [('I', 'include', [], 'include path in search'),
1336 ('X', 'exclude', [], 'exclude path from search')],
1338 ('X', 'exclude', [], 'exclude path from search')],
1337 "hg addremove [OPTION]... [FILE]..."),
1339 "hg addremove [OPTION]... [FILE]..."),
1338 "^annotate":
1340 "^annotate":
1339 (annotate,
1341 (annotate,
1340 [('r', 'rev', '', 'revision'),
1342 [('r', 'rev', '', 'revision'),
1341 ('a', 'text', None, 'treat all files as text'),
1343 ('a', 'text', None, 'treat all files as text'),
1342 ('u', 'user', None, 'show user'),
1344 ('u', 'user', None, 'show user'),
1343 ('n', 'number', None, 'show revision number'),
1345 ('n', 'number', None, 'show revision number'),
1344 ('c', 'changeset', None, 'show changeset'),
1346 ('c', 'changeset', None, 'show changeset'),
1345 ('I', 'include', [], 'include path in search'),
1347 ('I', 'include', [], 'include path in search'),
1346 ('X', 'exclude', [], 'exclude path from search')],
1348 ('X', 'exclude', [], 'exclude path from search')],
1347 'hg annotate [OPTION]... FILE...'),
1349 'hg annotate [OPTION]... FILE...'),
1348 "cat":
1350 "cat":
1349 (cat,
1351 (cat,
1350 [('o', 'output', "", 'output to file')],
1352 [('o', 'output', "", 'output to file')],
1351 'hg cat [-o OUTFILE] FILE [REV]'),
1353 'hg cat [-o OUTFILE] FILE [REV]'),
1352 "^clone":
1354 "^clone":
1353 (clone,
1355 (clone,
1354 [('U', 'noupdate', None, 'skip update after cloning'),
1356 [('U', 'noupdate', None, 'skip update after cloning'),
1355 ('e', 'ssh', "", 'ssh command'),
1357 ('e', 'ssh', "", 'ssh command'),
1356 ('', 'remotecmd', "", 'remote hg command')],
1358 ('', 'remotecmd', "", 'remote hg command')],
1357 'hg clone [OPTIONS] SOURCE [DEST]'),
1359 'hg clone [OPTIONS] SOURCE [DEST]'),
1358 "^commit|ci":
1360 "^commit|ci":
1359 (commit,
1361 (commit,
1360 [('A', 'addremove', None, 'run add/remove during commit'),
1362 [('A', 'addremove', None, 'run add/remove during commit'),
1361 ('I', 'include', [], 'include path in search'),
1363 ('I', 'include', [], 'include path in search'),
1362 ('X', 'exclude', [], 'exclude path from search'),
1364 ('X', 'exclude', [], 'exclude path from search'),
1363 ('m', 'message', "", 'commit message'),
1365 ('m', 'message', "", 'commit message'),
1364 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1366 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1365 ('l', 'logfile', "", 'commit message file'),
1367 ('l', 'logfile', "", 'commit message file'),
1366 ('d', 'date', "", 'date code'),
1368 ('d', 'date', "", 'date code'),
1367 ('u', 'user', "", 'user')],
1369 ('u', 'user', "", 'user')],
1368 'hg commit [OPTION]... [FILE]...'),
1370 'hg commit [OPTION]... [FILE]...'),
1369 "copy": (copy, [], 'hg copy SOURCE DEST'),
1371 "copy": (copy, [], 'hg copy SOURCE DEST'),
1370 "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'),
1372 "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'),
1371 "debugconfig": (debugconfig, [], 'debugconfig'),
1373 "debugconfig": (debugconfig, [], 'debugconfig'),
1372 "debugstate": (debugstate, [], 'debugstate'),
1374 "debugstate": (debugstate, [], 'debugstate'),
1373 "debugindex": (debugindex, [], 'debugindex FILE'),
1375 "debugindex": (debugindex, [], 'debugindex FILE'),
1374 "debugindexdot": (debugindexdot, [], 'debugindexdot FILE'),
1376 "debugindexdot": (debugindexdot, [], 'debugindexdot FILE'),
1375 "debugwalk":
1377 "debugwalk":
1376 (debugwalk,
1378 (debugwalk,
1377 [('I', 'include', [], 'include path in search'),
1379 [('I', 'include', [], 'include path in search'),
1378 ('X', 'exclude', [], 'exclude path from search')],
1380 ('X', 'exclude', [], 'exclude path from search')],
1379 'debugwalk [OPTION]... [FILE]...'),
1381 'debugwalk [OPTION]... [FILE]...'),
1380 "^diff":
1382 "^diff":
1381 (diff,
1383 (diff,
1382 [('r', 'rev', [], 'revision'),
1384 [('r', 'rev', [], 'revision'),
1383 ('a', 'text', None, 'treat all files as text'),
1385 ('a', 'text', None, 'treat all files as text'),
1384 ('I', 'include', [], 'include path in search'),
1386 ('I', 'include', [], 'include path in search'),
1385 ('X', 'exclude', [], 'exclude path from search')],
1387 ('X', 'exclude', [], 'exclude path from search')],
1386 'hg diff [-I] [-X] [-r REV1 [-r REV2]] [FILE]...'),
1388 'hg diff [-I] [-X] [-r REV1 [-r REV2]] [FILE]...'),
1387 "^export":
1389 "^export":
1388 (export,
1390 (export,
1389 [('o', 'output', "", 'output to file'),
1391 [('o', 'output', "", 'output to file'),
1390 ('a', 'text', None, 'treat all files as text')],
1392 ('a', 'text', None, 'treat all files as text')],
1391 "hg export [-o OUTFILE] REV..."),
1393 "hg export [-o OUTFILE] REV..."),
1392 "forget":
1394 "forget":
1393 (forget,
1395 (forget,
1394 [('I', 'include', [], 'include path in search'),
1396 [('I', 'include', [], 'include path in search'),
1395 ('X', 'exclude', [], 'exclude path from search')],
1397 ('X', 'exclude', [], 'exclude path from search')],
1396 "hg forget [OPTION]... FILE..."),
1398 "hg forget [OPTION]... FILE..."),
1397 "heads":
1399 "heads":
1398 (heads,
1400 (heads,
1399 [('b', 'branches', None, 'find branch info')],
1401 [('b', 'branches', None, 'find branch info')],
1400 'hg [-b] heads'),
1402 'hg [-b] heads'),
1401 "help": (help_, [], 'hg help [COMMAND]'),
1403 "help": (help_, [], 'hg help [COMMAND]'),
1402 "identify|id": (identify, [], 'hg identify'),
1404 "identify|id": (identify, [], 'hg identify'),
1403 "import|patch":
1405 "import|patch":
1404 (import_,
1406 (import_,
1405 [('p', 'strip', 1, 'path strip'),
1407 [('p', 'strip', 1, 'path strip'),
1406 ('f', 'force', None, 'skip check for outstanding changes'),
1408 ('f', 'force', None, 'skip check for outstanding changes'),
1407 ('b', 'base', "", 'base path')],
1409 ('b', 'base', "", 'base path')],
1408 "hg import [-p NUM] [-b BASE] PATCH..."),
1410 "hg import [-p NUM] [-b BASE] PATCH..."),
1409 "incoming|in": (incoming, [], 'hg incoming [SOURCE]'),
1411 "incoming|in": (incoming, [], 'hg incoming [SOURCE]'),
1410 "^init": (init, [], 'hg init [DEST]'),
1412 "^init": (init, [], 'hg init [DEST]'),
1411 "locate":
1413 "locate":
1412 (locate,
1414 (locate,
1413 [('r', 'rev', '', 'revision'),
1415 [('r', 'rev', '', 'revision'),
1414 ('0', 'print0', None, 'end records with NUL'),
1416 ('0', 'print0', None, 'end records with NUL'),
1415 ('f', 'fullpath', None, 'print complete paths'),
1417 ('f', 'fullpath', None, 'print complete paths'),
1416 ('I', 'include', [], 'include path in search'),
1418 ('I', 'include', [], 'include path in search'),
1417 ('X', 'exclude', [], 'exclude path from search')],
1419 ('X', 'exclude', [], 'exclude path from search')],
1418 'hg locate [OPTION]... [PATTERN]...'),
1420 'hg locate [OPTION]... [PATTERN]...'),
1419 "^log|history":
1421 "^log|history":
1420 (log,
1422 (log,
1421 [('I', 'include', [], 'include path in search'),
1423 [('I', 'include', [], 'include path in search'),
1422 ('X', 'exclude', [], 'exclude path from search'),
1424 ('X', 'exclude', [], 'exclude path from search'),
1423 ('r', 'rev', [], 'revision'),
1425 ('r', 'rev', [], 'revision'),
1424 ('p', 'patch', None, 'show patch')],
1426 ('p', 'patch', None, 'show patch')],
1425 'hg log [-r REV1 [-r REV2]] [-p] [FILE]'),
1427 'hg log [-r REV1 [-r REV2]] [-p] [FILE]'),
1426 "manifest": (manifest, [], 'hg manifest [REV]'),
1428 "manifest": (manifest, [], 'hg manifest [REV]'),
1427 "outgoing|out": (outgoing, [], 'hg outgoing [DEST]'),
1429 "outgoing|out": (outgoing, [], 'hg outgoing [DEST]'),
1428 "parents": (parents, [], 'hg parents [REV]'),
1430 "parents": (parents, [], 'hg parents [REV]'),
1429 "paths": (paths, [], 'hg paths [NAME]'),
1431 "paths": (paths, [], 'hg paths [NAME]'),
1430 "^pull":
1432 "^pull":
1431 (pull,
1433 (pull,
1432 [('u', 'update', None, 'update working directory'),
1434 [('u', 'update', None, 'update working directory'),
1433 ('e', 'ssh', "", 'ssh command'),
1435 ('e', 'ssh', "", 'ssh command'),
1434 ('', 'remotecmd', "", 'remote hg command')],
1436 ('', 'remotecmd', "", 'remote hg command')],
1435 'hg pull [OPTIONS] [SOURCE]'),
1437 'hg pull [OPTIONS] [SOURCE]'),
1436 "^push":
1438 "^push":
1437 (push,
1439 (push,
1438 [('f', 'force', None, 'force push'),
1440 [('f', 'force', None, 'force push'),
1439 ('e', 'ssh', "", 'ssh command'),
1441 ('e', 'ssh', "", 'ssh command'),
1440 ('', 'remotecmd', "", 'remote hg command')],
1442 ('', 'remotecmd', "", 'remote hg command')],
1441 'hg push [-f] [DEST]'),
1443 'hg push [-f] [DEST]'),
1442 "rawcommit":
1444 "rawcommit":
1443 (rawcommit,
1445 (rawcommit,
1444 [('p', 'parent', [], 'parent'),
1446 [('p', 'parent', [], 'parent'),
1445 ('d', 'date', "", 'date code'),
1447 ('d', 'date', "", 'date code'),
1446 ('u', 'user', "", 'user'),
1448 ('u', 'user', "", 'user'),
1447 ('F', 'files', "", 'file list'),
1449 ('F', 'files', "", 'file list'),
1448 ('m', 'message', "", 'commit message'),
1450 ('m', 'message', "", 'commit message'),
1449 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1451 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1450 ('l', 'logfile', "", 'commit message file')],
1452 ('l', 'logfile', "", 'commit message file')],
1451 'hg rawcommit [OPTION]... [FILE]...'),
1453 'hg rawcommit [OPTION]... [FILE]...'),
1452 "recover": (recover, [], "hg recover"),
1454 "recover": (recover, [], "hg recover"),
1453 "^remove|rm": (remove, [], "hg remove FILE..."),
1455 "^remove|rm": (remove, [], "hg remove FILE..."),
1454 "^revert":
1456 "^revert":
1455 (revert,
1457 (revert,
1456 [("n", "nonrecursive", None, "don't recurse into subdirs"),
1458 [("n", "nonrecursive", None, "don't recurse into subdirs"),
1457 ("r", "rev", "", "revision")],
1459 ("r", "rev", "", "revision")],
1458 "hg revert [-n] [-r REV] [NAME]..."),
1460 "hg revert [-n] [-r REV] [NAME]..."),
1459 "root": (root, [], "hg root"),
1461 "root": (root, [], "hg root"),
1460 "^serve":
1462 "^serve":
1461 (serve,
1463 (serve,
1462 [('A', 'accesslog', '', 'access log file'),
1464 [('A', 'accesslog', '', 'access log file'),
1463 ('E', 'errorlog', '', 'error log file'),
1465 ('E', 'errorlog', '', 'error log file'),
1464 ('p', 'port', 0, 'listen port'),
1466 ('p', 'port', 0, 'listen port'),
1465 ('a', 'address', '', 'interface address'),
1467 ('a', 'address', '', 'interface address'),
1466 ('n', 'name', "", 'repository name'),
1468 ('n', 'name', "", 'repository name'),
1467 ('', 'stdio', None, 'for remote clients'),
1469 ('', 'stdio', None, 'for remote clients'),
1468 ('t', 'templates', "", 'template directory'),
1470 ('t', 'templates', "", 'template directory'),
1469 ('', 'style', "", 'template style'),
1471 ('', 'style', "", 'template style'),
1470 ('6', 'ipv6', None, 'use IPv6 in addition to IPv4')],
1472 ('6', 'ipv6', None, 'use IPv6 in addition to IPv4')],
1471 "hg serve [OPTION]..."),
1473 "hg serve [OPTION]..."),
1472 "^status":
1474 "^status":
1473 (status,
1475 (status,
1474 [('m', 'modified', None, 'show only modified files'),
1476 [('m', 'modified', None, 'show only modified files'),
1475 ('a', 'added', None, 'show only added files'),
1477 ('a', 'added', None, 'show only added files'),
1476 ('r', 'removed', None, 'show only removed files'),
1478 ('r', 'removed', None, 'show only removed files'),
1477 ('u', 'unknown', None, 'show only unknown (not tracked) files'),
1479 ('u', 'unknown', None, 'show only unknown (not tracked) files'),
1478 ('I', 'include', [], 'include path in search'),
1480 ('I', 'include', [], 'include path in search'),
1479 ('X', 'exclude', [], 'exclude path from search')],
1481 ('X', 'exclude', [], 'exclude path from search')],
1480 "hg status [OPTION]... [FILE]..."),
1482 "hg status [OPTION]... [FILE]..."),
1481 "tag":
1483 "tag":
1482 (tag,
1484 (tag,
1483 [('l', 'local', None, 'make the tag local'),
1485 [('l', 'local', None, 'make the tag local'),
1484 ('m', 'message', "", 'commit message'),
1486 ('m', 'message', "", 'commit message'),
1485 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1487 ('t', 'text', "", 'commit message (deprecated: use -m)'),
1486 ('d', 'date', "", 'date code'),
1488 ('d', 'date', "", 'date code'),
1487 ('u', 'user', "", 'user')],
1489 ('u', 'user', "", 'user')],
1488 'hg tag [OPTION]... NAME [REV]'),
1490 'hg tag [OPTION]... NAME [REV]'),
1489 "tags": (tags, [], 'hg tags'),
1491 "tags": (tags, [], 'hg tags'),
1490 "tip": (tip, [], 'hg tip'),
1492 "tip": (tip, [], 'hg tip'),
1491 "undo": (undo, [], 'hg undo'),
1493 "undo": (undo, [], 'hg undo'),
1492 "^update|up|checkout|co":
1494 "^update|up|checkout|co":
1493 (update,
1495 (update,
1494 [('b', 'branch', "", 'checkout the head of a specific branch'),
1496 [('b', 'branch', "", 'checkout the head of a specific branch'),
1495 ('m', 'merge', None, 'allow merging of conflicts'),
1497 ('m', 'merge', None, 'allow merging of conflicts'),
1496 ('C', 'clean', None, 'overwrite locally modified files')],
1498 ('C', 'clean', None, 'overwrite locally modified files')],
1497 'hg update [-b TAG] [-m] [-C] [REV]'),
1499 'hg update [-b TAG] [-m] [-C] [REV]'),
1498 "verify": (verify, [], 'hg verify'),
1500 "verify": (verify, [], 'hg verify'),
1499 "version": (show_version, [], 'hg version'),
1501 "version": (show_version, [], 'hg version'),
1500 }
1502 }
1501
1503
1502 globalopts = [('v', 'verbose', None, 'verbose mode'),
1504 globalopts = [('v', 'verbose', None, 'verbose mode'),
1503 ('', 'debug', None, 'debug mode'),
1505 ('', 'debug', None, 'debug mode'),
1504 ('q', 'quiet', None, 'quiet mode'),
1506 ('q', 'quiet', None, 'quiet mode'),
1505 ('', 'profile', None, 'profile'),
1507 ('', 'profile', None, 'profile'),
1506 ('', 'cwd', '', 'change working directory'),
1508 ('', 'cwd', '', 'change working directory'),
1507 ('R', 'repository', "", 'repository root directory'),
1509 ('R', 'repository', "", 'repository root directory'),
1508 ('', 'traceback', None, 'print traceback on exception'),
1510 ('', 'traceback', None, 'print traceback on exception'),
1509 ('y', 'noninteractive', None, 'run non-interactively'),
1511 ('y', 'noninteractive', None, 'run non-interactively'),
1510 ('', 'version', None, 'output version information and exit'),
1512 ('', 'version', None, 'output version information and exit'),
1511 ('', 'time', None, 'time how long the command takes'),
1513 ('', 'time', None, 'time how long the command takes'),
1512 ]
1514 ]
1513
1515
1514 norepo = "clone init version help debugconfig debugindex debugindexdot paths"
1516 norepo = "clone init version help debugconfig debugindex debugindexdot paths"
1515
1517
1516 def find(cmd):
1518 def find(cmd):
1517 for e in table.keys():
1519 for e in table.keys():
1518 if re.match("(%s)$" % e, cmd):
1520 if re.match("(%s)$" % e, cmd):
1519 return e, table[e]
1521 return e, table[e]
1520
1522
1521 raise UnknownCommand(cmd)
1523 raise UnknownCommand(cmd)
1522
1524
1523 class SignalInterrupt(Exception):
1525 class SignalInterrupt(Exception):
1524 """Exception raised on SIGTERM and SIGHUP."""
1526 """Exception raised on SIGTERM and SIGHUP."""
1525
1527
1526 def catchterm(*args):
1528 def catchterm(*args):
1527 raise SignalInterrupt
1529 raise SignalInterrupt
1528
1530
1529 def run():
1531 def run():
1530 sys.exit(dispatch(sys.argv[1:]))
1532 sys.exit(dispatch(sys.argv[1:]))
1531
1533
1532 class ParseError(Exception):
1534 class ParseError(Exception):
1533 """Exception raised on errors in parsing the command line."""
1535 """Exception raised on errors in parsing the command line."""
1534
1536
1535 def parse(args):
1537 def parse(args):
1536 options = {}
1538 options = {}
1537 cmdoptions = {}
1539 cmdoptions = {}
1538
1540
1539 try:
1541 try:
1540 args = fancyopts.fancyopts(args, globalopts, options)
1542 args = fancyopts.fancyopts(args, globalopts, options)
1541 except fancyopts.getopt.GetoptError, inst:
1543 except fancyopts.getopt.GetoptError, inst:
1542 raise ParseError(None, inst)
1544 raise ParseError(None, inst)
1543
1545
1544 if options["version"]:
1546 if options["version"]:
1545 return ("version", show_version, [], options, cmdoptions)
1547 return ("version", show_version, [], options, cmdoptions)
1546 elif not args:
1548 elif not args:
1547 return ("help", help_, ["shortlist"], options, cmdoptions)
1549 return ("help", help_, ["shortlist"], options, cmdoptions)
1548 else:
1550 else:
1549 cmd, args = args[0], args[1:]
1551 cmd, args = args[0], args[1:]
1550
1552
1551 i = find(cmd)[1]
1553 i = find(cmd)[1]
1552
1554
1553 # combine global options into local
1555 # combine global options into local
1554 c = list(i[1])
1556 c = list(i[1])
1555 for o in globalopts:
1557 for o in globalopts:
1556 c.append((o[0], o[1], options[o[1]], o[3]))
1558 c.append((o[0], o[1], options[o[1]], o[3]))
1557
1559
1558 try:
1560 try:
1559 args = fancyopts.fancyopts(args, c, cmdoptions)
1561 args = fancyopts.fancyopts(args, c, cmdoptions)
1560 except fancyopts.getopt.GetoptError, inst:
1562 except fancyopts.getopt.GetoptError, inst:
1561 raise ParseError(cmd, inst)
1563 raise ParseError(cmd, inst)
1562
1564
1563 # separate global options back out
1565 # separate global options back out
1564 for o in globalopts:
1566 for o in globalopts:
1565 n = o[1]
1567 n = o[1]
1566 options[n] = cmdoptions[n]
1568 options[n] = cmdoptions[n]
1567 del cmdoptions[n]
1569 del cmdoptions[n]
1568
1570
1569 return (cmd, i[0], args, options, cmdoptions)
1571 return (cmd, i[0], args, options, cmdoptions)
1570
1572
1571 def dispatch(args):
1573 def dispatch(args):
1572 signal.signal(signal.SIGTERM, catchterm)
1574 signal.signal(signal.SIGTERM, catchterm)
1573 try:
1575 try:
1574 signal.signal(signal.SIGHUP, catchterm)
1576 signal.signal(signal.SIGHUP, catchterm)
1575 except AttributeError:
1577 except AttributeError:
1576 pass
1578 pass
1577
1579
1578 try:
1580 try:
1579 cmd, func, args, options, cmdoptions = parse(args)
1581 cmd, func, args, options, cmdoptions = parse(args)
1580 except ParseError, inst:
1582 except ParseError, inst:
1581 u = ui.ui()
1583 u = ui.ui()
1582 if inst.args[0]:
1584 if inst.args[0]:
1583 u.warn("hg %s: %s\n" % (inst.args[0], inst.args[1]))
1585 u.warn("hg %s: %s\n" % (inst.args[0], inst.args[1]))
1584 help_(u, inst.args[0])
1586 help_(u, inst.args[0])
1585 else:
1587 else:
1586 u.warn("hg: %s\n" % inst.args[1])
1588 u.warn("hg: %s\n" % inst.args[1])
1587 help_(u, 'shortlist')
1589 help_(u, 'shortlist')
1588 sys.exit(-1)
1590 sys.exit(-1)
1589 except UnknownCommand, inst:
1591 except UnknownCommand, inst:
1590 u = ui.ui()
1592 u = ui.ui()
1591 u.warn("hg: unknown command '%s'\n" % inst.args[0])
1593 u.warn("hg: unknown command '%s'\n" % inst.args[0])
1592 help_(u, 'shortlist')
1594 help_(u, 'shortlist')
1593 sys.exit(1)
1595 sys.exit(1)
1594
1596
1595 if options['cwd']:
1597 if options['cwd']:
1596 try:
1598 try:
1597 os.chdir(options['cwd'])
1599 os.chdir(options['cwd'])
1598 except OSError, inst:
1600 except OSError, inst:
1599 u = ui.ui()
1601 u = ui.ui()
1600 u.warn('abort: %s: %s\n' % (options['cwd'], inst.strerror))
1602 u.warn('abort: %s: %s\n' % (options['cwd'], inst.strerror))
1601 sys.exit(1)
1603 sys.exit(1)
1602
1604
1603 if options["time"]:
1605 if options["time"]:
1604 def get_times():
1606 def get_times():
1605 t = os.times()
1607 t = os.times()
1606 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
1608 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
1607 t = (t[0], t[1], t[2], t[3], time.clock())
1609 t = (t[0], t[1], t[2], t[3], time.clock())
1608 return t
1610 return t
1609 s = get_times()
1611 s = get_times()
1610 def print_time():
1612 def print_time():
1611 t = get_times()
1613 t = get_times()
1612 u = ui.ui()
1614 u = ui.ui()
1613 u.warn("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n" %
1615 u.warn("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n" %
1614 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
1616 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
1615 atexit.register(print_time)
1617 atexit.register(print_time)
1616
1618
1617 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
1619 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
1618 not options["noninteractive"])
1620 not options["noninteractive"])
1619
1621
1620 try:
1622 try:
1621 try:
1623 try:
1622 if cmd not in norepo.split():
1624 if cmd not in norepo.split():
1623 path = options["repository"] or ""
1625 path = options["repository"] or ""
1624 repo = hg.repository(ui=u, path=path)
1626 repo = hg.repository(ui=u, path=path)
1625 d = lambda: func(u, repo, *args, **cmdoptions)
1627 d = lambda: func(u, repo, *args, **cmdoptions)
1626 else:
1628 else:
1627 d = lambda: func(u, *args, **cmdoptions)
1629 d = lambda: func(u, *args, **cmdoptions)
1628
1630
1629 if options['profile']:
1631 if options['profile']:
1630 import hotshot, hotshot.stats
1632 import hotshot, hotshot.stats
1631 prof = hotshot.Profile("hg.prof")
1633 prof = hotshot.Profile("hg.prof")
1632 r = prof.runcall(d)
1634 r = prof.runcall(d)
1633 prof.close()
1635 prof.close()
1634 stats = hotshot.stats.load("hg.prof")
1636 stats = hotshot.stats.load("hg.prof")
1635 stats.strip_dirs()
1637 stats.strip_dirs()
1636 stats.sort_stats('time', 'calls')
1638 stats.sort_stats('time', 'calls')
1637 stats.print_stats(40)
1639 stats.print_stats(40)
1638 return r
1640 return r
1639 else:
1641 else:
1640 return d()
1642 return d()
1641 except:
1643 except:
1642 if options['traceback']:
1644 if options['traceback']:
1643 traceback.print_exc()
1645 traceback.print_exc()
1644 raise
1646 raise
1645 except hg.RepoError, inst:
1647 except hg.RepoError, inst:
1646 u.warn("abort: ", inst, "!\n")
1648 u.warn("abort: ", inst, "!\n")
1647 except SignalInterrupt:
1649 except SignalInterrupt:
1648 u.warn("killed!\n")
1650 u.warn("killed!\n")
1649 except KeyboardInterrupt:
1651 except KeyboardInterrupt:
1650 try:
1652 try:
1651 u.warn("interrupted!\n")
1653 u.warn("interrupted!\n")
1652 except IOError, inst:
1654 except IOError, inst:
1653 if inst.errno == errno.EPIPE:
1655 if inst.errno == errno.EPIPE:
1654 if u.debugflag:
1656 if u.debugflag:
1655 u.warn("\nbroken pipe\n")
1657 u.warn("\nbroken pipe\n")
1656 else:
1658 else:
1657 raise
1659 raise
1658 except IOError, inst:
1660 except IOError, inst:
1659 if hasattr(inst, "code"):
1661 if hasattr(inst, "code"):
1660 u.warn("abort: %s\n" % inst)
1662 u.warn("abort: %s\n" % inst)
1661 elif hasattr(inst, "reason"):
1663 elif hasattr(inst, "reason"):
1662 u.warn("abort: error: %s\n" % inst.reason[1])
1664 u.warn("abort: error: %s\n" % inst.reason[1])
1663 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
1665 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
1664 if u.debugflag: u.warn("broken pipe\n")
1666 if u.debugflag: u.warn("broken pipe\n")
1665 else:
1667 else:
1666 raise
1668 raise
1667 except OSError, inst:
1669 except OSError, inst:
1668 if hasattr(inst, "filename"):
1670 if hasattr(inst, "filename"):
1669 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename))
1671 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename))
1670 else:
1672 else:
1671 u.warn("abort: %s\n" % inst.strerror)
1673 u.warn("abort: %s\n" % inst.strerror)
1672 except util.Abort, inst:
1674 except util.Abort, inst:
1673 u.warn('abort: ', inst.args[0] % inst.args[1:], '\n')
1675 u.warn('abort: ', inst.args[0] % inst.args[1:], '\n')
1674 sys.exit(1)
1676 sys.exit(1)
1675 except TypeError, inst:
1677 except TypeError, inst:
1676 # was this an argument error?
1678 # was this an argument error?
1677 tb = traceback.extract_tb(sys.exc_info()[2])
1679 tb = traceback.extract_tb(sys.exc_info()[2])
1678 if len(tb) > 2: # no
1680 if len(tb) > 2: # no
1679 raise
1681 raise
1680 u.debug(inst, "\n")
1682 u.debug(inst, "\n")
1681 u.warn("%s: invalid arguments\n" % cmd)
1683 u.warn("%s: invalid arguments\n" % cmd)
1682 help_(u, cmd)
1684 help_(u, cmd)
1683 except UnknownCommand, inst:
1685 except UnknownCommand, inst:
1684 u.warn("hg: unknown command '%s'\n" % inst.args[0])
1686 u.warn("hg: unknown command '%s'\n" % inst.args[0])
1685 help_(u, 'shortlist')
1687 help_(u, 'shortlist')
1686
1688
1687 sys.exit(-1)
1689 sys.exit(-1)
@@ -1,216 +1,216 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 the revision history of the repository or a single file
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 the revision history of the repository or a single file
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 the revision history of the repository or a single file
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 the revision history of the repository or a single file
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
115 hg add: option -h not recognized
116 hg add [OPTION]... [FILE]...
116 hg add [OPTION]... [FILE]...
117
117
118 add the specified files on the next commit
118 add the specified files on the next commit
119
119
120 options:
120 options:
121
121
122 -I --include
122 -I --include
123 include path in search
123 include path in search
124 -X --exclude
124 -X --exclude
125 exclude path from search
125 exclude path from search
126 hg add: option --skjdfks not recognized
126 hg add: option --skjdfks not recognized
127 hg add [OPTION]... [FILE]...
127 hg add [OPTION]... [FILE]...
128
128
129 add the specified files on the next commit
129 add the specified files on the next commit
130
130
131 options:
131 options:
132
132
133 -I --include
133 -I --include
134 include path in search
134 include path in search
135 -X --exclude
135 -X --exclude
136 exclude path from search
136 exclude path from search
137 hg diff [-I] [-X] [-r REV1 [-r REV2]] [FILE]...
137 hg diff [-I] [-X] [-r REV1 [-r REV2]] [FILE]...
138
138
139 diff working directory (or selected files)
139 diff working directory (or selected files)
140
140
141 options:
141 options:
142
142
143 -r --rev
143 -r --rev
144 revision
144 revision
145 -a --text
145 -a --text
146 treat all files as text
146 treat all files as text
147 -I --include
147 -I --include
148 include path in search
148 include path in search
149 -X --exclude
149 -X --exclude
150 exclude path from search
150 exclude path from search
151 hg status [OPTION]... [FILE]...
151 hg status [OPTION]... [FILE]...
152
152
153 show changed files in the working directory
153 show changed files in the working directory
154
154
155 M = modified
155 M = modified
156 A = added
156 A = added
157 R = removed
157 R = removed
158 ? = not tracked
158 ? = not tracked
159
159
160 options:
160 options:
161
161
162 -m --modified
162 -m --modified
163 show only modified files
163 show only modified files
164 -a --added
164 -a --added
165 show only added files
165 show only added files
166 -r --removed
166 -r --removed
167 show only removed files
167 show only removed files
168 -u --unknown
168 -u --unknown
169 show only unknown (not tracked) files
169 show only unknown (not tracked) files
170 -I --include
170 -I --include
171 include path in search
171 include path in search
172 -X --exclude
172 -X --exclude
173 exclude path from search
173 exclude path from search
174 hg status [OPTION]... [FILE]...
174 hg status [OPTION]... [FILE]...
175
175
176 show changed files in the working directory
176 show changed files in the working directory
177 hg: unknown command 'foo'
177 hg: unknown command 'foo'
178 Mercurial Distributed SCM
178 Mercurial Distributed SCM
179
179
180 basic commands (use "hg help" for the full list or option "-v" for details):
180 basic commands (use "hg help" for the full list or option "-v" for details):
181
181
182 add add the specified files on the next commit
182 add add the specified files on the next commit
183 annotate show changeset information per file line
183 annotate show changeset information per file line
184 clone make a copy of an existing repository
184 clone make a copy of an existing repository
185 commit commit the specified files or all outstanding changes
185 commit commit the specified files or all outstanding changes
186 diff diff working directory (or selected files)
186 diff diff working directory (or selected files)
187 export dump the header and diffs for one or more changesets
187 export dump the header and diffs for one or more changesets
188 init create a new repository in the given directory
188 init create a new repository in the given directory
189 log show the revision history of the repository or a single file
189 log show revision history of entire repository or files
190 pull pull changes from the specified source
190 pull pull changes from the specified source
191 push push changes to the specified destination
191 push push changes to the specified destination
192 remove remove the specified files on the next commit
192 remove remove the specified files on the next commit
193 revert revert modified files or dirs back to their unmodified states
193 revert revert modified files or dirs back to their unmodified states
194 serve export the repository via HTTP
194 serve export the repository via HTTP
195 status show changed files in the working directory
195 status show changed files in the working directory
196 update update or merge working directory
196 update update or merge working directory
197 hg: unknown command 'skjdfks'
197 hg: unknown command 'skjdfks'
198 Mercurial Distributed SCM
198 Mercurial Distributed SCM
199
199
200 basic commands (use "hg help" for the full list or option "-v" for details):
200 basic commands (use "hg help" for the full list or option "-v" for details):
201
201
202 add add the specified files on the next commit
202 add add the specified files on the next commit
203 annotate show changeset information per file line
203 annotate show changeset information per file line
204 clone make a copy of an existing repository
204 clone make a copy of an existing repository
205 commit commit the specified files or all outstanding changes
205 commit commit the specified files or all outstanding changes
206 diff diff working directory (or selected files)
206 diff diff working directory (or selected files)
207 export dump the header and diffs for one or more changesets
207 export dump the header and diffs for one or more changesets
208 init create a new repository in the given directory
208 init create a new repository in the given directory
209 log show the revision history of the repository or a single file
209 log show revision history of entire repository or files
210 pull pull changes from the specified source
210 pull pull changes from the specified source
211 push push changes to the specified destination
211 push push changes to the specified destination
212 remove remove the specified files on the next commit
212 remove remove the specified files on the next commit
213 revert revert modified files or dirs back to their unmodified states
213 revert revert modified files or dirs back to their unmodified states
214 serve export the repository via HTTP
214 serve export the repository via HTTP
215 status show changed files in the working directory
215 status show changed files in the working directory
216 update update or merge working directory
216 update update or merge working directory
General Comments 0
You need to be logged in to leave comments. Login now