##// END OF EJS Templates
import docstring from doc/hg.1.txt
Benoit Boissinot -
r1437:ea51d296 default
parent child Browse files
Show More
This diff has been collapsed as it changes many lines, (642 lines changed) Show them Hide them
@@ -1,2258 +1,2626
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 from node import *
9 from node import *
10 from i18n import gettext as _
10 from i18n import gettext as _
11 demandload(globals(), "os re sys signal shutil imp urllib pdb")
11 demandload(globals(), "os re sys signal shutil imp urllib pdb")
12 demandload(globals(), "fancyopts ui hg util lock revlog")
12 demandload(globals(), "fancyopts ui hg util lock revlog")
13 demandload(globals(), "fnmatch hgweb mdiff random signal time traceback")
13 demandload(globals(), "fnmatch hgweb mdiff random signal time traceback")
14 demandload(globals(), "errno socket version struct atexit sets bz2")
14 demandload(globals(), "errno socket version struct atexit sets bz2")
15
15
16 class UnknownCommand(Exception):
16 class UnknownCommand(Exception):
17 """Exception raised if command is not in the command table."""
17 """Exception raised if command is not in the command table."""
18
18
19 def filterfiles(filters, files):
19 def filterfiles(filters, files):
20 l = [x for x in files if x in filters]
20 l = [x for x in files if x in filters]
21
21
22 for t in filters:
22 for t in filters:
23 if t and t[-1] != "/":
23 if t and t[-1] != "/":
24 t += "/"
24 t += "/"
25 l += [x for x in files if x.startswith(t)]
25 l += [x for x in files if x.startswith(t)]
26 return l
26 return l
27
27
28 def relpath(repo, args):
28 def relpath(repo, args):
29 cwd = repo.getcwd()
29 cwd = repo.getcwd()
30 if cwd:
30 if cwd:
31 return [util.normpath(os.path.join(cwd, x)) for x in args]
31 return [util.normpath(os.path.join(cwd, x)) for x in args]
32 return args
32 return args
33
33
34 def matchpats(repo, cwd, pats=[], opts={}, head=''):
34 def matchpats(repo, cwd, pats=[], opts={}, head=''):
35 return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
35 return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
36 opts.get('exclude'), head)
36 opts.get('exclude'), head)
37
37
38 def makewalk(repo, pats, opts, head=''):
38 def makewalk(repo, pats, opts, head=''):
39 cwd = repo.getcwd()
39 cwd = repo.getcwd()
40 files, matchfn, anypats = matchpats(repo, cwd, pats, opts, head)
40 files, matchfn, anypats = matchpats(repo, cwd, pats, opts, head)
41 exact = dict(zip(files, files))
41 exact = dict(zip(files, files))
42 def walk():
42 def walk():
43 for src, fn in repo.walk(files=files, match=matchfn):
43 for src, fn in repo.walk(files=files, match=matchfn):
44 yield src, fn, util.pathto(cwd, fn), fn in exact
44 yield src, fn, util.pathto(cwd, fn), fn in exact
45 return files, matchfn, walk()
45 return files, matchfn, walk()
46
46
47 def walk(repo, pats, opts, head=''):
47 def walk(repo, pats, opts, head=''):
48 files, matchfn, results = makewalk(repo, pats, opts, head)
48 files, matchfn, results = makewalk(repo, pats, opts, head)
49 for r in results:
49 for r in results:
50 yield r
50 yield r
51
51
52 def walkchangerevs(ui, repo, cwd, pats, opts):
52 def walkchangerevs(ui, repo, cwd, pats, opts):
53 '''Iterate over files and the revs they changed in.
53 '''Iterate over files and the revs they changed in.
54
54
55 Callers most commonly need to iterate backwards over the history
55 Callers most commonly need to iterate backwards over the history
56 it is interested in. Doing so has awful (quadratic-looking)
56 it is interested in. Doing so has awful (quadratic-looking)
57 performance, so we use iterators in a "windowed" way.
57 performance, so we use iterators in a "windowed" way.
58
58
59 We walk a window of revisions in the desired order. Within the
59 We walk a window of revisions in the desired order. Within the
60 window, we first walk forwards to gather data, then in the desired
60 window, we first walk forwards to gather data, then in the desired
61 order (usually backwards) to display it.
61 order (usually backwards) to display it.
62
62
63 This function returns an (iterator, getchange) pair. The
63 This function returns an (iterator, getchange) pair. The
64 getchange function returns the changelog entry for a numeric
64 getchange function returns the changelog entry for a numeric
65 revision. The iterator yields 3-tuples. They will be of one of
65 revision. The iterator yields 3-tuples. They will be of one of
66 the following forms:
66 the following forms:
67
67
68 "window", incrementing, lastrev: stepping through a window,
68 "window", incrementing, lastrev: stepping through a window,
69 positive if walking forwards through revs, last rev in the
69 positive if walking forwards through revs, last rev in the
70 sequence iterated over - use to reset state for the current window
70 sequence iterated over - use to reset state for the current window
71
71
72 "add", rev, fns: out-of-order traversal of the given file names
72 "add", rev, fns: out-of-order traversal of the given file names
73 fns, which changed during revision rev - use to gather data for
73 fns, which changed during revision rev - use to gather data for
74 possible display
74 possible display
75
75
76 "iter", rev, None: in-order traversal of the revs earlier iterated
76 "iter", rev, None: in-order traversal of the revs earlier iterated
77 over with "add" - use to display data'''
77 over with "add" - use to display data'''
78
78
79 if repo.changelog.count() == 0:
79 if repo.changelog.count() == 0:
80 return [], False
80 return [], False
81
81
82 cwd = repo.getcwd()
82 cwd = repo.getcwd()
83 if not pats and cwd:
83 if not pats and cwd:
84 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
84 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
85 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
85 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
86 files, matchfn, anypats = matchpats(repo, (pats and cwd) or '',
86 files, matchfn, anypats = matchpats(repo, (pats and cwd) or '',
87 pats, opts)
87 pats, opts)
88 revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
88 revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
89 wanted = {}
89 wanted = {}
90 slowpath = anypats
90 slowpath = anypats
91 window = 300
91 window = 300
92 fncache = {}
92 fncache = {}
93
93
94 chcache = {}
94 chcache = {}
95 def getchange(rev):
95 def getchange(rev):
96 ch = chcache.get(rev)
96 ch = chcache.get(rev)
97 if ch is None:
97 if ch is None:
98 chcache[rev] = ch = repo.changelog.read(repo.lookup(str(rev)))
98 chcache[rev] = ch = repo.changelog.read(repo.lookup(str(rev)))
99 return ch
99 return ch
100
100
101 if not slowpath and not files:
101 if not slowpath and not files:
102 # No files, no patterns. Display all revs.
102 # No files, no patterns. Display all revs.
103 wanted = dict(zip(revs, revs))
103 wanted = dict(zip(revs, revs))
104 if not slowpath:
104 if not slowpath:
105 # Only files, no patterns. Check the history of each file.
105 # Only files, no patterns. Check the history of each file.
106 def filerevgen(filelog):
106 def filerevgen(filelog):
107 for i in xrange(filelog.count() - 1, -1, -window):
107 for i in xrange(filelog.count() - 1, -1, -window):
108 revs = []
108 revs = []
109 for j in xrange(max(0, i - window), i + 1):
109 for j in xrange(max(0, i - window), i + 1):
110 revs.append(filelog.linkrev(filelog.node(j)))
110 revs.append(filelog.linkrev(filelog.node(j)))
111 revs.reverse()
111 revs.reverse()
112 for rev in revs:
112 for rev in revs:
113 yield rev
113 yield rev
114
114
115 minrev, maxrev = min(revs), max(revs)
115 minrev, maxrev = min(revs), max(revs)
116 for file in files:
116 for file in files:
117 filelog = repo.file(file)
117 filelog = repo.file(file)
118 # A zero count may be a directory or deleted file, so
118 # A zero count may be a directory or deleted file, so
119 # try to find matching entries on the slow path.
119 # try to find matching entries on the slow path.
120 if filelog.count() == 0:
120 if filelog.count() == 0:
121 slowpath = True
121 slowpath = True
122 break
122 break
123 for rev in filerevgen(filelog):
123 for rev in filerevgen(filelog):
124 if rev <= maxrev:
124 if rev <= maxrev:
125 if rev < minrev:
125 if rev < minrev:
126 break
126 break
127 fncache.setdefault(rev, [])
127 fncache.setdefault(rev, [])
128 fncache[rev].append(file)
128 fncache[rev].append(file)
129 wanted[rev] = 1
129 wanted[rev] = 1
130 if slowpath:
130 if slowpath:
131 # The slow path checks files modified in every changeset.
131 # The slow path checks files modified in every changeset.
132 def changerevgen():
132 def changerevgen():
133 for i in xrange(repo.changelog.count() - 1, -1, -window):
133 for i in xrange(repo.changelog.count() - 1, -1, -window):
134 for j in xrange(max(0, i - window), i + 1):
134 for j in xrange(max(0, i - window), i + 1):
135 yield j, getchange(j)[3]
135 yield j, getchange(j)[3]
136
136
137 for rev, changefiles in changerevgen():
137 for rev, changefiles in changerevgen():
138 matches = filter(matchfn, changefiles)
138 matches = filter(matchfn, changefiles)
139 if matches:
139 if matches:
140 fncache[rev] = matches
140 fncache[rev] = matches
141 wanted[rev] = 1
141 wanted[rev] = 1
142
142
143 def iterate():
143 def iterate():
144 for i in xrange(0, len(revs), window):
144 for i in xrange(0, len(revs), window):
145 yield 'window', revs[0] < revs[-1], revs[-1]
145 yield 'window', revs[0] < revs[-1], revs[-1]
146 nrevs = [rev for rev in revs[i:min(i+window, len(revs))]
146 nrevs = [rev for rev in revs[i:min(i+window, len(revs))]
147 if rev in wanted]
147 if rev in wanted]
148 srevs = list(nrevs)
148 srevs = list(nrevs)
149 srevs.sort()
149 srevs.sort()
150 for rev in srevs:
150 for rev in srevs:
151 fns = fncache.get(rev) or filter(matchfn, getchange(rev)[3])
151 fns = fncache.get(rev) or filter(matchfn, getchange(rev)[3])
152 yield 'add', rev, fns
152 yield 'add', rev, fns
153 for rev in nrevs:
153 for rev in nrevs:
154 yield 'iter', rev, None
154 yield 'iter', rev, None
155 return iterate(), getchange
155 return iterate(), getchange
156
156
157 revrangesep = ':'
157 revrangesep = ':'
158
158
159 def revrange(ui, repo, revs, revlog=None):
159 def revrange(ui, repo, revs, revlog=None):
160 """Yield revision as strings from a list of revision specifications."""
160 """Yield revision as strings from a list of revision specifications."""
161 if revlog is None:
161 if revlog is None:
162 revlog = repo.changelog
162 revlog = repo.changelog
163 revcount = revlog.count()
163 revcount = revlog.count()
164 def fix(val, defval):
164 def fix(val, defval):
165 if not val:
165 if not val:
166 return defval
166 return defval
167 try:
167 try:
168 num = int(val)
168 num = int(val)
169 if str(num) != val:
169 if str(num) != val:
170 raise ValueError
170 raise ValueError
171 if num < 0: num += revcount
171 if num < 0: num += revcount
172 if num < 0: num = 0
172 if num < 0: num = 0
173 elif num >= revcount:
173 elif num >= revcount:
174 raise ValueError
174 raise ValueError
175 except ValueError:
175 except ValueError:
176 try:
176 try:
177 num = repo.changelog.rev(repo.lookup(val))
177 num = repo.changelog.rev(repo.lookup(val))
178 except KeyError:
178 except KeyError:
179 try:
179 try:
180 num = revlog.rev(revlog.lookup(val))
180 num = revlog.rev(revlog.lookup(val))
181 except KeyError:
181 except KeyError:
182 raise util.Abort(_('invalid revision identifier %s'), val)
182 raise util.Abort(_('invalid revision identifier %s'), val)
183 return num
183 return num
184 seen = {}
184 seen = {}
185 for spec in revs:
185 for spec in revs:
186 if spec.find(revrangesep) >= 0:
186 if spec.find(revrangesep) >= 0:
187 start, end = spec.split(revrangesep, 1)
187 start, end = spec.split(revrangesep, 1)
188 start = fix(start, 0)
188 start = fix(start, 0)
189 end = fix(end, revcount - 1)
189 end = fix(end, revcount - 1)
190 step = start > end and -1 or 1
190 step = start > end and -1 or 1
191 for rev in xrange(start, end+step, step):
191 for rev in xrange(start, end+step, step):
192 if rev in seen: continue
192 if rev in seen: continue
193 seen[rev] = 1
193 seen[rev] = 1
194 yield str(rev)
194 yield str(rev)
195 else:
195 else:
196 rev = fix(spec, None)
196 rev = fix(spec, None)
197 if rev in seen: continue
197 if rev in seen: continue
198 seen[rev] = 1
198 seen[rev] = 1
199 yield str(rev)
199 yield str(rev)
200
200
201 def make_filename(repo, r, pat, node=None,
201 def make_filename(repo, r, pat, node=None,
202 total=None, seqno=None, revwidth=None, pathname=None):
202 total=None, seqno=None, revwidth=None, pathname=None):
203 node_expander = {
203 node_expander = {
204 'H': lambda: hex(node),
204 'H': lambda: hex(node),
205 'R': lambda: str(r.rev(node)),
205 'R': lambda: str(r.rev(node)),
206 'h': lambda: short(node),
206 'h': lambda: short(node),
207 }
207 }
208 expander = {
208 expander = {
209 '%': lambda: '%',
209 '%': lambda: '%',
210 'b': lambda: os.path.basename(repo.root),
210 'b': lambda: os.path.basename(repo.root),
211 }
211 }
212
212
213 try:
213 try:
214 if node:
214 if node:
215 expander.update(node_expander)
215 expander.update(node_expander)
216 if node and revwidth is not None:
216 if node and revwidth is not None:
217 expander['r'] = lambda: str(r.rev(node)).zfill(revwidth)
217 expander['r'] = lambda: str(r.rev(node)).zfill(revwidth)
218 if total is not None:
218 if total is not None:
219 expander['N'] = lambda: str(total)
219 expander['N'] = lambda: str(total)
220 if seqno is not None:
220 if seqno is not None:
221 expander['n'] = lambda: str(seqno)
221 expander['n'] = lambda: str(seqno)
222 if total is not None and seqno is not None:
222 if total is not None and seqno is not None:
223 expander['n'] = lambda:str(seqno).zfill(len(str(total)))
223 expander['n'] = lambda:str(seqno).zfill(len(str(total)))
224 if pathname is not None:
224 if pathname is not None:
225 expander['s'] = lambda: os.path.basename(pathname)
225 expander['s'] = lambda: os.path.basename(pathname)
226 expander['d'] = lambda: os.path.dirname(pathname) or '.'
226 expander['d'] = lambda: os.path.dirname(pathname) or '.'
227 expander['p'] = lambda: pathname
227 expander['p'] = lambda: pathname
228
228
229 newname = []
229 newname = []
230 patlen = len(pat)
230 patlen = len(pat)
231 i = 0
231 i = 0
232 while i < patlen:
232 while i < patlen:
233 c = pat[i]
233 c = pat[i]
234 if c == '%':
234 if c == '%':
235 i += 1
235 i += 1
236 c = pat[i]
236 c = pat[i]
237 c = expander[c]()
237 c = expander[c]()
238 newname.append(c)
238 newname.append(c)
239 i += 1
239 i += 1
240 return ''.join(newname)
240 return ''.join(newname)
241 except KeyError, inst:
241 except KeyError, inst:
242 raise util.Abort(_("invalid format spec '%%%s' in output file name"),
242 raise util.Abort(_("invalid format spec '%%%s' in output file name"),
243 inst.args[0])
243 inst.args[0])
244
244
245 def make_file(repo, r, pat, node=None,
245 def make_file(repo, r, pat, node=None,
246 total=None, seqno=None, revwidth=None, mode='wb', pathname=None):
246 total=None, seqno=None, revwidth=None, mode='wb', pathname=None):
247 if not pat or pat == '-':
247 if not pat or pat == '-':
248 return 'w' in mode and sys.stdout or sys.stdin
248 return 'w' in mode and sys.stdout or sys.stdin
249 if hasattr(pat, 'write') and 'w' in mode:
249 if hasattr(pat, 'write') and 'w' in mode:
250 return pat
250 return pat
251 if hasattr(pat, 'read') and 'r' in mode:
251 if hasattr(pat, 'read') and 'r' in mode:
252 return pat
252 return pat
253 return open(make_filename(repo, r, pat, node, total, seqno, revwidth,
253 return open(make_filename(repo, r, pat, node, total, seqno, revwidth,
254 pathname),
254 pathname),
255 mode)
255 mode)
256
256
257 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always,
257 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always,
258 changes=None, text=False):
258 changes=None, text=False):
259 if not changes:
259 if not changes:
260 (c, a, d, u) = repo.changes(node1, node2, files, match=match)
260 (c, a, d, u) = repo.changes(node1, node2, files, match=match)
261 else:
261 else:
262 (c, a, d, u) = changes
262 (c, a, d, u) = changes
263 if files:
263 if files:
264 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
264 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
265
265
266 if not c and not a and not d:
266 if not c and not a and not d:
267 return
267 return
268
268
269 if node2:
269 if node2:
270 change = repo.changelog.read(node2)
270 change = repo.changelog.read(node2)
271 mmap2 = repo.manifest.read(change[0])
271 mmap2 = repo.manifest.read(change[0])
272 date2 = util.datestr(change[2])
272 date2 = util.datestr(change[2])
273 def read(f):
273 def read(f):
274 return repo.file(f).read(mmap2[f])
274 return repo.file(f).read(mmap2[f])
275 else:
275 else:
276 date2 = util.datestr()
276 date2 = util.datestr()
277 if not node1:
277 if not node1:
278 node1 = repo.dirstate.parents()[0]
278 node1 = repo.dirstate.parents()[0]
279 def read(f):
279 def read(f):
280 return repo.wfile(f).read()
280 return repo.wfile(f).read()
281
281
282 if ui.quiet:
282 if ui.quiet:
283 r = None
283 r = None
284 else:
284 else:
285 hexfunc = ui.verbose and hex or short
285 hexfunc = ui.verbose and hex or short
286 r = [hexfunc(node) for node in [node1, node2] if node]
286 r = [hexfunc(node) for node in [node1, node2] if node]
287
287
288 change = repo.changelog.read(node1)
288 change = repo.changelog.read(node1)
289 mmap = repo.manifest.read(change[0])
289 mmap = repo.manifest.read(change[0])
290 date1 = util.datestr(change[2])
290 date1 = util.datestr(change[2])
291
291
292 for f in c:
292 for f in c:
293 to = None
293 to = None
294 if f in mmap:
294 if f in mmap:
295 to = repo.file(f).read(mmap[f])
295 to = repo.file(f).read(mmap[f])
296 tn = read(f)
296 tn = read(f)
297 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
297 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
298 for f in a:
298 for f in a:
299 to = None
299 to = None
300 tn = read(f)
300 tn = read(f)
301 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
301 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
302 for f in d:
302 for f in d:
303 to = repo.file(f).read(mmap[f])
303 to = repo.file(f).read(mmap[f])
304 tn = None
304 tn = None
305 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
305 fp.write(mdiff.unidiff(to, date1, tn, date2, f, r, text=text))
306
306
307 def trimuser(ui, name, rev, revcache):
307 def trimuser(ui, name, rev, revcache):
308 """trim the name of the user who committed a change"""
308 """trim the name of the user who committed a change"""
309 user = revcache.get(rev)
309 user = revcache.get(rev)
310 if user is None:
310 if user is None:
311 user = revcache[rev] = ui.shortuser(name)
311 user = revcache[rev] = ui.shortuser(name)
312 return user
312 return user
313
313
314 def show_changeset(ui, repo, rev=0, changenode=None, brinfo=None):
314 def show_changeset(ui, repo, rev=0, changenode=None, brinfo=None):
315 """show a single changeset or file revision"""
315 """show a single changeset or file revision"""
316 log = repo.changelog
316 log = repo.changelog
317 if changenode is None:
317 if changenode is None:
318 changenode = log.node(rev)
318 changenode = log.node(rev)
319 elif not rev:
319 elif not rev:
320 rev = log.rev(changenode)
320 rev = log.rev(changenode)
321
321
322 if ui.quiet:
322 if ui.quiet:
323 ui.write("%d:%s\n" % (rev, short(changenode)))
323 ui.write("%d:%s\n" % (rev, short(changenode)))
324 return
324 return
325
325
326 changes = log.read(changenode)
326 changes = log.read(changenode)
327 date = util.datestr(changes[2])
327 date = util.datestr(changes[2])
328
328
329 parents = [(log.rev(p), ui.verbose and hex(p) or short(p))
329 parents = [(log.rev(p), ui.verbose and hex(p) or short(p))
330 for p in log.parents(changenode)
330 for p in log.parents(changenode)
331 if ui.debugflag or p != nullid]
331 if ui.debugflag or p != nullid]
332 if not ui.debugflag and len(parents) == 1 and parents[0][0] == rev-1:
332 if not ui.debugflag and len(parents) == 1 and parents[0][0] == rev-1:
333 parents = []
333 parents = []
334
334
335 if ui.verbose:
335 if ui.verbose:
336 ui.write(_("changeset: %d:%s\n") % (rev, hex(changenode)))
336 ui.write(_("changeset: %d:%s\n") % (rev, hex(changenode)))
337 else:
337 else:
338 ui.write(_("changeset: %d:%s\n") % (rev, short(changenode)))
338 ui.write(_("changeset: %d:%s\n") % (rev, short(changenode)))
339
339
340 for tag in repo.nodetags(changenode):
340 for tag in repo.nodetags(changenode):
341 ui.status(_("tag: %s\n") % tag)
341 ui.status(_("tag: %s\n") % tag)
342 for parent in parents:
342 for parent in parents:
343 ui.write(_("parent: %d:%s\n") % parent)
343 ui.write(_("parent: %d:%s\n") % parent)
344
344
345 if brinfo and changenode in brinfo:
345 if brinfo and changenode in brinfo:
346 br = brinfo[changenode]
346 br = brinfo[changenode]
347 ui.write(_("branch: %s\n") % " ".join(br))
347 ui.write(_("branch: %s\n") % " ".join(br))
348
348
349 ui.debug(_("manifest: %d:%s\n") % (repo.manifest.rev(changes[0]),
349 ui.debug(_("manifest: %d:%s\n") % (repo.manifest.rev(changes[0]),
350 hex(changes[0])))
350 hex(changes[0])))
351 ui.status(_("user: %s\n") % changes[1])
351 ui.status(_("user: %s\n") % changes[1])
352 ui.status(_("date: %s\n") % date)
352 ui.status(_("date: %s\n") % date)
353
353
354 if ui.debugflag:
354 if ui.debugflag:
355 files = repo.changes(log.parents(changenode)[0], changenode)
355 files = repo.changes(log.parents(changenode)[0], changenode)
356 for key, value in zip([_("files:"), _("files+:"), _("files-:")], files):
356 for key, value in zip([_("files:"), _("files+:"), _("files-:")], files):
357 if value:
357 if value:
358 ui.note("%-12s %s\n" % (key, " ".join(value)))
358 ui.note("%-12s %s\n" % (key, " ".join(value)))
359 else:
359 else:
360 ui.note(_("files: %s\n") % " ".join(changes[3]))
360 ui.note(_("files: %s\n") % " ".join(changes[3]))
361
361
362 description = changes[4].strip()
362 description = changes[4].strip()
363 if description:
363 if description:
364 if ui.verbose:
364 if ui.verbose:
365 ui.status(_("description:\n"))
365 ui.status(_("description:\n"))
366 ui.status(description)
366 ui.status(description)
367 ui.status("\n\n")
367 ui.status("\n\n")
368 else:
368 else:
369 ui.status(_("summary: %s\n") % description.splitlines()[0])
369 ui.status(_("summary: %s\n") % description.splitlines()[0])
370 ui.status("\n")
370 ui.status("\n")
371
371
372 def show_version(ui):
372 def show_version(ui):
373 """output version and copyright information"""
373 """output version and copyright information"""
374 ui.write(_("Mercurial Distributed SCM (version %s)\n")
374 ui.write(_("Mercurial Distributed SCM (version %s)\n")
375 % version.get_version())
375 % version.get_version())
376 ui.status(_(
376 ui.status(_(
377 "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
377 "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
378 "This is free software; see the source for copying conditions. "
378 "This is free software; see the source for copying conditions. "
379 "There is NO\nwarranty; "
379 "There is NO\nwarranty; "
380 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
380 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
381 ))
381 ))
382
382
383 def help_(ui, cmd=None, with_version=False):
383 def help_(ui, cmd=None, with_version=False):
384 """show help for a given command or all commands"""
384 """show help for a given command or all commands"""
385 option_lists = []
385 option_lists = []
386 if cmd and cmd != 'shortlist':
386 if cmd and cmd != 'shortlist':
387 if with_version:
387 if with_version:
388 show_version(ui)
388 show_version(ui)
389 ui.write('\n')
389 ui.write('\n')
390 key, i = find(cmd)
390 key, i = find(cmd)
391 # synopsis
391 # synopsis
392 ui.write("%s\n\n" % i[2])
392 ui.write("%s\n\n" % i[2])
393
393
394 # description
394 # description
395 doc = i[0].__doc__
395 doc = i[0].__doc__
396 if ui.quiet:
396 if ui.quiet:
397 doc = doc.splitlines(0)[0]
397 doc = doc.splitlines(0)[0]
398 ui.write("%s\n" % doc.rstrip())
398 ui.write("%s\n" % doc.rstrip())
399
399
400 if not ui.quiet:
400 if not ui.quiet:
401 # aliases
401 # aliases
402 aliases = ', '.join(key.split('|')[1:])
402 aliases = ', '.join(key.split('|')[1:])
403 if aliases:
403 if aliases:
404 ui.write(_("\naliases: %s\n") % aliases)
404 ui.write(_("\naliases: %s\n") % aliases)
405
405
406 # options
406 # options
407 if i[1]:
407 if i[1]:
408 option_lists.append(("options", i[1]))
408 option_lists.append(("options", i[1]))
409
409
410 else:
410 else:
411 # program name
411 # program name
412 if ui.verbose or with_version:
412 if ui.verbose or with_version:
413 show_version(ui)
413 show_version(ui)
414 else:
414 else:
415 ui.status(_("Mercurial Distributed SCM\n"))
415 ui.status(_("Mercurial Distributed SCM\n"))
416 ui.status('\n')
416 ui.status('\n')
417
417
418 # list of commands
418 # list of commands
419 if cmd == "shortlist":
419 if cmd == "shortlist":
420 ui.status(_('basic commands (use "hg help" '
420 ui.status(_('basic commands (use "hg help" '
421 'for the full list or option "-v" for details):\n\n'))
421 'for the full list or option "-v" for details):\n\n'))
422 elif ui.verbose:
422 elif ui.verbose:
423 ui.status(_('list of commands:\n\n'))
423 ui.status(_('list of commands:\n\n'))
424 else:
424 else:
425 ui.status(_('list of commands (use "hg help -v" '
425 ui.status(_('list of commands (use "hg help -v" '
426 'to show aliases and global options):\n\n'))
426 'to show aliases and global options):\n\n'))
427
427
428 h = {}
428 h = {}
429 cmds = {}
429 cmds = {}
430 for c, e in table.items():
430 for c, e in table.items():
431 f = c.split("|")[0]
431 f = c.split("|")[0]
432 if cmd == "shortlist" and not f.startswith("^"):
432 if cmd == "shortlist" and not f.startswith("^"):
433 continue
433 continue
434 f = f.lstrip("^")
434 f = f.lstrip("^")
435 if not ui.debugflag and f.startswith("debug"):
435 if not ui.debugflag and f.startswith("debug"):
436 continue
436 continue
437 d = ""
437 d = ""
438 if e[0].__doc__:
438 if e[0].__doc__:
439 d = e[0].__doc__.splitlines(0)[0].rstrip()
439 d = e[0].__doc__.splitlines(0)[0].rstrip()
440 h[f] = d
440 h[f] = d
441 cmds[f]=c.lstrip("^")
441 cmds[f]=c.lstrip("^")
442
442
443 fns = h.keys()
443 fns = h.keys()
444 fns.sort()
444 fns.sort()
445 m = max(map(len, fns))
445 m = max(map(len, fns))
446 for f in fns:
446 for f in fns:
447 if ui.verbose:
447 if ui.verbose:
448 commands = cmds[f].replace("|",", ")
448 commands = cmds[f].replace("|",", ")
449 ui.write(" %s:\n %s\n"%(commands,h[f]))
449 ui.write(" %s:\n %s\n"%(commands,h[f]))
450 else:
450 else:
451 ui.write(' %-*s %s\n' % (m, f, h[f]))
451 ui.write(' %-*s %s\n' % (m, f, h[f]))
452
452
453 # global options
453 # global options
454 if ui.verbose:
454 if ui.verbose:
455 option_lists.append(("global options", globalopts))
455 option_lists.append(("global options", globalopts))
456
456
457 # list all option lists
457 # list all option lists
458 opt_output = []
458 opt_output = []
459 for title, options in option_lists:
459 for title, options in option_lists:
460 opt_output.append(("\n%s:\n" % title, None))
460 opt_output.append(("\n%s:\n" % title, None))
461 for shortopt, longopt, default, desc in options:
461 for shortopt, longopt, default, desc in options:
462 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
462 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
463 longopt and " --%s" % longopt),
463 longopt and " --%s" % longopt),
464 "%s%s" % (desc,
464 "%s%s" % (desc,
465 default and _(" (default: %s)") % default
465 default and _(" (default: %s)") % default
466 or "")))
466 or "")))
467
467
468 if opt_output:
468 if opt_output:
469 opts_len = max([len(line[0]) for line in opt_output if line[1]])
469 opts_len = max([len(line[0]) for line in opt_output if line[1]])
470 for first, second in opt_output:
470 for first, second in opt_output:
471 if second:
471 if second:
472 ui.write(" %-*s %s\n" % (opts_len, first, second))
472 ui.write(" %-*s %s\n" % (opts_len, first, second))
473 else:
473 else:
474 ui.write("%s\n" % first)
474 ui.write("%s\n" % first)
475
475
476 # Commands start here, listed alphabetically
476 # Commands start here, listed alphabetically
477
477
478 def add(ui, repo, *pats, **opts):
478 def add(ui, repo, *pats, **opts):
479 '''add the specified files on the next commit'''
479 """add the specified files on the next commit
480
481 Schedule files to be version controlled and added to the repository.
482
483 The files will be added to the repository at the next commit.
484
485 If no names are given, add all files in the current directory and
486 its subdirectories.
487 """
488
480 names = []
489 names = []
481 for src, abs, rel, exact in walk(repo, pats, opts):
490 for src, abs, rel, exact in walk(repo, pats, opts):
482 if exact:
491 if exact:
483 if ui.verbose: ui.status(_('adding %s\n') % rel)
492 if ui.verbose: ui.status(_('adding %s\n') % rel)
484 names.append(abs)
493 names.append(abs)
485 elif repo.dirstate.state(abs) == '?':
494 elif repo.dirstate.state(abs) == '?':
486 ui.status(_('adding %s\n') % rel)
495 ui.status(_('adding %s\n') % rel)
487 names.append(abs)
496 names.append(abs)
488 repo.add(names)
497 repo.add(names)
489
498
490 def addremove(ui, repo, *pats, **opts):
499 def addremove(ui, repo, *pats, **opts):
491 """add all new files, delete all missing files"""
500 """add all new files, delete all missing files
501
502 Add all new files and remove all missing files from the repository.
503
504 New files are ignored if they match any of the patterns in .hgignore. As
505 with add, these changes take effect at the next commit.
506 """
492 add, remove = [], []
507 add, remove = [], []
493 for src, abs, rel, exact in walk(repo, pats, opts):
508 for src, abs, rel, exact in walk(repo, pats, opts):
494 if src == 'f' and repo.dirstate.state(abs) == '?':
509 if src == 'f' and repo.dirstate.state(abs) == '?':
495 add.append(abs)
510 add.append(abs)
496 if ui.verbose or not exact:
511 if ui.verbose or not exact:
497 ui.status(_('adding %s\n') % rel)
512 ui.status(_('adding %s\n') % rel)
498 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
513 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
499 remove.append(abs)
514 remove.append(abs)
500 if ui.verbose or not exact:
515 if ui.verbose or not exact:
501 ui.status(_('removing %s\n') % rel)
516 ui.status(_('removing %s\n') % rel)
502 repo.add(add)
517 repo.add(add)
503 repo.remove(remove)
518 repo.remove(remove)
504
519
505 def annotate(ui, repo, *pats, **opts):
520 def annotate(ui, repo, *pats, **opts):
506 """show changeset information per file line"""
521 """show changeset information per file line
522
523 List changes in files, showing the revision id responsible for each line
524
525 This command is useful to discover who did a change or when a change took
526 place.
527
528 Without the -a option, annotate will avoid processing files it
529 detects as binary. With -a, annotate will generate an annotation
530 anyway, probably with undesirable results.
531 """
507 def getnode(rev):
532 def getnode(rev):
508 return short(repo.changelog.node(rev))
533 return short(repo.changelog.node(rev))
509
534
510 ucache = {}
535 ucache = {}
511 def getname(rev):
536 def getname(rev):
512 cl = repo.changelog.read(repo.changelog.node(rev))
537 cl = repo.changelog.read(repo.changelog.node(rev))
513 return trimuser(ui, cl[1], rev, ucache)
538 return trimuser(ui, cl[1], rev, ucache)
514
539
515 if not pats:
540 if not pats:
516 raise util.Abort(_('at least one file name or pattern required'))
541 raise util.Abort(_('at least one file name or pattern required'))
517
542
518 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
543 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
519 if not opts['user'] and not opts['changeset']:
544 if not opts['user'] and not opts['changeset']:
520 opts['number'] = 1
545 opts['number'] = 1
521
546
522 if opts['rev']:
547 if opts['rev']:
523 node = repo.changelog.lookup(opts['rev'])
548 node = repo.changelog.lookup(opts['rev'])
524 else:
549 else:
525 node = repo.dirstate.parents()[0]
550 node = repo.dirstate.parents()[0]
526 change = repo.changelog.read(node)
551 change = repo.changelog.read(node)
527 mmap = repo.manifest.read(change[0])
552 mmap = repo.manifest.read(change[0])
528
553
529 for src, abs, rel, exact in walk(repo, pats, opts):
554 for src, abs, rel, exact in walk(repo, pats, opts):
530 if abs not in mmap:
555 if abs not in mmap:
531 ui.warn(_("warning: %s is not in the repository!\n") % rel)
556 ui.warn(_("warning: %s is not in the repository!\n") % rel)
532 continue
557 continue
533
558
534 f = repo.file(abs)
559 f = repo.file(abs)
535 if not opts['text'] and util.binary(f.read(mmap[abs])):
560 if not opts['text'] and util.binary(f.read(mmap[abs])):
536 ui.write(_("%s: binary file\n") % rel)
561 ui.write(_("%s: binary file\n") % rel)
537 continue
562 continue
538
563
539 lines = f.annotate(mmap[abs])
564 lines = f.annotate(mmap[abs])
540 pieces = []
565 pieces = []
541
566
542 for o, f in opmap:
567 for o, f in opmap:
543 if opts[o]:
568 if opts[o]:
544 l = [f(n) for n, dummy in lines]
569 l = [f(n) for n, dummy in lines]
545 if l:
570 if l:
546 m = max(map(len, l))
571 m = max(map(len, l))
547 pieces.append(["%*s" % (m, x) for x in l])
572 pieces.append(["%*s" % (m, x) for x in l])
548
573
549 if pieces:
574 if pieces:
550 for p, l in zip(zip(*pieces), lines):
575 for p, l in zip(zip(*pieces), lines):
551 ui.write("%s: %s" % (" ".join(p), l[1]))
576 ui.write("%s: %s" % (" ".join(p), l[1]))
552
577
553 def bundle(ui, repo, fname, dest="default-push", **opts):
578 def bundle(ui, repo, fname, dest="default-push", **opts):
554 """create a changegroup file"""
579 """create a changegroup file
580
581 Generate a compressed changegroup file collecting all changesets
582 not found in the other repository.
583
584 This file can then be transferred using conventional means and
585 applied to another repository with the unbundle command. This is
586 useful when native push and pull are not available or when
587 exporting an entire repository is undesirable. The standard file
588 extension is ".hg".
589
590 Unlike import/export, this exactly preserves all changeset
591 contents including permissions, rename data, and revision history.
592 """
555 f = open(fname, "wb")
593 f = open(fname, "wb")
556 dest = ui.expandpath(dest)
594 dest = ui.expandpath(dest)
557 other = hg.repository(ui, dest)
595 other = hg.repository(ui, dest)
558 o = repo.findoutgoing(other)
596 o = repo.findoutgoing(other)
559 cg = repo.changegroup(o)
597 cg = repo.changegroup(o)
560
598
561 try:
599 try:
562 f.write("HG10")
600 f.write("HG10")
563 z = bz2.BZ2Compressor(9)
601 z = bz2.BZ2Compressor(9)
564 while 1:
602 while 1:
565 chunk = cg.read(4096)
603 chunk = cg.read(4096)
566 if not chunk:
604 if not chunk:
567 break
605 break
568 f.write(z.compress(chunk))
606 f.write(z.compress(chunk))
569 f.write(z.flush())
607 f.write(z.flush())
570 except:
608 except:
571 os.unlink(fname)
609 os.unlink(fname)
572 raise
610 raise
573
611
574 def cat(ui, repo, file1, *pats, **opts):
612 def cat(ui, repo, file1, *pats, **opts):
575 """output the latest or given revisions of files"""
613 """output the latest or given revisions of files
614
615 Print the specified files as they were at the given revision.
616 If no revision is given then the tip is used.
617
618 Output may be to a file, in which case the name of the file is
619 given using a format string. The formatting rules are the same as
620 for the export command, with the following additions:
621
622 %s basename of file being printed
623 %d dirname of file being printed, or '.' if in repo root
624 %p root-relative path name of file being printed
625 """
576 mf = {}
626 mf = {}
577 if opts['rev']:
627 if opts['rev']:
578 change = repo.changelog.read(repo.lookup(opts['rev']))
628 change = repo.changelog.read(repo.lookup(opts['rev']))
579 mf = repo.manifest.read(change[0])
629 mf = repo.manifest.read(change[0])
580 for src, abs, rel, exact in walk(repo, (file1,) + pats, opts):
630 for src, abs, rel, exact in walk(repo, (file1,) + pats, opts):
581 r = repo.file(abs)
631 r = repo.file(abs)
582 if opts['rev']:
632 if opts['rev']:
583 try:
633 try:
584 n = mf[abs]
634 n = mf[abs]
585 except (hg.RepoError, KeyError):
635 except (hg.RepoError, KeyError):
586 try:
636 try:
587 n = r.lookup(rev)
637 n = r.lookup(rev)
588 except KeyError, inst:
638 except KeyError, inst:
589 raise util.Abort(_('cannot find file %s in rev %s'), rel, rev)
639 raise util.Abort(_('cannot find file %s in rev %s'), rel, rev)
590 else:
640 else:
591 n = r.tip()
641 n = r.tip()
592 fp = make_file(repo, r, opts['output'], node=n, pathname=abs)
642 fp = make_file(repo, r, opts['output'], node=n, pathname=abs)
593 fp.write(r.read(n))
643 fp.write(r.read(n))
594
644
595 def clone(ui, source, dest=None, **opts):
645 def clone(ui, source, dest=None, **opts):
596 """make a copy of an existing repository"""
646 """make a copy of an existing repository
647
648 Create a copy of an existing repository in a new directory.
649
650 If no destination directory name is specified, it defaults to the
651 basename of the source.
652
653 The location of the source is added to the new repository's
654 .hg/hgrc file, as the default to be used for future pulls.
655
656 For efficiency, hardlinks are used for cloning whenever the source
657 and destination are on the same filesystem. Some filesystems,
658 such as AFS, implement hardlinking incorrectly, but do not report
659 errors. In these cases, use the --pull option to avoid
660 hardlinking.
661 """
597 if dest is None:
662 if dest is None:
598 dest = os.path.basename(os.path.normpath(source))
663 dest = os.path.basename(os.path.normpath(source))
599
664
600 if os.path.exists(dest):
665 if os.path.exists(dest):
601 raise util.Abort(_("destination '%s' already exists"), dest)
666 raise util.Abort(_("destination '%s' already exists"), dest)
602
667
603 dest = os.path.realpath(dest)
668 dest = os.path.realpath(dest)
604
669
605 class Dircleanup:
670 class Dircleanup:
606 def __init__(self, dir_):
671 def __init__(self, dir_):
607 self.rmtree = shutil.rmtree
672 self.rmtree = shutil.rmtree
608 self.dir_ = dir_
673 self.dir_ = dir_
609 os.mkdir(dir_)
674 os.mkdir(dir_)
610 def close(self):
675 def close(self):
611 self.dir_ = None
676 self.dir_ = None
612 def __del__(self):
677 def __del__(self):
613 if self.dir_:
678 if self.dir_:
614 self.rmtree(self.dir_, True)
679 self.rmtree(self.dir_, True)
615
680
616 if opts['ssh']:
681 if opts['ssh']:
617 ui.setconfig("ui", "ssh", opts['ssh'])
682 ui.setconfig("ui", "ssh", opts['ssh'])
618 if opts['remotecmd']:
683 if opts['remotecmd']:
619 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
684 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
620
685
621 if not os.path.exists(source):
686 if not os.path.exists(source):
622 source = ui.expandpath(source)
687 source = ui.expandpath(source)
623
688
624 d = Dircleanup(dest)
689 d = Dircleanup(dest)
625 abspath = source
690 abspath = source
626 other = hg.repository(ui, source)
691 other = hg.repository(ui, source)
627
692
628 copy = False
693 copy = False
629 if other.dev() != -1:
694 if other.dev() != -1:
630 abspath = os.path.abspath(source)
695 abspath = os.path.abspath(source)
631 if not opts['pull']:
696 if not opts['pull']:
632 copy = True
697 copy = True
633
698
634 if copy:
699 if copy:
635 try:
700 try:
636 # we use a lock here because if we race with commit, we
701 # we use a lock here because if we race with commit, we
637 # can end up with extra data in the cloned revlogs that's
702 # can end up with extra data in the cloned revlogs that's
638 # not pointed to by changesets, thus causing verify to
703 # not pointed to by changesets, thus causing verify to
639 # fail
704 # fail
640 l1 = lock.lock(os.path.join(source, ".hg", "lock"))
705 l1 = lock.lock(os.path.join(source, ".hg", "lock"))
641 except OSError:
706 except OSError:
642 copy = False
707 copy = False
643
708
644 if copy:
709 if copy:
645 # we lock here to avoid premature writing to the target
710 # we lock here to avoid premature writing to the target
646 os.mkdir(os.path.join(dest, ".hg"))
711 os.mkdir(os.path.join(dest, ".hg"))
647 l2 = lock.lock(os.path.join(dest, ".hg", "lock"))
712 l2 = lock.lock(os.path.join(dest, ".hg", "lock"))
648
713
649 files = "data 00manifest.d 00manifest.i 00changelog.d 00changelog.i"
714 files = "data 00manifest.d 00manifest.i 00changelog.d 00changelog.i"
650 for f in files.split():
715 for f in files.split():
651 src = os.path.join(source, ".hg", f)
716 src = os.path.join(source, ".hg", f)
652 dst = os.path.join(dest, ".hg", f)
717 dst = os.path.join(dest, ".hg", f)
653 util.copyfiles(src, dst)
718 util.copyfiles(src, dst)
654
719
655 repo = hg.repository(ui, dest)
720 repo = hg.repository(ui, dest)
656
721
657 else:
722 else:
658 repo = hg.repository(ui, dest, create=1)
723 repo = hg.repository(ui, dest, create=1)
659 repo.pull(other)
724 repo.pull(other)
660
725
661 f = repo.opener("hgrc", "w", text=True)
726 f = repo.opener("hgrc", "w", text=True)
662 f.write("[paths]\n")
727 f.write("[paths]\n")
663 f.write("default = %s\n" % abspath)
728 f.write("default = %s\n" % abspath)
664
729
665 if not opts['noupdate']:
730 if not opts['noupdate']:
666 update(ui, repo)
731 update(ui, repo)
667
732
668 d.close()
733 d.close()
669
734
670 def commit(ui, repo, *pats, **opts):
735 def commit(ui, repo, *pats, **opts):
671 """commit the specified files or all outstanding changes"""
736 """commit the specified files or all outstanding changes
737
738 Commit changes to the given files into the repository.
739
740 If a list of files is omitted, all changes reported by "hg status"
741 from the root of the repository will be commited.
742
743 The HGEDITOR or EDITOR environment variables are used to start an
744 editor to add a commit comment.
745 """
672 if opts['text']:
746 if opts['text']:
673 ui.warn(_("Warning: -t and --text is deprecated,"
747 ui.warn(_("Warning: -t and --text is deprecated,"
674 " please use -m or --message instead.\n"))
748 " please use -m or --message instead.\n"))
675 message = opts['message'] or opts['text']
749 message = opts['message'] or opts['text']
676 logfile = opts['logfile']
750 logfile = opts['logfile']
677
751
678 if message and logfile:
752 if message and logfile:
679 raise util.Abort(_('options --message and --logfile are mutually '
753 raise util.Abort(_('options --message and --logfile are mutually '
680 'exclusive'))
754 'exclusive'))
681 if not message and logfile:
755 if not message and logfile:
682 try:
756 try:
683 if logfile == '-':
757 if logfile == '-':
684 message = sys.stdin.read()
758 message = sys.stdin.read()
685 else:
759 else:
686 message = open(logfile).read()
760 message = open(logfile).read()
687 except IOError, inst:
761 except IOError, inst:
688 raise util.Abort(_("can't read commit message '%s': %s") %
762 raise util.Abort(_("can't read commit message '%s': %s") %
689 (logfile, inst.strerror))
763 (logfile, inst.strerror))
690
764
691 if opts['addremove']:
765 if opts['addremove']:
692 addremove(ui, repo, *pats, **opts)
766 addremove(ui, repo, *pats, **opts)
693 cwd = repo.getcwd()
767 cwd = repo.getcwd()
694 if not pats and cwd:
768 if not pats and cwd:
695 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
769 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
696 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
770 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
697 fns, match, anypats = matchpats(repo, (pats and repo.getcwd()) or '',
771 fns, match, anypats = matchpats(repo, (pats and repo.getcwd()) or '',
698 pats, opts)
772 pats, opts)
699 if pats:
773 if pats:
700 c, a, d, u = repo.changes(files=fns, match=match)
774 c, a, d, u = repo.changes(files=fns, match=match)
701 files = c + a + [fn for fn in d if repo.dirstate.state(fn) == 'r']
775 files = c + a + [fn for fn in d if repo.dirstate.state(fn) == 'r']
702 else:
776 else:
703 files = []
777 files = []
704 try:
778 try:
705 repo.commit(files, message, opts['user'], opts['date'], match)
779 repo.commit(files, message, opts['user'], opts['date'], match)
706 except ValueError, inst:
780 except ValueError, inst:
707 raise util.Abort(str(inst))
781 raise util.Abort(str(inst))
708
782
709 def docopy(ui, repo, pats, opts):
783 def docopy(ui, repo, pats, opts):
710 if not pats:
784 if not pats:
711 raise util.Abort(_('no source or destination specified'))
785 raise util.Abort(_('no source or destination specified'))
712 elif len(pats) == 1:
786 elif len(pats) == 1:
713 raise util.Abort(_('no destination specified'))
787 raise util.Abort(_('no destination specified'))
714 pats = list(pats)
788 pats = list(pats)
715 dest = pats.pop()
789 dest = pats.pop()
716 sources = []
790 sources = []
717
791
718 def okaytocopy(abs, rel, exact):
792 def okaytocopy(abs, rel, exact):
719 reasons = {'?': _('is not managed'),
793 reasons = {'?': _('is not managed'),
720 'a': _('has been marked for add')}
794 'a': _('has been marked for add')}
721 reason = reasons.get(repo.dirstate.state(abs))
795 reason = reasons.get(repo.dirstate.state(abs))
722 if reason:
796 if reason:
723 if exact: ui.warn(_('%s: not copying - file %s\n') % (rel, reason))
797 if exact: ui.warn(_('%s: not copying - file %s\n') % (rel, reason))
724 else:
798 else:
725 return True
799 return True
726
800
727 for src, abs, rel, exact in walk(repo, pats, opts):
801 for src, abs, rel, exact in walk(repo, pats, opts):
728 if okaytocopy(abs, rel, exact):
802 if okaytocopy(abs, rel, exact):
729 sources.append((abs, rel, exact))
803 sources.append((abs, rel, exact))
730 if not sources:
804 if not sources:
731 raise util.Abort(_('no files to copy'))
805 raise util.Abort(_('no files to copy'))
732
806
733 cwd = repo.getcwd()
807 cwd = repo.getcwd()
734 absdest = util.canonpath(repo.root, cwd, dest)
808 absdest = util.canonpath(repo.root, cwd, dest)
735 reldest = util.pathto(cwd, absdest)
809 reldest = util.pathto(cwd, absdest)
736 if os.path.exists(reldest):
810 if os.path.exists(reldest):
737 destisfile = not os.path.isdir(reldest)
811 destisfile = not os.path.isdir(reldest)
738 else:
812 else:
739 destisfile = len(sources) == 1 or repo.dirstate.state(absdest) != '?'
813 destisfile = len(sources) == 1 or repo.dirstate.state(absdest) != '?'
740
814
741 if destisfile:
815 if destisfile:
742 if opts['parents']:
816 if opts['parents']:
743 raise util.Abort(_('with --parents, destination must be a directory'))
817 raise util.Abort(_('with --parents, destination must be a directory'))
744 elif len(sources) > 1:
818 elif len(sources) > 1:
745 raise util.Abort(_('with multiple sources, destination must be a '
819 raise util.Abort(_('with multiple sources, destination must be a '
746 'directory'))
820 'directory'))
747 errs, copied = 0, []
821 errs, copied = 0, []
748 for abs, rel, exact in sources:
822 for abs, rel, exact in sources:
749 if opts['parents']:
823 if opts['parents']:
750 mydest = os.path.join(dest, rel)
824 mydest = os.path.join(dest, rel)
751 elif destisfile:
825 elif destisfile:
752 mydest = reldest
826 mydest = reldest
753 else:
827 else:
754 mydest = os.path.join(dest, os.path.basename(rel))
828 mydest = os.path.join(dest, os.path.basename(rel))
755 myabsdest = util.canonpath(repo.root, cwd, mydest)
829 myabsdest = util.canonpath(repo.root, cwd, mydest)
756 myreldest = util.pathto(cwd, myabsdest)
830 myreldest = util.pathto(cwd, myabsdest)
757 if not opts['force'] and repo.dirstate.state(myabsdest) not in 'a?':
831 if not opts['force'] and repo.dirstate.state(myabsdest) not in 'a?':
758 ui.warn(_('%s: not overwriting - file already managed\n') % myreldest)
832 ui.warn(_('%s: not overwriting - file already managed\n') % myreldest)
759 continue
833 continue
760 mydestdir = os.path.dirname(myreldest) or '.'
834 mydestdir = os.path.dirname(myreldest) or '.'
761 if not opts['after']:
835 if not opts['after']:
762 try:
836 try:
763 if opts['parents']: os.makedirs(mydestdir)
837 if opts['parents']: os.makedirs(mydestdir)
764 elif not destisfile: os.mkdir(mydestdir)
838 elif not destisfile: os.mkdir(mydestdir)
765 except OSError, inst:
839 except OSError, inst:
766 if inst.errno != errno.EEXIST: raise
840 if inst.errno != errno.EEXIST: raise
767 if ui.verbose or not exact:
841 if ui.verbose or not exact:
768 ui.status(_('copying %s to %s\n') % (rel, myreldest))
842 ui.status(_('copying %s to %s\n') % (rel, myreldest))
769 if not opts['after']:
843 if not opts['after']:
770 try:
844 try:
771 shutil.copyfile(rel, myreldest)
845 shutil.copyfile(rel, myreldest)
772 shutil.copymode(rel, myreldest)
846 shutil.copymode(rel, myreldest)
773 except shutil.Error, inst:
847 except shutil.Error, inst:
774 raise util.Abort(str(inst))
848 raise util.Abort(str(inst))
775 except IOError, inst:
849 except IOError, inst:
776 if inst.errno == errno.ENOENT:
850 if inst.errno == errno.ENOENT:
777 ui.warn(_('%s: deleted in working copy\n') % rel)
851 ui.warn(_('%s: deleted in working copy\n') % rel)
778 else:
852 else:
779 ui.warn(_('%s: cannot copy - %s\n') % (rel, inst.strerror))
853 ui.warn(_('%s: cannot copy - %s\n') % (rel, inst.strerror))
780 errs += 1
854 errs += 1
781 continue
855 continue
782 repo.copy(abs, myabsdest)
856 repo.copy(abs, myabsdest)
783 copied.append((abs, rel, exact))
857 copied.append((abs, rel, exact))
784 if errs:
858 if errs:
785 ui.warn(_('(consider using --after)\n'))
859 ui.warn(_('(consider using --after)\n'))
786 return errs, copied
860 return errs, copied
787
861
788 def copy(ui, repo, *pats, **opts):
862 def copy(ui, repo, *pats, **opts):
789 """mark files as copied for the next commit"""
863 """mark files as copied for the next commit
864
865 Mark dest as having copies of source files. If dest is a
866 directory, copies are put in that directory. If dest is a file,
867 there can only be one source.
868
869 By default, this command copies the contents of files as they
870 stand in the working directory. If invoked with --after, the
871 operation is recorded, but no copying is performed.
872
873 This command takes effect in the next commit.
874
875 NOTE: This command should be treated as experimental. While it
876 should properly record copied files, this information is not yet
877 fully used by merge, nor fully reported by log.
878 """
790 errs, copied = docopy(ui, repo, pats, opts)
879 errs, copied = docopy(ui, repo, pats, opts)
791 return errs
880 return errs
792
881
793 def debugancestor(ui, index, rev1, rev2):
882 def debugancestor(ui, index, rev1, rev2):
794 """find the ancestor revision of two revisions in a given index"""
883 """find the ancestor revision of two revisions in a given index"""
795 r = revlog.revlog(file, index, "")
884 r = revlog.revlog(file, index, "")
796 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
885 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
797 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
886 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
798
887
799 def debugcheckstate(ui, repo):
888 def debugcheckstate(ui, repo):
800 """validate the correctness of the current dirstate"""
889 """validate the correctness of the current dirstate"""
801 parent1, parent2 = repo.dirstate.parents()
890 parent1, parent2 = repo.dirstate.parents()
802 repo.dirstate.read()
891 repo.dirstate.read()
803 dc = repo.dirstate.map
892 dc = repo.dirstate.map
804 keys = dc.keys()
893 keys = dc.keys()
805 keys.sort()
894 keys.sort()
806 m1n = repo.changelog.read(parent1)[0]
895 m1n = repo.changelog.read(parent1)[0]
807 m2n = repo.changelog.read(parent2)[0]
896 m2n = repo.changelog.read(parent2)[0]
808 m1 = repo.manifest.read(m1n)
897 m1 = repo.manifest.read(m1n)
809 m2 = repo.manifest.read(m2n)
898 m2 = repo.manifest.read(m2n)
810 errors = 0
899 errors = 0
811 for f in dc:
900 for f in dc:
812 state = repo.dirstate.state(f)
901 state = repo.dirstate.state(f)
813 if state in "nr" and f not in m1:
902 if state in "nr" and f not in m1:
814 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
903 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
815 errors += 1
904 errors += 1
816 if state in "a" and f in m1:
905 if state in "a" and f in m1:
817 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
906 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
818 errors += 1
907 errors += 1
819 if state in "m" and f not in m1 and f not in m2:
908 if state in "m" and f not in m1 and f not in m2:
820 ui.warn(_("%s in state %s, but not in either manifest\n") %
909 ui.warn(_("%s in state %s, but not in either manifest\n") %
821 (f, state))
910 (f, state))
822 errors += 1
911 errors += 1
823 for f in m1:
912 for f in m1:
824 state = repo.dirstate.state(f)
913 state = repo.dirstate.state(f)
825 if state not in "nrm":
914 if state not in "nrm":
826 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
915 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
827 errors += 1
916 errors += 1
828 if errors:
917 if errors:
829 raise util.Abort(_(".hg/dirstate inconsistent with current parent's manifest"))
918 raise util.Abort(_(".hg/dirstate inconsistent with current parent's manifest"))
830
919
831 def debugconfig(ui):
920 def debugconfig(ui):
832 """show combined config settings from all hgrc files"""
921 """show combined config settings from all hgrc files"""
833 try:
922 try:
834 repo = hg.repository(ui)
923 repo = hg.repository(ui)
835 except hg.RepoError:
924 except hg.RepoError:
836 pass
925 pass
837 for section, name, value in ui.walkconfig():
926 for section, name, value in ui.walkconfig():
838 ui.write('%s.%s=%s\n' % (section, name, value))
927 ui.write('%s.%s=%s\n' % (section, name, value))
839
928
840 def debugsetparents(ui, repo, rev1, rev2=None):
929 def debugsetparents(ui, repo, rev1, rev2=None):
841 """
930 """
842 manually set the parents of the current working directory
931 manually set the parents of the current working directory
843
932
844 This is useful for writing repository conversion tools, but should
933 This is useful for writing repository conversion tools, but should
845 be used with care.
934 be used with care.
846 """
935 """
847
936
848 if not rev2:
937 if not rev2:
849 rev2 = hex(nullid)
938 rev2 = hex(nullid)
850
939
851 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
940 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
852
941
853 def debugstate(ui, repo):
942 def debugstate(ui, repo):
854 """show the contents of the current dirstate"""
943 """show the contents of the current dirstate"""
855 repo.dirstate.read()
944 repo.dirstate.read()
856 dc = repo.dirstate.map
945 dc = repo.dirstate.map
857 keys = dc.keys()
946 keys = dc.keys()
858 keys.sort()
947 keys.sort()
859 for file_ in keys:
948 for file_ in keys:
860 ui.write("%c %3o %10d %s %s\n"
949 ui.write("%c %3o %10d %s %s\n"
861 % (dc[file_][0], dc[file_][1] & 0777, dc[file_][2],
950 % (dc[file_][0], dc[file_][1] & 0777, dc[file_][2],
862 time.strftime("%x %X",
951 time.strftime("%x %X",
863 time.localtime(dc[file_][3])), file_))
952 time.localtime(dc[file_][3])), file_))
864 for f in repo.dirstate.copies:
953 for f in repo.dirstate.copies:
865 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copies[f], f))
954 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copies[f], f))
866
955
867 def debugdata(ui, file_, rev):
956 def debugdata(ui, file_, rev):
868 """dump the contents of an data file revision"""
957 """dump the contents of an data file revision"""
869 r = revlog.revlog(file, file_[:-2] + ".i", file_)
958 r = revlog.revlog(file, file_[:-2] + ".i", file_)
870 try:
959 try:
871 ui.write(r.revision(r.lookup(rev)))
960 ui.write(r.revision(r.lookup(rev)))
872 except KeyError:
961 except KeyError:
873 raise util.Abort(_('invalid revision identifier %s'), rev)
962 raise util.Abort(_('invalid revision identifier %s'), rev)
874
963
875 def debugindex(ui, file_):
964 def debugindex(ui, file_):
876 """dump the contents of an index file"""
965 """dump the contents of an index file"""
877 r = revlog.revlog(file, file_, "")
966 r = revlog.revlog(file, file_, "")
878 ui.write(" rev offset length base linkrev" +
967 ui.write(" rev offset length base linkrev" +
879 " nodeid p1 p2\n")
968 " nodeid p1 p2\n")
880 for i in range(r.count()):
969 for i in range(r.count()):
881 e = r.index[i]
970 e = r.index[i]
882 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
971 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
883 i, e[0], e[1], e[2], e[3],
972 i, e[0], e[1], e[2], e[3],
884 short(e[6]), short(e[4]), short(e[5])))
973 short(e[6]), short(e[4]), short(e[5])))
885
974
886 def debugindexdot(ui, file_):
975 def debugindexdot(ui, file_):
887 """dump an index DAG as a .dot file"""
976 """dump an index DAG as a .dot file"""
888 r = revlog.revlog(file, file_, "")
977 r = revlog.revlog(file, file_, "")
889 ui.write("digraph G {\n")
978 ui.write("digraph G {\n")
890 for i in range(r.count()):
979 for i in range(r.count()):
891 e = r.index[i]
980 e = r.index[i]
892 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i))
981 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i))
893 if e[5] != nullid:
982 if e[5] != nullid:
894 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i))
983 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i))
895 ui.write("}\n")
984 ui.write("}\n")
896
985
897 def debugrename(ui, repo, file, rev=None):
986 def debugrename(ui, repo, file, rev=None):
898 """dump rename information"""
987 """dump rename information"""
899 r = repo.file(relpath(repo, [file])[0])
988 r = repo.file(relpath(repo, [file])[0])
900 if rev:
989 if rev:
901 try:
990 try:
902 # assume all revision numbers are for changesets
991 # assume all revision numbers are for changesets
903 n = repo.lookup(rev)
992 n = repo.lookup(rev)
904 change = repo.changelog.read(n)
993 change = repo.changelog.read(n)
905 m = repo.manifest.read(change[0])
994 m = repo.manifest.read(change[0])
906 n = m[relpath(repo, [file])[0]]
995 n = m[relpath(repo, [file])[0]]
907 except hg.RepoError, KeyError:
996 except hg.RepoError, KeyError:
908 n = r.lookup(rev)
997 n = r.lookup(rev)
909 else:
998 else:
910 n = r.tip()
999 n = r.tip()
911 m = r.renamed(n)
1000 m = r.renamed(n)
912 if m:
1001 if m:
913 ui.write(_("renamed from %s:%s\n") % (m[0], hex(m[1])))
1002 ui.write(_("renamed from %s:%s\n") % (m[0], hex(m[1])))
914 else:
1003 else:
915 ui.write(_("not renamed\n"))
1004 ui.write(_("not renamed\n"))
916
1005
917 def debugwalk(ui, repo, *pats, **opts):
1006 def debugwalk(ui, repo, *pats, **opts):
918 """show how files match on given patterns"""
1007 """show how files match on given patterns"""
919 items = list(walk(repo, pats, opts))
1008 items = list(walk(repo, pats, opts))
920 if not items:
1009 if not items:
921 return
1010 return
922 fmt = '%%s %%-%ds %%-%ds %%s' % (
1011 fmt = '%%s %%-%ds %%-%ds %%s' % (
923 max([len(abs) for (src, abs, rel, exact) in items]),
1012 max([len(abs) for (src, abs, rel, exact) in items]),
924 max([len(rel) for (src, abs, rel, exact) in items]))
1013 max([len(rel) for (src, abs, rel, exact) in items]))
925 for src, abs, rel, exact in items:
1014 for src, abs, rel, exact in items:
926 line = fmt % (src, abs, rel, exact and 'exact' or '')
1015 line = fmt % (src, abs, rel, exact and 'exact' or '')
927 ui.write("%s\n" % line.rstrip())
1016 ui.write("%s\n" % line.rstrip())
928
1017
929 def diff(ui, repo, *pats, **opts):
1018 def diff(ui, repo, *pats, **opts):
930 """diff working directory (or selected files)"""
1019 """diff working directory (or selected files)
1020
1021 Show differences between revisions for the specified files.
1022
1023 Differences between files are shown using the unified diff format.
1024
1025 When two revision arguments are given, then changes are shown
1026 between those revisions. If only one revision is specified then
1027 that revision is compared to the working directory, and, when no
1028 revisions are specified, the working directory files are compared
1029 to its parent.
1030
1031 Without the -a option, diff will avoid generating diffs of files
1032 it detects as binary. With -a, diff will generate a diff anyway,
1033 probably with undesirable results.
1034 """
931 node1, node2 = None, None
1035 node1, node2 = None, None
932 revs = [repo.lookup(x) for x in opts['rev']]
1036 revs = [repo.lookup(x) for x in opts['rev']]
933
1037
934 if len(revs) > 0:
1038 if len(revs) > 0:
935 node1 = revs[0]
1039 node1 = revs[0]
936 if len(revs) > 1:
1040 if len(revs) > 1:
937 node2 = revs[1]
1041 node2 = revs[1]
938 if len(revs) > 2:
1042 if len(revs) > 2:
939 raise util.Abort(_("too many revisions to diff"))
1043 raise util.Abort(_("too many revisions to diff"))
940
1044
941 fns, matchfn, anypats = matchpats(repo, repo.getcwd(), pats, opts)
1045 fns, matchfn, anypats = matchpats(repo, repo.getcwd(), pats, opts)
942
1046
943 dodiff(sys.stdout, ui, repo, node1, node2, fns, match=matchfn,
1047 dodiff(sys.stdout, ui, repo, node1, node2, fns, match=matchfn,
944 text=opts['text'])
1048 text=opts['text'])
945
1049
946 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
1050 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
947 node = repo.lookup(changeset)
1051 node = repo.lookup(changeset)
948 prev, other = repo.changelog.parents(node)
1052 prev, other = repo.changelog.parents(node)
949 change = repo.changelog.read(node)
1053 change = repo.changelog.read(node)
950
1054
951 fp = make_file(repo, repo.changelog, opts['output'],
1055 fp = make_file(repo, repo.changelog, opts['output'],
952 node=node, total=total, seqno=seqno,
1056 node=node, total=total, seqno=seqno,
953 revwidth=revwidth)
1057 revwidth=revwidth)
954 if fp != sys.stdout:
1058 if fp != sys.stdout:
955 ui.note("%s\n" % fp.name)
1059 ui.note("%s\n" % fp.name)
956
1060
957 fp.write("# HG changeset patch\n")
1061 fp.write("# HG changeset patch\n")
958 fp.write("# User %s\n" % change[1])
1062 fp.write("# User %s\n" % change[1])
959 fp.write("# Node ID %s\n" % hex(node))
1063 fp.write("# Node ID %s\n" % hex(node))
960 fp.write("# Parent %s\n" % hex(prev))
1064 fp.write("# Parent %s\n" % hex(prev))
961 if other != nullid:
1065 if other != nullid:
962 fp.write("# Parent %s\n" % hex(other))
1066 fp.write("# Parent %s\n" % hex(other))
963 fp.write(change[4].rstrip())
1067 fp.write(change[4].rstrip())
964 fp.write("\n\n")
1068 fp.write("\n\n")
965
1069
966 dodiff(fp, ui, repo, prev, node, text=opts['text'])
1070 dodiff(fp, ui, repo, prev, node, text=opts['text'])
967 if fp != sys.stdout:
1071 if fp != sys.stdout:
968 fp.close()
1072 fp.close()
969
1073
970 def export(ui, repo, *changesets, **opts):
1074 def export(ui, repo, *changesets, **opts):
971 """dump the header and diffs for one or more changesets"""
1075 """dump the header and diffs for one or more changesets
1076
1077 Print the changeset header and diffs for one or more revisions.
1078
1079 The information shown in the changeset header is: author,
1080 changeset hash, parent and commit comment.
1081
1082 Output may be to a file, in which case the name of the file is
1083 given using a format string. The formatting rules are as follows:
1084
1085 %% literal "%" character
1086 %H changeset hash (40 bytes of hexadecimal)
1087 %N number of patches being generated
1088 %R changeset revision number
1089 %b basename of the exporting repository
1090 %h short-form changeset hash (12 bytes of hexadecimal)
1091 %n zero-padded sequence number, starting at 1
1092 %r zero-padded changeset revision number
1093
1094 Without the -a option, export will avoid generating diffs of files
1095 it detects as binary. With -a, export will generate a diff anyway,
1096 probably with undesirable results.
1097 """
972 if not changesets:
1098 if not changesets:
973 raise util.Abort(_("export requires at least one changeset"))
1099 raise util.Abort(_("export requires at least one changeset"))
974 seqno = 0
1100 seqno = 0
975 revs = list(revrange(ui, repo, changesets))
1101 revs = list(revrange(ui, repo, changesets))
976 total = len(revs)
1102 total = len(revs)
977 revwidth = max(map(len, revs))
1103 revwidth = max(map(len, revs))
978 ui.note(len(revs) > 1 and _("Exporting patches:\n") or _("Exporting patch:\n"))
1104 ui.note(len(revs) > 1 and _("Exporting patches:\n") or _("Exporting patch:\n"))
979 for cset in revs:
1105 for cset in revs:
980 seqno += 1
1106 seqno += 1
981 doexport(ui, repo, cset, seqno, total, revwidth, opts)
1107 doexport(ui, repo, cset, seqno, total, revwidth, opts)
982
1108
983 def forget(ui, repo, *pats, **opts):
1109 def forget(ui, repo, *pats, **opts):
984 """don't add the specified files on the next commit"""
1110 """don't add the specified files on the next commit
1111
1112 Undo an 'hg add' scheduled for the next commit.
1113 """
985 forget = []
1114 forget = []
986 for src, abs, rel, exact in walk(repo, pats, opts):
1115 for src, abs, rel, exact in walk(repo, pats, opts):
987 if repo.dirstate.state(abs) == 'a':
1116 if repo.dirstate.state(abs) == 'a':
988 forget.append(abs)
1117 forget.append(abs)
989 if ui.verbose or not exact:
1118 if ui.verbose or not exact:
990 ui.status(_('forgetting %s\n') % rel)
1119 ui.status(_('forgetting %s\n') % rel)
991 repo.forget(forget)
1120 repo.forget(forget)
992
1121
993 def grep(ui, repo, pattern, *pats, **opts):
1122 def grep(ui, repo, pattern, *pats, **opts):
994 """search for a pattern in specified files and revisions"""
1123 """search for a pattern in specified files and revisions
1124
1125 Search revisions of files for a regular expression.
1126
1127 This command behaves differently than Unix grep. It only accepts
1128 Python/Perl regexps. It searches repository history, not the
1129 working directory. It always prints the revision number in which
1130 a match appears.
1131
1132 By default, grep only prints output for the first revision of a
1133 file in which it finds a match. To get it to print every revision
1134 that contains a change in match status ("-" for a match that
1135 becomes a non-match, or "+" for a non-match that becomes a match),
1136 use the --all flag.
1137 """
995 reflags = 0
1138 reflags = 0
996 if opts['ignore_case']:
1139 if opts['ignore_case']:
997 reflags |= re.I
1140 reflags |= re.I
998 regexp = re.compile(pattern, reflags)
1141 regexp = re.compile(pattern, reflags)
999 sep, eol = ':', '\n'
1142 sep, eol = ':', '\n'
1000 if opts['print0']:
1143 if opts['print0']:
1001 sep = eol = '\0'
1144 sep = eol = '\0'
1002
1145
1003 fcache = {}
1146 fcache = {}
1004 def getfile(fn):
1147 def getfile(fn):
1005 if fn not in fcache:
1148 if fn not in fcache:
1006 fcache[fn] = repo.file(fn)
1149 fcache[fn] = repo.file(fn)
1007 return fcache[fn]
1150 return fcache[fn]
1008
1151
1009 def matchlines(body):
1152 def matchlines(body):
1010 begin = 0
1153 begin = 0
1011 linenum = 0
1154 linenum = 0
1012 while True:
1155 while True:
1013 match = regexp.search(body, begin)
1156 match = regexp.search(body, begin)
1014 if not match:
1157 if not match:
1015 break
1158 break
1016 mstart, mend = match.span()
1159 mstart, mend = match.span()
1017 linenum += body.count('\n', begin, mstart) + 1
1160 linenum += body.count('\n', begin, mstart) + 1
1018 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1161 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1019 lend = body.find('\n', mend)
1162 lend = body.find('\n', mend)
1020 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1163 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1021 begin = lend + 1
1164 begin = lend + 1
1022
1165
1023 class linestate:
1166 class linestate:
1024 def __init__(self, line, linenum, colstart, colend):
1167 def __init__(self, line, linenum, colstart, colend):
1025 self.line = line
1168 self.line = line
1026 self.linenum = linenum
1169 self.linenum = linenum
1027 self.colstart = colstart
1170 self.colstart = colstart
1028 self.colend = colend
1171 self.colend = colend
1029 def __eq__(self, other):
1172 def __eq__(self, other):
1030 return self.line == other.line
1173 return self.line == other.line
1031 def __hash__(self):
1174 def __hash__(self):
1032 return hash(self.line)
1175 return hash(self.line)
1033
1176
1034 matches = {}
1177 matches = {}
1035 def grepbody(fn, rev, body):
1178 def grepbody(fn, rev, body):
1036 matches[rev].setdefault(fn, {})
1179 matches[rev].setdefault(fn, {})
1037 m = matches[rev][fn]
1180 m = matches[rev][fn]
1038 for lnum, cstart, cend, line in matchlines(body):
1181 for lnum, cstart, cend, line in matchlines(body):
1039 s = linestate(line, lnum, cstart, cend)
1182 s = linestate(line, lnum, cstart, cend)
1040 m[s] = s
1183 m[s] = s
1041
1184
1042 prev = {}
1185 prev = {}
1043 ucache = {}
1186 ucache = {}
1044 def display(fn, rev, states, prevstates):
1187 def display(fn, rev, states, prevstates):
1045 diff = list(sets.Set(states).symmetric_difference(sets.Set(prevstates)))
1188 diff = list(sets.Set(states).symmetric_difference(sets.Set(prevstates)))
1046 diff.sort(lambda x, y: cmp(x.linenum, y.linenum))
1189 diff.sort(lambda x, y: cmp(x.linenum, y.linenum))
1047 counts = {'-': 0, '+': 0}
1190 counts = {'-': 0, '+': 0}
1048 filerevmatches = {}
1191 filerevmatches = {}
1049 for l in diff:
1192 for l in diff:
1050 if incrementing or not opts['all']:
1193 if incrementing or not opts['all']:
1051 change = ((l in prevstates) and '-') or '+'
1194 change = ((l in prevstates) and '-') or '+'
1052 r = rev
1195 r = rev
1053 else:
1196 else:
1054 change = ((l in states) and '-') or '+'
1197 change = ((l in states) and '-') or '+'
1055 r = prev[fn]
1198 r = prev[fn]
1056 cols = [fn, str(rev)]
1199 cols = [fn, str(rev)]
1057 if opts['line_number']: cols.append(str(l.linenum))
1200 if opts['line_number']: cols.append(str(l.linenum))
1058 if opts['all']: cols.append(change)
1201 if opts['all']: cols.append(change)
1059 if opts['user']: cols.append(trimuser(ui, getchange(rev)[1], rev,
1202 if opts['user']: cols.append(trimuser(ui, getchange(rev)[1], rev,
1060 ucache))
1203 ucache))
1061 if opts['files_with_matches']:
1204 if opts['files_with_matches']:
1062 c = (fn, rev)
1205 c = (fn, rev)
1063 if c in filerevmatches: continue
1206 if c in filerevmatches: continue
1064 filerevmatches[c] = 1
1207 filerevmatches[c] = 1
1065 else:
1208 else:
1066 cols.append(l.line)
1209 cols.append(l.line)
1067 ui.write(sep.join(cols), eol)
1210 ui.write(sep.join(cols), eol)
1068 counts[change] += 1
1211 counts[change] += 1
1069 return counts['+'], counts['-']
1212 return counts['+'], counts['-']
1070
1213
1071 fstate = {}
1214 fstate = {}
1072 skip = {}
1215 skip = {}
1073 changeiter, getchange = walkchangerevs(ui, repo, repo.getcwd(), pats, opts)
1216 changeiter, getchange = walkchangerevs(ui, repo, repo.getcwd(), pats, opts)
1074 count = 0
1217 count = 0
1075 incrementing = False
1218 incrementing = False
1076 for st, rev, fns in changeiter:
1219 for st, rev, fns in changeiter:
1077 if st == 'window':
1220 if st == 'window':
1078 incrementing = rev
1221 incrementing = rev
1079 matches.clear()
1222 matches.clear()
1080 elif st == 'add':
1223 elif st == 'add':
1081 change = repo.changelog.read(repo.lookup(str(rev)))
1224 change = repo.changelog.read(repo.lookup(str(rev)))
1082 mf = repo.manifest.read(change[0])
1225 mf = repo.manifest.read(change[0])
1083 matches[rev] = {}
1226 matches[rev] = {}
1084 for fn in fns:
1227 for fn in fns:
1085 if fn in skip: continue
1228 if fn in skip: continue
1086 fstate.setdefault(fn, {})
1229 fstate.setdefault(fn, {})
1087 try:
1230 try:
1088 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1231 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1089 except KeyError:
1232 except KeyError:
1090 pass
1233 pass
1091 elif st == 'iter':
1234 elif st == 'iter':
1092 states = matches[rev].items()
1235 states = matches[rev].items()
1093 states.sort()
1236 states.sort()
1094 for fn, m in states:
1237 for fn, m in states:
1095 if fn in skip: continue
1238 if fn in skip: continue
1096 if incrementing or not opts['all'] or fstate[fn]:
1239 if incrementing or not opts['all'] or fstate[fn]:
1097 pos, neg = display(fn, rev, m, fstate[fn])
1240 pos, neg = display(fn, rev, m, fstate[fn])
1098 count += pos + neg
1241 count += pos + neg
1099 if pos and not opts['all']:
1242 if pos and not opts['all']:
1100 skip[fn] = True
1243 skip[fn] = True
1101 fstate[fn] = m
1244 fstate[fn] = m
1102 prev[fn] = rev
1245 prev[fn] = rev
1103
1246
1104 if not incrementing:
1247 if not incrementing:
1105 fstate = fstate.items()
1248 fstate = fstate.items()
1106 fstate.sort()
1249 fstate.sort()
1107 for fn, state in fstate:
1250 for fn, state in fstate:
1108 if fn in skip: continue
1251 if fn in skip: continue
1109 display(fn, rev, {}, state)
1252 display(fn, rev, {}, state)
1110 return (count == 0 and 1) or 0
1253 return (count == 0 and 1) or 0
1111
1254
1112 def heads(ui, repo, **opts):
1255 def heads(ui, repo, **opts):
1113 """show current repository heads"""
1256 """show current repository heads
1257
1258 Show all repository head changesets.
1259
1260 Repository "heads" are changesets that don't have children
1261 changesets. They are where development generally takes place and
1262 are the usual targets for update and merge operations.
1263 """
1114 heads = repo.changelog.heads()
1264 heads = repo.changelog.heads()
1115 br = None
1265 br = None
1116 if opts['branches']:
1266 if opts['branches']:
1117 br = repo.branchlookup(heads)
1267 br = repo.branchlookup(heads)
1118 for n in repo.changelog.heads():
1268 for n in repo.changelog.heads():
1119 show_changeset(ui, repo, changenode=n, brinfo=br)
1269 show_changeset(ui, repo, changenode=n, brinfo=br)
1120
1270
1121 def identify(ui, repo):
1271 def identify(ui, repo):
1122 """print information about the working copy"""
1272 """print information about the working copy
1273 Print a short summary of the current state of the repo.
1274
1275 This summary identifies the repository state using one or two parent
1276 hash identifiers, followed by a "+" if there are uncommitted changes
1277 in the working directory, followed by a list of tags for this revision.
1278 """
1123 parents = [p for p in repo.dirstate.parents() if p != nullid]
1279 parents = [p for p in repo.dirstate.parents() if p != nullid]
1124 if not parents:
1280 if not parents:
1125 ui.write(_("unknown\n"))
1281 ui.write(_("unknown\n"))
1126 return
1282 return
1127
1283
1128 hexfunc = ui.verbose and hex or short
1284 hexfunc = ui.verbose and hex or short
1129 (c, a, d, u) = repo.changes()
1285 (c, a, d, u) = repo.changes()
1130 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
1286 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
1131 (c or a or d) and "+" or "")]
1287 (c or a or d) and "+" or "")]
1132
1288
1133 if not ui.quiet:
1289 if not ui.quiet:
1134 # multiple tags for a single parent separated by '/'
1290 # multiple tags for a single parent separated by '/'
1135 parenttags = ['/'.join(tags)
1291 parenttags = ['/'.join(tags)
1136 for tags in map(repo.nodetags, parents) if tags]
1292 for tags in map(repo.nodetags, parents) if tags]
1137 # tags for multiple parents separated by ' + '
1293 # tags for multiple parents separated by ' + '
1138 if parenttags:
1294 if parenttags:
1139 output.append(' + '.join(parenttags))
1295 output.append(' + '.join(parenttags))
1140
1296
1141 ui.write("%s\n" % ' '.join(output))
1297 ui.write("%s\n" % ' '.join(output))
1142
1298
1143 def import_(ui, repo, patch1, *patches, **opts):
1299 def import_(ui, repo, patch1, *patches, **opts):
1144 """import an ordered set of patches"""
1300 """import an ordered set of patches
1301
1302 Import a list of patches and commit them individually.
1303
1304 If there are outstanding changes in the working directory, import
1305 will abort unless given the -f flag.
1306
1307 If a patch looks like a mail message (its first line starts with
1308 "From " or looks like an RFC822 header), it will not be applied
1309 unless the -f option is used. The importer neither parses nor
1310 discards mail headers, so use -f only to override the "mailness"
1311 safety check, not to import a real mail message.
1312 """
1145 patches = (patch1,) + patches
1313 patches = (patch1,) + patches
1146
1314
1147 if not opts['force']:
1315 if not opts['force']:
1148 (c, a, d, u) = repo.changes()
1316 (c, a, d, u) = repo.changes()
1149 if c or a or d:
1317 if c or a or d:
1150 raise util.Abort(_("outstanding uncommitted changes"))
1318 raise util.Abort(_("outstanding uncommitted changes"))
1151
1319
1152 d = opts["base"]
1320 d = opts["base"]
1153 strip = opts["strip"]
1321 strip = opts["strip"]
1154
1322
1155 mailre = re.compile(r'(?:From |[\w-]+:)')
1323 mailre = re.compile(r'(?:From |[\w-]+:)')
1156
1324
1157 # attempt to detect the start of a patch
1325 # attempt to detect the start of a patch
1158 # (this heuristic is borrowed from quilt)
1326 # (this heuristic is borrowed from quilt)
1159 diffre = re.compile(r'(?:Index:[ \t]|diff[ \t]|RCS file: |' +
1327 diffre = re.compile(r'(?:Index:[ \t]|diff[ \t]|RCS file: |' +
1160 'retrieving revision [0-9]+(\.[0-9]+)*$|' +
1328 'retrieving revision [0-9]+(\.[0-9]+)*$|' +
1161 '(---|\*\*\*)[ \t])')
1329 '(---|\*\*\*)[ \t])')
1162
1330
1163 for patch in patches:
1331 for patch in patches:
1164 ui.status(_("applying %s\n") % patch)
1332 ui.status(_("applying %s\n") % patch)
1165 pf = os.path.join(d, patch)
1333 pf = os.path.join(d, patch)
1166
1334
1167 message = []
1335 message = []
1168 user = None
1336 user = None
1169 hgpatch = False
1337 hgpatch = False
1170 for line in file(pf):
1338 for line in file(pf):
1171 line = line.rstrip()
1339 line = line.rstrip()
1172 if (not message and not hgpatch and
1340 if (not message and not hgpatch and
1173 mailre.match(line) and not opts['force']):
1341 mailre.match(line) and not opts['force']):
1174 if len(line) > 35: line = line[:32] + '...'
1342 if len(line) > 35: line = line[:32] + '...'
1175 raise util.Abort(_('first line looks like a '
1343 raise util.Abort(_('first line looks like a '
1176 'mail header: ') + line)
1344 'mail header: ') + line)
1177 if diffre.match(line):
1345 if diffre.match(line):
1178 break
1346 break
1179 elif hgpatch:
1347 elif hgpatch:
1180 # parse values when importing the result of an hg export
1348 # parse values when importing the result of an hg export
1181 if line.startswith("# User "):
1349 if line.startswith("# User "):
1182 user = line[7:]
1350 user = line[7:]
1183 ui.debug(_('User: %s\n') % user)
1351 ui.debug(_('User: %s\n') % user)
1184 elif not line.startswith("# ") and line:
1352 elif not line.startswith("# ") and line:
1185 message.append(line)
1353 message.append(line)
1186 hgpatch = False
1354 hgpatch = False
1187 elif line == '# HG changeset patch':
1355 elif line == '# HG changeset patch':
1188 hgpatch = True
1356 hgpatch = True
1189 message = [] # We may have collected garbage
1357 message = [] # We may have collected garbage
1190 else:
1358 else:
1191 message.append(line)
1359 message.append(line)
1192
1360
1193 # make sure message isn't empty
1361 # make sure message isn't empty
1194 if not message:
1362 if not message:
1195 message = _("imported patch %s\n") % patch
1363 message = _("imported patch %s\n") % patch
1196 else:
1364 else:
1197 message = "%s\n" % '\n'.join(message)
1365 message = "%s\n" % '\n'.join(message)
1198 ui.debug(_('message:\n%s\n') % message)
1366 ui.debug(_('message:\n%s\n') % message)
1199
1367
1200 files = util.patch(strip, pf, ui)
1368 files = util.patch(strip, pf, ui)
1201
1369
1202 if len(files) > 0:
1370 if len(files) > 0:
1203 addremove(ui, repo, *files)
1371 addremove(ui, repo, *files)
1204 repo.commit(files, message, user)
1372 repo.commit(files, message, user)
1205
1373
1206 def incoming(ui, repo, source="default", **opts):
1374 def incoming(ui, repo, source="default", **opts):
1207 """show new changesets found in source"""
1375 """show new changesets found in source
1376
1377 Show new changesets found in the specified repo or the default
1378 pull repo. These are the changesets that would be pulled if a pull
1379 was requested.
1380
1381 Currently only local repositories are supported.
1382 """
1208 source = ui.expandpath(source)
1383 source = ui.expandpath(source)
1209 other = hg.repository(ui, source)
1384 other = hg.repository(ui, source)
1210 if not other.local():
1385 if not other.local():
1211 raise util.Abort(_("incoming doesn't work for remote repositories yet"))
1386 raise util.Abort(_("incoming doesn't work for remote repositories yet"))
1212 o = repo.findincoming(other)
1387 o = repo.findincoming(other)
1213 if not o:
1388 if not o:
1214 return
1389 return
1215 o = other.newer(o)
1390 o = other.newer(o)
1216 for n in o:
1391 for n in o:
1217 parents = [p for p in other.changelog.parents(n) if p != nullid]
1392 parents = [p for p in other.changelog.parents(n) if p != nullid]
1218 if opts['no_merges'] and len(parents) == 2:
1393 if opts['no_merges'] and len(parents) == 2:
1219 continue
1394 continue
1220 show_changeset(ui, other, changenode=n)
1395 show_changeset(ui, other, changenode=n)
1221 if opts['patch']:
1396 if opts['patch']:
1222 prev = (parents and parents[0]) or nullid
1397 prev = (parents and parents[0]) or nullid
1223 dodiff(ui, ui, other, prev, n)
1398 dodiff(ui, ui, other, prev, n)
1224 ui.write("\n")
1399 ui.write("\n")
1225
1400
1226 def init(ui, dest="."):
1401 def init(ui, dest="."):
1227 """create a new repository in the given directory"""
1402 """create a new repository in the given directory
1403
1404 Initialize a new repository in the given directory. If the given
1405 directory does not exist, it is created.
1406
1407 If no directory is given, the current directory is used.
1408 """
1228 if not os.path.exists(dest):
1409 if not os.path.exists(dest):
1229 os.mkdir(dest)
1410 os.mkdir(dest)
1230 hg.repository(ui, dest, create=1)
1411 hg.repository(ui, dest, create=1)
1231
1412
1232 def locate(ui, repo, *pats, **opts):
1413 def locate(ui, repo, *pats, **opts):
1233 """locate files matching specific patterns"""
1414 """locate files matching specific patterns
1415
1416 Print all files under Mercurial control whose names match the
1417 given patterns.
1418
1419 This command searches the current directory and its
1420 subdirectories. To search an entire repository, move to the root
1421 of the repository.
1422
1423 If no patterns are given to match, this command prints all file
1424 names.
1425
1426 If you want to feed the output of this command into the "xargs"
1427 command, use the "-0" option to both this command and "xargs".
1428 This will avoid the problem of "xargs" treating single filenames
1429 that contain white space as multiple filenames.
1430 """
1234 end = opts['print0'] and '\0' or '\n'
1431 end = opts['print0'] and '\0' or '\n'
1235
1432
1236 for src, abs, rel, exact in walk(repo, pats, opts, '(?:.*/|)'):
1433 for src, abs, rel, exact in walk(repo, pats, opts, '(?:.*/|)'):
1237 if repo.dirstate.state(abs) == '?':
1434 if repo.dirstate.state(abs) == '?':
1238 continue
1435 continue
1239 if opts['fullpath']:
1436 if opts['fullpath']:
1240 ui.write(os.path.join(repo.root, abs), end)
1437 ui.write(os.path.join(repo.root, abs), end)
1241 else:
1438 else:
1242 ui.write(rel, end)
1439 ui.write(rel, end)
1243
1440
1244 def log(ui, repo, *pats, **opts):
1441 def log(ui, repo, *pats, **opts):
1245 """show revision history of entire repository or files"""
1442 """show revision history of entire repository or files
1443
1444 Print the revision history of the specified files or the entire project.
1445
1446 By default this command outputs: changeset id and hash, tags,
1447 parents, user, date and time, and a summary for each commit. The
1448 -v switch adds some more detail, such as changed files, manifest
1449 hashes or message signatures.
1450 """
1246 class dui:
1451 class dui:
1247 # Implement and delegate some ui protocol. Save hunks of
1452 # Implement and delegate some ui protocol. Save hunks of
1248 # output for later display in the desired order.
1453 # output for later display in the desired order.
1249 def __init__(self, ui):
1454 def __init__(self, ui):
1250 self.ui = ui
1455 self.ui = ui
1251 self.hunk = {}
1456 self.hunk = {}
1252 def bump(self, rev):
1457 def bump(self, rev):
1253 self.rev = rev
1458 self.rev = rev
1254 self.hunk[rev] = []
1459 self.hunk[rev] = []
1255 def note(self, *args):
1460 def note(self, *args):
1256 if self.verbose:
1461 if self.verbose:
1257 self.write(*args)
1462 self.write(*args)
1258 def status(self, *args):
1463 def status(self, *args):
1259 if not self.quiet:
1464 if not self.quiet:
1260 self.write(*args)
1465 self.write(*args)
1261 def write(self, *args):
1466 def write(self, *args):
1262 self.hunk[self.rev].append(args)
1467 self.hunk[self.rev].append(args)
1263 def debug(self, *args):
1468 def debug(self, *args):
1264 if self.debugflag:
1469 if self.debugflag:
1265 self.write(*args)
1470 self.write(*args)
1266 def __getattr__(self, key):
1471 def __getattr__(self, key):
1267 return getattr(self.ui, key)
1472 return getattr(self.ui, key)
1268 cwd = repo.getcwd()
1473 cwd = repo.getcwd()
1269 if not pats and cwd:
1474 if not pats and cwd:
1270 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
1475 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
1271 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
1476 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
1272 changeiter, getchange = walkchangerevs(ui, repo, (pats and cwd) or '',
1477 changeiter, getchange = walkchangerevs(ui, repo, (pats and cwd) or '',
1273 pats, opts)
1478 pats, opts)
1274 for st, rev, fns in changeiter:
1479 for st, rev, fns in changeiter:
1275 if st == 'window':
1480 if st == 'window':
1276 du = dui(ui)
1481 du = dui(ui)
1277 elif st == 'add':
1482 elif st == 'add':
1278 du.bump(rev)
1483 du.bump(rev)
1279 changenode = repo.changelog.node(rev)
1484 changenode = repo.changelog.node(rev)
1280 parents = [p for p in repo.changelog.parents(changenode)
1485 parents = [p for p in repo.changelog.parents(changenode)
1281 if p != nullid]
1486 if p != nullid]
1282 if opts['no_merges'] and len(parents) == 2:
1487 if opts['no_merges'] and len(parents) == 2:
1283 continue
1488 continue
1284 if opts['only_merges'] and len(parents) != 2:
1489 if opts['only_merges'] and len(parents) != 2:
1285 continue
1490 continue
1286
1491
1287 br = None
1492 br = None
1288 if opts['keyword']:
1493 if opts['keyword']:
1289 changes = repo.changelog.read(repo.changelog.node(rev))
1494 changes = repo.changelog.read(repo.changelog.node(rev))
1290 miss = 0
1495 miss = 0
1291 for k in [kw.lower() for kw in opts['keyword']]:
1496 for k in [kw.lower() for kw in opts['keyword']]:
1292 if not (k in changes[1].lower() or
1497 if not (k in changes[1].lower() or
1293 k in changes[4].lower() or
1498 k in changes[4].lower() or
1294 k in " ".join(changes[3][:20]).lower()):
1499 k in " ".join(changes[3][:20]).lower()):
1295 miss = 1
1500 miss = 1
1296 break
1501 break
1297 if miss:
1502 if miss:
1298 continue
1503 continue
1299
1504
1300 if opts['branch']:
1505 if opts['branch']:
1301 br = repo.branchlookup([repo.changelog.node(rev)])
1506 br = repo.branchlookup([repo.changelog.node(rev)])
1302
1507
1303 show_changeset(du, repo, rev, brinfo=br)
1508 show_changeset(du, repo, rev, brinfo=br)
1304 if opts['patch']:
1509 if opts['patch']:
1305 prev = (parents and parents[0]) or nullid
1510 prev = (parents and parents[0]) or nullid
1306 dodiff(du, du, repo, prev, changenode, fns)
1511 dodiff(du, du, repo, prev, changenode, fns)
1307 du.write("\n\n")
1512 du.write("\n\n")
1308 elif st == 'iter':
1513 elif st == 'iter':
1309 for args in du.hunk[rev]:
1514 for args in du.hunk[rev]:
1310 ui.write(*args)
1515 ui.write(*args)
1311
1516
1312 def manifest(ui, repo, rev=None):
1517 def manifest(ui, repo, rev=None):
1313 """output the latest or given revision of the project manifest"""
1518 """output the latest or given revision of the project manifest
1519
1520 Print a list of version controlled files for the given revision.
1521
1522 The manifest is the list of files being version controlled. If no revision
1523 is given then the tip is used.
1524 """
1314 if rev:
1525 if rev:
1315 try:
1526 try:
1316 # assume all revision numbers are for changesets
1527 # assume all revision numbers are for changesets
1317 n = repo.lookup(rev)
1528 n = repo.lookup(rev)
1318 change = repo.changelog.read(n)
1529 change = repo.changelog.read(n)
1319 n = change[0]
1530 n = change[0]
1320 except hg.RepoError:
1531 except hg.RepoError:
1321 n = repo.manifest.lookup(rev)
1532 n = repo.manifest.lookup(rev)
1322 else:
1533 else:
1323 n = repo.manifest.tip()
1534 n = repo.manifest.tip()
1324 m = repo.manifest.read(n)
1535 m = repo.manifest.read(n)
1325 mf = repo.manifest.readflags(n)
1536 mf = repo.manifest.readflags(n)
1326 files = m.keys()
1537 files = m.keys()
1327 files.sort()
1538 files.sort()
1328
1539
1329 for f in files:
1540 for f in files:
1330 ui.write("%40s %3s %s\n" % (hex(m[f]), mf[f] and "755" or "644", f))
1541 ui.write("%40s %3s %s\n" % (hex(m[f]), mf[f] and "755" or "644", f))
1331
1542
1332 def outgoing(ui, repo, dest="default-push", **opts):
1543 def outgoing(ui, repo, dest="default-push", **opts):
1333 """show changesets not found in destination"""
1544 """show changesets not found in destination
1545
1546 Show changesets not found in the specified destination repo or the
1547 default push repo. These are the changesets that would be pushed
1548 if a push was requested.
1549 """
1334 dest = ui.expandpath(dest)
1550 dest = ui.expandpath(dest)
1335 other = hg.repository(ui, dest)
1551 other = hg.repository(ui, dest)
1336 o = repo.findoutgoing(other)
1552 o = repo.findoutgoing(other)
1337 o = repo.newer(o)
1553 o = repo.newer(o)
1338 for n in o:
1554 for n in o:
1339 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1555 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1340 if opts['no_merges'] and len(parents) == 2:
1556 if opts['no_merges'] and len(parents) == 2:
1341 continue
1557 continue
1342 show_changeset(ui, repo, changenode=n)
1558 show_changeset(ui, repo, changenode=n)
1343 if opts['patch']:
1559 if opts['patch']:
1344 prev = (parents and parents[0]) or nullid
1560 prev = (parents and parents[0]) or nullid
1345 dodiff(ui, ui, repo, prev, n)
1561 dodiff(ui, ui, repo, prev, n)
1346 ui.write("\n")
1562 ui.write("\n")
1347
1563
1348 def parents(ui, repo, rev=None):
1564 def parents(ui, repo, rev=None):
1349 """show the parents of the working dir or revision"""
1565 """show the parents of the working dir or revision
1566
1567 Print the working directory's parent revisions.
1568 """
1350 if rev:
1569 if rev:
1351 p = repo.changelog.parents(repo.lookup(rev))
1570 p = repo.changelog.parents(repo.lookup(rev))
1352 else:
1571 else:
1353 p = repo.dirstate.parents()
1572 p = repo.dirstate.parents()
1354
1573
1355 for n in p:
1574 for n in p:
1356 if n != nullid:
1575 if n != nullid:
1357 show_changeset(ui, repo, changenode=n)
1576 show_changeset(ui, repo, changenode=n)
1358
1577
1359 def paths(ui, search=None):
1578 def paths(ui, search=None):
1360 """show definition of symbolic path names"""
1579 """show definition of symbolic path names
1580
1581 Show definition of symbolic path name NAME. If no name is given, show
1582 definition of available names.
1583
1584 Path names are defined in the [paths] section of /etc/mercurial/hgrc
1585 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
1586 """
1361 try:
1587 try:
1362 repo = hg.repository(ui=ui)
1588 repo = hg.repository(ui=ui)
1363 except hg.RepoError:
1589 except hg.RepoError:
1364 pass
1590 pass
1365
1591
1366 if search:
1592 if search:
1367 for name, path in ui.configitems("paths"):
1593 for name, path in ui.configitems("paths"):
1368 if name == search:
1594 if name == search:
1369 ui.write("%s\n" % path)
1595 ui.write("%s\n" % path)
1370 return
1596 return
1371 ui.warn(_("not found!\n"))
1597 ui.warn(_("not found!\n"))
1372 return 1
1598 return 1
1373 else:
1599 else:
1374 for name, path in ui.configitems("paths"):
1600 for name, path in ui.configitems("paths"):
1375 ui.write("%s = %s\n" % (name, path))
1601 ui.write("%s = %s\n" % (name, path))
1376
1602
1377 def pull(ui, repo, source="default", **opts):
1603 def pull(ui, repo, source="default", **opts):
1378 """pull changes from the specified source"""
1604 """pull changes from the specified source
1605
1606 Pull changes from a remote repository to a local one.
1607
1608 This finds all changes from the repository at the specified path
1609 or URL and adds them to the local repository. By default, this
1610 does not update the copy of the project in the working directory.
1611
1612 Valid URLs are of the form:
1613
1614 local/filesystem/path
1615 http://[user@]host[:port][/path]
1616 https://[user@]host[:port][/path]
1617 ssh://[user@]host[:port][/path]
1618
1619 SSH requires an accessible shell account on the destination machine
1620 and a copy of hg in the remote path. With SSH, paths are relative
1621 to the remote user's home directory by default; use two slashes at
1622 the start of a path to specify it as relative to the filesystem root.
1623 """
1379 source = ui.expandpath(source)
1624 source = ui.expandpath(source)
1380 ui.status(_('pulling from %s\n') % (source))
1625 ui.status(_('pulling from %s\n') % (source))
1381
1626
1382 if opts['ssh']:
1627 if opts['ssh']:
1383 ui.setconfig("ui", "ssh", opts['ssh'])
1628 ui.setconfig("ui", "ssh", opts['ssh'])
1384 if opts['remotecmd']:
1629 if opts['remotecmd']:
1385 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
1630 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
1386
1631
1387 other = hg.repository(ui, source)
1632 other = hg.repository(ui, source)
1388 r = repo.pull(other)
1633 r = repo.pull(other)
1389 if not r:
1634 if not r:
1390 if opts['update']:
1635 if opts['update']:
1391 return update(ui, repo)
1636 return update(ui, repo)
1392 else:
1637 else:
1393 ui.status(_("(run 'hg update' to get a working copy)\n"))
1638 ui.status(_("(run 'hg update' to get a working copy)\n"))
1394
1639
1395 return r
1640 return r
1396
1641
1397 def push(ui, repo, dest="default-push", force=False, ssh=None, remotecmd=None):
1642 def push(ui, repo, dest="default-push", force=False, ssh=None, remotecmd=None):
1398 """push changes to the specified destination"""
1643 """push changes to the specified destination
1644
1645 Push changes from the local repository to the given destination.
1646
1647 This is the symmetrical operation for pull. It helps to move
1648 changes from the current repository to a different one. If the
1649 destination is local this is identical to a pull in that directory
1650 from the current one.
1651
1652 By default, push will refuse to run if it detects the result would
1653 increase the number of remote heads. This generally indicates the
1654 the client has forgotten to sync and merge before pushing.
1655
1656 Valid URLs are of the form:
1657
1658 local/filesystem/path
1659 ssh://[user@]host[:port][/path]
1660
1661 SSH requires an accessible shell account on the destination
1662 machine and a copy of hg in the remote path.
1663 """
1399 dest = ui.expandpath(dest)
1664 dest = ui.expandpath(dest)
1400 ui.status('pushing to %s\n' % (dest))
1665 ui.status('pushing to %s\n' % (dest))
1401
1666
1402 if ssh:
1667 if ssh:
1403 ui.setconfig("ui", "ssh", ssh)
1668 ui.setconfig("ui", "ssh", ssh)
1404 if remotecmd:
1669 if remotecmd:
1405 ui.setconfig("ui", "remotecmd", remotecmd)
1670 ui.setconfig("ui", "remotecmd", remotecmd)
1406
1671
1407 other = hg.repository(ui, dest)
1672 other = hg.repository(ui, dest)
1408 r = repo.push(other, force)
1673 r = repo.push(other, force)
1409 return r
1674 return r
1410
1675
1411 def rawcommit(ui, repo, *flist, **rc):
1676 def rawcommit(ui, repo, *flist, **rc):
1412 "raw commit interface"
1677 """raw commit interface
1678
1679 Lowlevel commit, for use in helper scripts.
1680
1681 This command is not intended to be used by normal users, as it is
1682 primarily useful for importing from other SCMs.
1683 """
1413 if rc['text']:
1684 if rc['text']:
1414 ui.warn(_("Warning: -t and --text is deprecated,"
1685 ui.warn(_("Warning: -t and --text is deprecated,"
1415 " please use -m or --message instead.\n"))
1686 " please use -m or --message instead.\n"))
1416 message = rc['message'] or rc['text']
1687 message = rc['message'] or rc['text']
1417 if not message and rc['logfile']:
1688 if not message and rc['logfile']:
1418 try:
1689 try:
1419 message = open(rc['logfile']).read()
1690 message = open(rc['logfile']).read()
1420 except IOError:
1691 except IOError:
1421 pass
1692 pass
1422 if not message and not rc['logfile']:
1693 if not message and not rc['logfile']:
1423 raise util.Abort(_("missing commit message"))
1694 raise util.Abort(_("missing commit message"))
1424
1695
1425 files = relpath(repo, list(flist))
1696 files = relpath(repo, list(flist))
1426 if rc['files']:
1697 if rc['files']:
1427 files += open(rc['files']).read().splitlines()
1698 files += open(rc['files']).read().splitlines()
1428
1699
1429 rc['parent'] = map(repo.lookup, rc['parent'])
1700 rc['parent'] = map(repo.lookup, rc['parent'])
1430
1701
1431 try:
1702 try:
1432 repo.rawcommit(files, message, rc['user'], rc['date'], *rc['parent'])
1703 repo.rawcommit(files, message, rc['user'], rc['date'], *rc['parent'])
1433 except ValueError, inst:
1704 except ValueError, inst:
1434 raise util.Abort(str(inst))
1705 raise util.Abort(str(inst))
1435
1706
1436 def recover(ui, repo):
1707 def recover(ui, repo):
1437 """roll back an interrupted transaction"""
1708 """roll back an interrupted transaction
1709
1710 Recover from an interrupted commit or pull.
1711
1712 This command tries to fix the repository status after an interrupted
1713 operation. It should only be necessary when Mercurial suggests it.
1714 """
1438 repo.recover()
1715 repo.recover()
1439
1716
1440 def remove(ui, repo, pat, *pats, **opts):
1717 def remove(ui, repo, pat, *pats, **opts):
1441 """remove the specified files on the next commit"""
1718 """remove the specified files on the next commit
1719
1720 Schedule the indicated files for removal from the repository.
1721
1722 This command schedules the files to be removed at the next commit.
1723 This only removes files from the current branch, not from the
1724 entire project history. If the files still exist in the working
1725 directory, they will be deleted from it.
1726 """
1442 names = []
1727 names = []
1443 def okaytoremove(abs, rel, exact):
1728 def okaytoremove(abs, rel, exact):
1444 c, a, d, u = repo.changes(files = [abs])
1729 c, a, d, u = repo.changes(files = [abs])
1445 reason = None
1730 reason = None
1446 if c: reason = _('is modified')
1731 if c: reason = _('is modified')
1447 elif a: reason = _('has been marked for add')
1732 elif a: reason = _('has been marked for add')
1448 elif u: reason = _('is not managed')
1733 elif u: reason = _('is not managed')
1449 if reason:
1734 if reason:
1450 if exact: ui.warn(_('not removing %s: file %s\n') % (rel, reason))
1735 if exact: ui.warn(_('not removing %s: file %s\n') % (rel, reason))
1451 else:
1736 else:
1452 return True
1737 return True
1453 for src, abs, rel, exact in walk(repo, (pat,) + pats, opts):
1738 for src, abs, rel, exact in walk(repo, (pat,) + pats, opts):
1454 if okaytoremove(abs, rel, exact):
1739 if okaytoremove(abs, rel, exact):
1455 if ui.verbose or not exact: ui.status(_('removing %s\n') % rel)
1740 if ui.verbose or not exact: ui.status(_('removing %s\n') % rel)
1456 names.append(abs)
1741 names.append(abs)
1457 repo.remove(names, unlink=True)
1742 repo.remove(names, unlink=True)
1458
1743
1459 def rename(ui, repo, *pats, **opts):
1744 def rename(ui, repo, *pats, **opts):
1460 """rename files; equivalent of copy + remove"""
1745 """rename files; equivalent of copy + remove
1746
1747 Mark dest as copies of sources; mark sources for deletion. If
1748 dest is a directory, copies are put in that directory. If dest is
1749 a file, there can only be one source.
1750
1751 By default, this command copies the contents of files as they
1752 stand in the working directory. If invoked with --after, the
1753 operation is recorded, but no copying is performed.
1754
1755 This command takes effect in the next commit.
1756
1757 NOTE: This command should be treated as experimental. While it
1758 should properly record rename files, this information is not yet
1759 fully used by merge, nor fully reported by log.
1760 """
1461 errs, copied = docopy(ui, repo, pats, opts)
1761 errs, copied = docopy(ui, repo, pats, opts)
1462 names = []
1762 names = []
1463 for abs, rel, exact in copied:
1763 for abs, rel, exact in copied:
1464 if ui.verbose or not exact: ui.status(_('removing %s\n') % rel)
1764 if ui.verbose or not exact: ui.status(_('removing %s\n') % rel)
1465 names.append(abs)
1765 names.append(abs)
1466 repo.remove(names, unlink=True)
1766 repo.remove(names, unlink=True)
1467 return errs
1767 return errs
1468
1768
1469 def revert(ui, repo, *names, **opts):
1769 def revert(ui, repo, *names, **opts):
1470 """revert modified files or dirs back to their unmodified states"""
1770 """revert modified files or dirs back to their unmodified states
1771
1772 Revert any uncommitted modifications made to the named files or
1773 directories. This restores the contents of the affected files to
1774 an unmodified state.
1775
1776 If a file has been deleted, it is recreated. If the executable
1777 mode of a file was changed, it is reset.
1778
1779 If a directory is given, all files in that directory and its
1780 subdirectories are reverted.
1781
1782 If no arguments are given, all files in the current directory and
1783 its subdirectories are reverted.
1784 """
1471 node = opts['rev'] and repo.lookup(opts['rev']) or \
1785 node = opts['rev'] and repo.lookup(opts['rev']) or \
1472 repo.dirstate.parents()[0]
1786 repo.dirstate.parents()[0]
1473 root = os.path.realpath(repo.root)
1787 root = os.path.realpath(repo.root)
1474
1788
1475 def trimpath(p):
1789 def trimpath(p):
1476 p = os.path.realpath(p)
1790 p = os.path.realpath(p)
1477 if p.startswith(root):
1791 if p.startswith(root):
1478 rest = p[len(root):]
1792 rest = p[len(root):]
1479 if not rest:
1793 if not rest:
1480 return rest
1794 return rest
1481 if p.startswith(os.sep):
1795 if p.startswith(os.sep):
1482 return rest[1:]
1796 return rest[1:]
1483 return p
1797 return p
1484
1798
1485 relnames = map(trimpath, names or [os.getcwd()])
1799 relnames = map(trimpath, names or [os.getcwd()])
1486 chosen = {}
1800 chosen = {}
1487
1801
1488 def choose(name):
1802 def choose(name):
1489 def body(name):
1803 def body(name):
1490 for r in relnames:
1804 for r in relnames:
1491 if not name.startswith(r):
1805 if not name.startswith(r):
1492 continue
1806 continue
1493 rest = name[len(r):]
1807 rest = name[len(r):]
1494 if not rest:
1808 if not rest:
1495 return r, True
1809 return r, True
1496 depth = rest.count(os.sep)
1810 depth = rest.count(os.sep)
1497 if not r:
1811 if not r:
1498 if depth == 0 or not opts['nonrecursive']:
1812 if depth == 0 or not opts['nonrecursive']:
1499 return r, True
1813 return r, True
1500 elif rest[0] == os.sep:
1814 elif rest[0] == os.sep:
1501 if depth == 1 or not opts['nonrecursive']:
1815 if depth == 1 or not opts['nonrecursive']:
1502 return r, True
1816 return r, True
1503 return None, False
1817 return None, False
1504 relname, ret = body(name)
1818 relname, ret = body(name)
1505 if ret:
1819 if ret:
1506 chosen[relname] = 1
1820 chosen[relname] = 1
1507 return ret
1821 return ret
1508
1822
1509 r = repo.update(node, False, True, choose, False)
1823 r = repo.update(node, False, True, choose, False)
1510 for n in relnames:
1824 for n in relnames:
1511 if n not in chosen:
1825 if n not in chosen:
1512 ui.warn(_('error: no matches for %s\n') % n)
1826 ui.warn(_('error: no matches for %s\n') % n)
1513 r = 1
1827 r = 1
1514 sys.stdout.flush()
1828 sys.stdout.flush()
1515 return r
1829 return r
1516
1830
1517 def root(ui, repo):
1831 def root(ui, repo):
1518 """print the root (top) of the current working dir"""
1832 """print the root (top) of the current working dir
1833
1834 Print the root directory of the current repository.
1835 """
1519 ui.write(repo.root + "\n")
1836 ui.write(repo.root + "\n")
1520
1837
1521 def serve(ui, repo, **opts):
1838 def serve(ui, repo, **opts):
1522 """export the repository via HTTP"""
1839 """export the repository via HTTP
1840
1841 Start a local HTTP repository browser and pull server.
1842
1843 By default, the server logs accesses to stdout and errors to
1844 stderr. Use the "-A" and "-E" options to log to files.
1845 """
1523
1846
1524 if opts["stdio"]:
1847 if opts["stdio"]:
1525 fin, fout = sys.stdin, sys.stdout
1848 fin, fout = sys.stdin, sys.stdout
1526 sys.stdout = sys.stderr
1849 sys.stdout = sys.stderr
1527
1850
1528 # Prevent insertion/deletion of CRs
1851 # Prevent insertion/deletion of CRs
1529 util.set_binary(fin)
1852 util.set_binary(fin)
1530 util.set_binary(fout)
1853 util.set_binary(fout)
1531
1854
1532 def getarg():
1855 def getarg():
1533 argline = fin.readline()[:-1]
1856 argline = fin.readline()[:-1]
1534 arg, l = argline.split()
1857 arg, l = argline.split()
1535 val = fin.read(int(l))
1858 val = fin.read(int(l))
1536 return arg, val
1859 return arg, val
1537 def respond(v):
1860 def respond(v):
1538 fout.write("%d\n" % len(v))
1861 fout.write("%d\n" % len(v))
1539 fout.write(v)
1862 fout.write(v)
1540 fout.flush()
1863 fout.flush()
1541
1864
1542 lock = None
1865 lock = None
1543
1866
1544 while 1:
1867 while 1:
1545 cmd = fin.readline()[:-1]
1868 cmd = fin.readline()[:-1]
1546 if cmd == '':
1869 if cmd == '':
1547 return
1870 return
1548 if cmd == "heads":
1871 if cmd == "heads":
1549 h = repo.heads()
1872 h = repo.heads()
1550 respond(" ".join(map(hex, h)) + "\n")
1873 respond(" ".join(map(hex, h)) + "\n")
1551 if cmd == "lock":
1874 if cmd == "lock":
1552 lock = repo.lock()
1875 lock = repo.lock()
1553 respond("")
1876 respond("")
1554 if cmd == "unlock":
1877 if cmd == "unlock":
1555 if lock:
1878 if lock:
1556 lock.release()
1879 lock.release()
1557 lock = None
1880 lock = None
1558 respond("")
1881 respond("")
1559 elif cmd == "branches":
1882 elif cmd == "branches":
1560 arg, nodes = getarg()
1883 arg, nodes = getarg()
1561 nodes = map(bin, nodes.split(" "))
1884 nodes = map(bin, nodes.split(" "))
1562 r = []
1885 r = []
1563 for b in repo.branches(nodes):
1886 for b in repo.branches(nodes):
1564 r.append(" ".join(map(hex, b)) + "\n")
1887 r.append(" ".join(map(hex, b)) + "\n")
1565 respond("".join(r))
1888 respond("".join(r))
1566 elif cmd == "between":
1889 elif cmd == "between":
1567 arg, pairs = getarg()
1890 arg, pairs = getarg()
1568 pairs = [map(bin, p.split("-")) for p in pairs.split(" ")]
1891 pairs = [map(bin, p.split("-")) for p in pairs.split(" ")]
1569 r = []
1892 r = []
1570 for b in repo.between(pairs):
1893 for b in repo.between(pairs):
1571 r.append(" ".join(map(hex, b)) + "\n")
1894 r.append(" ".join(map(hex, b)) + "\n")
1572 respond("".join(r))
1895 respond("".join(r))
1573 elif cmd == "changegroup":
1896 elif cmd == "changegroup":
1574 nodes = []
1897 nodes = []
1575 arg, roots = getarg()
1898 arg, roots = getarg()
1576 nodes = map(bin, roots.split(" "))
1899 nodes = map(bin, roots.split(" "))
1577
1900
1578 cg = repo.changegroup(nodes)
1901 cg = repo.changegroup(nodes)
1579 while 1:
1902 while 1:
1580 d = cg.read(4096)
1903 d = cg.read(4096)
1581 if not d:
1904 if not d:
1582 break
1905 break
1583 fout.write(d)
1906 fout.write(d)
1584
1907
1585 fout.flush()
1908 fout.flush()
1586
1909
1587 elif cmd == "addchangegroup":
1910 elif cmd == "addchangegroup":
1588 if not lock:
1911 if not lock:
1589 respond("not locked")
1912 respond("not locked")
1590 continue
1913 continue
1591 respond("")
1914 respond("")
1592
1915
1593 r = repo.addchangegroup(fin)
1916 r = repo.addchangegroup(fin)
1594 respond("")
1917 respond("")
1595
1918
1596 optlist = "name templates style address port ipv6 accesslog errorlog"
1919 optlist = "name templates style address port ipv6 accesslog errorlog"
1597 for o in optlist.split():
1920 for o in optlist.split():
1598 if opts[o]:
1921 if opts[o]:
1599 ui.setconfig("web", o, opts[o])
1922 ui.setconfig("web", o, opts[o])
1600
1923
1601 try:
1924 try:
1602 httpd = hgweb.create_server(repo)
1925 httpd = hgweb.create_server(repo)
1603 except socket.error, inst:
1926 except socket.error, inst:
1604 raise util.Abort('cannot start server: ' + inst.args[1])
1927 raise util.Abort('cannot start server: ' + inst.args[1])
1605
1928
1606 if ui.verbose:
1929 if ui.verbose:
1607 addr, port = httpd.socket.getsockname()
1930 addr, port = httpd.socket.getsockname()
1608 if addr == '0.0.0.0':
1931 if addr == '0.0.0.0':
1609 addr = socket.gethostname()
1932 addr = socket.gethostname()
1610 else:
1933 else:
1611 try:
1934 try:
1612 addr = socket.gethostbyaddr(addr)[0]
1935 addr = socket.gethostbyaddr(addr)[0]
1613 except socket.error:
1936 except socket.error:
1614 pass
1937 pass
1615 if port != 80:
1938 if port != 80:
1616 ui.status(_('listening at http://%s:%d/\n') % (addr, port))
1939 ui.status(_('listening at http://%s:%d/\n') % (addr, port))
1617 else:
1940 else:
1618 ui.status(_('listening at http://%s/\n') % addr)
1941 ui.status(_('listening at http://%s/\n') % addr)
1619 httpd.serve_forever()
1942 httpd.serve_forever()
1620
1943
1621 def status(ui, repo, *pats, **opts):
1944 def status(ui, repo, *pats, **opts):
1622 '''show changed files in the working directory
1945 """show changed files in the working directory
1623
1946
1947 Show changed files in the working directory. If no names are
1948 given, all files are shown. Otherwise, only files matching the
1949 given names are shown.
1950
1951 The codes used to show the status of files are:
1624 M = modified
1952 M = modified
1625 A = added
1953 A = added
1626 R = removed
1954 R = removed
1627 ? = not tracked
1955 ? = not tracked
1628 '''
1956 """
1629
1957
1630 cwd = repo.getcwd()
1958 cwd = repo.getcwd()
1631 files, matchfn, anypats = matchpats(repo, cwd, pats, opts)
1959 files, matchfn, anypats = matchpats(repo, cwd, pats, opts)
1632 (c, a, d, u) = [[util.pathto(cwd, x) for x in n]
1960 (c, a, d, u) = [[util.pathto(cwd, x) for x in n]
1633 for n in repo.changes(files=files, match=matchfn)]
1961 for n in repo.changes(files=files, match=matchfn)]
1634
1962
1635 changetypes = [(_('modified'), 'M', c),
1963 changetypes = [(_('modified'), 'M', c),
1636 (_('added'), 'A', a),
1964 (_('added'), 'A', a),
1637 (_('removed'), 'R', d),
1965 (_('removed'), 'R', d),
1638 (_('unknown'), '?', u)]
1966 (_('unknown'), '?', u)]
1639
1967
1640 end = opts['print0'] and '\0' or '\n'
1968 end = opts['print0'] and '\0' or '\n'
1641
1969
1642 for opt, char, changes in ([ct for ct in changetypes if opts[ct[0]]]
1970 for opt, char, changes in ([ct for ct in changetypes if opts[ct[0]]]
1643 or changetypes):
1971 or changetypes):
1644 if opts['no_status']:
1972 if opts['no_status']:
1645 format = "%%s%s" % end
1973 format = "%%s%s" % end
1646 else:
1974 else:
1647 format = "%s %%s%s" % (char, end);
1975 format = "%s %%s%s" % (char, end);
1648
1976
1649 for f in changes:
1977 for f in changes:
1650 ui.write(format % f)
1978 ui.write(format % f)
1651
1979
1652 def tag(ui, repo, name, rev=None, **opts):
1980 def tag(ui, repo, name, rev=None, **opts):
1653 """add a tag for the current tip or a given revision"""
1981 """add a tag for the current tip or a given revision
1982
1983 Name a particular revision using <name>.
1984
1985 Tags are used to name particular revisions of the repository and are
1986 very useful to compare different revision, to go back to significant
1987 earlier versions or to mark branch points as releases, etc.
1988
1989 If no revision is given, the tip is used.
1990
1991 To facilitate version control, distribution, and merging of tags,
1992 they are stored as a file named ".hgtags" which is managed
1993 similarly to other project files and can be hand-edited if
1994 necessary.
1995 """
1654 if opts['text']:
1996 if opts['text']:
1655 ui.warn(_("Warning: -t and --text is deprecated,"
1997 ui.warn(_("Warning: -t and --text is deprecated,"
1656 " please use -m or --message instead.\n"))
1998 " please use -m or --message instead.\n"))
1657 if name == "tip":
1999 if name == "tip":
1658 raise util.Abort(_("the name 'tip' is reserved"))
2000 raise util.Abort(_("the name 'tip' is reserved"))
1659 if rev:
2001 if rev:
1660 r = hex(repo.lookup(rev))
2002 r = hex(repo.lookup(rev))
1661 else:
2003 else:
1662 r = hex(repo.changelog.tip())
2004 r = hex(repo.changelog.tip())
1663
2005
1664 if name.find(revrangesep) >= 0:
2006 if name.find(revrangesep) >= 0:
1665 raise util.Abort(_("'%s' cannot be used in a tag name") % revrangesep)
2007 raise util.Abort(_("'%s' cannot be used in a tag name") % revrangesep)
1666
2008
1667 if opts['local']:
2009 if opts['local']:
1668 repo.opener("localtags", "a").write("%s %s\n" % (r, name))
2010 repo.opener("localtags", "a").write("%s %s\n" % (r, name))
1669 return
2011 return
1670
2012
1671 (c, a, d, u) = repo.changes()
2013 (c, a, d, u) = repo.changes()
1672 for x in (c, a, d, u):
2014 for x in (c, a, d, u):
1673 if ".hgtags" in x:
2015 if ".hgtags" in x:
1674 raise util.Abort(_("working copy of .hgtags is changed "
2016 raise util.Abort(_("working copy of .hgtags is changed "
1675 "(please commit .hgtags manually)"))
2017 "(please commit .hgtags manually)"))
1676
2018
1677 repo.wfile(".hgtags", "ab").write("%s %s\n" % (r, name))
2019 repo.wfile(".hgtags", "ab").write("%s %s\n" % (r, name))
1678 if repo.dirstate.state(".hgtags") == '?':
2020 if repo.dirstate.state(".hgtags") == '?':
1679 repo.add([".hgtags"])
2021 repo.add([".hgtags"])
1680
2022
1681 message = (opts['message'] or opts['text'] or
2023 message = (opts['message'] or opts['text'] or
1682 _("Added tag %s for changeset %s") % (name, r))
2024 _("Added tag %s for changeset %s") % (name, r))
1683 try:
2025 try:
1684 repo.commit([".hgtags"], message, opts['user'], opts['date'])
2026 repo.commit([".hgtags"], message, opts['user'], opts['date'])
1685 except ValueError, inst:
2027 except ValueError, inst:
1686 raise util.Abort(str(inst))
2028 raise util.Abort(str(inst))
1687
2029
1688 def tags(ui, repo):
2030 def tags(ui, repo):
1689 """list repository tags"""
2031 """list repository tags
2032
2033 List the repository tags.
2034
2035 This lists both regular and local tags.
2036 """
1690
2037
1691 l = repo.tagslist()
2038 l = repo.tagslist()
1692 l.reverse()
2039 l.reverse()
1693 for t, n in l:
2040 for t, n in l:
1694 try:
2041 try:
1695 r = "%5d:%s" % (repo.changelog.rev(n), hex(n))
2042 r = "%5d:%s" % (repo.changelog.rev(n), hex(n))
1696 except KeyError:
2043 except KeyError:
1697 r = " ?:?"
2044 r = " ?:?"
1698 ui.write("%-30s %s\n" % (t, r))
2045 ui.write("%-30s %s\n" % (t, r))
1699
2046
1700 def tip(ui, repo):
2047 def tip(ui, repo):
1701 """show the tip revision"""
2048 """show the tip revision
2049
2050 Show the tip revision.
2051 """
1702 n = repo.changelog.tip()
2052 n = repo.changelog.tip()
1703 show_changeset(ui, repo, changenode=n)
2053 show_changeset(ui, repo, changenode=n)
1704
2054
1705 def unbundle(ui, repo, fname):
2055 def unbundle(ui, repo, fname):
1706 """apply a changegroup file"""
2056 """apply a changegroup file
2057
2058 Apply a compressed changegroup file generated by the bundle
2059 command.
2060 """
1707 f = urllib.urlopen(fname)
2061 f = urllib.urlopen(fname)
1708
2062
1709 if f.read(4) != "HG10":
2063 if f.read(4) != "HG10":
1710 raise util.Abort(_("%s: not a Mercurial bundle file") % fname)
2064 raise util.Abort(_("%s: not a Mercurial bundle file") % fname)
1711
2065
1712 def bzgenerator(f):
2066 def bzgenerator(f):
1713 zd = bz2.BZ2Decompressor()
2067 zd = bz2.BZ2Decompressor()
1714 for chunk in f:
2068 for chunk in f:
1715 yield zd.decompress(chunk)
2069 yield zd.decompress(chunk)
1716
2070
1717 bzgen = bzgenerator(util.filechunkiter(f, 4096))
2071 bzgen = bzgenerator(util.filechunkiter(f, 4096))
1718 repo.addchangegroup(util.chunkbuffer(bzgen))
2072 repo.addchangegroup(util.chunkbuffer(bzgen))
1719
2073
1720 def undo(ui, repo):
2074 def undo(ui, repo):
1721 """undo the last commit or pull
2075 """undo the last commit or pull
1722
2076
1723 Roll back the last pull or commit transaction on the
2077 Roll back the last pull or commit transaction on the
1724 repository, restoring the project to its earlier state.
2078 repository, restoring the project to its earlier state.
1725
2079
1726 This command should be used with care. There is only one level of
2080 This command should be used with care. There is only one level of
1727 undo and there is no redo.
2081 undo and there is no redo.
1728
2082
1729 This command is not intended for use on public repositories. Once
2083 This command is not intended for use on public repositories. Once
1730 a change is visible for pull by other users, undoing it locally is
2084 a change is visible for pull by other users, undoing it locally is
1731 ineffective.
2085 ineffective.
1732 """
2086 """
1733 repo.undo()
2087 repo.undo()
1734
2088
1735 def update(ui, repo, node=None, merge=False, clean=False, branch=None):
2089 def update(ui, repo, node=None, merge=False, clean=False, branch=None):
1736 '''update or merge working directory
2090 """update or merge working directory
2091
2092 Update the working directory to the specified revision.
1737
2093
1738 If there are no outstanding changes in the working directory and
2094 If there are no outstanding changes in the working directory and
1739 there is a linear relationship between the current version and the
2095 there is a linear relationship between the current version and the
1740 requested version, the result is the requested version.
2096 requested version, the result is the requested version.
1741
2097
1742 Otherwise the result is a merge between the contents of the
2098 Otherwise the result is a merge between the contents of the
1743 current working directory and the requested version. Files that
2099 current working directory and the requested version. Files that
1744 changed between either parent are marked as changed for the next
2100 changed between either parent are marked as changed for the next
1745 commit and a commit must be performed before any further updates
2101 commit and a commit must be performed before any further updates
1746 are allowed.
2102 are allowed.
1747 '''
2103
2104 By default, update will refuse to run if doing so would require
2105 merging or discarding local changes.
2106 """
1748 if branch:
2107 if branch:
1749 br = repo.branchlookup(branch=branch)
2108 br = repo.branchlookup(branch=branch)
1750 found = []
2109 found = []
1751 for x in br:
2110 for x in br:
1752 if branch in br[x]:
2111 if branch in br[x]:
1753 found.append(x)
2112 found.append(x)
1754 if len(found) > 1:
2113 if len(found) > 1:
1755 ui.warn(_("Found multiple heads for %s\n") % branch)
2114 ui.warn(_("Found multiple heads for %s\n") % branch)
1756 for x in found:
2115 for x in found:
1757 show_changeset(ui, repo, changenode=x, brinfo=br)
2116 show_changeset(ui, repo, changenode=x, brinfo=br)
1758 return 1
2117 return 1
1759 if len(found) == 1:
2118 if len(found) == 1:
1760 node = found[0]
2119 node = found[0]
1761 ui.warn(_("Using head %s for branch %s\n") % (short(node), branch))
2120 ui.warn(_("Using head %s for branch %s\n") % (short(node), branch))
1762 else:
2121 else:
1763 ui.warn(_("branch %s not found\n") % (branch))
2122 ui.warn(_("branch %s not found\n") % (branch))
1764 return 1
2123 return 1
1765 else:
2124 else:
1766 node = node and repo.lookup(node) or repo.changelog.tip()
2125 node = node and repo.lookup(node) or repo.changelog.tip()
1767 return repo.update(node, allow=merge, force=clean)
2126 return repo.update(node, allow=merge, force=clean)
1768
2127
1769 def verify(ui, repo):
2128 def verify(ui, repo):
1770 """verify the integrity of the repository"""
2129 """verify the integrity of the repository
2130
2131 Verify the integrity of the current repository.
2132
2133 This will perform an extensive check of the repository's
2134 integrity, validating the hashes and checksums of each entry in
2135 the changelog, manifest, and tracked files, as well as the
2136 integrity of their crosslinks and indices.
2137 """
1771 return repo.verify()
2138 return repo.verify()
1772
2139
1773 # Command options and aliases are listed here, alphabetically
2140 # Command options and aliases are listed here, alphabetically
1774
2141
1775 table = {
2142 table = {
1776 "^add":
2143 "^add":
1777 (add,
2144 (add,
1778 [('I', 'include', [], _('include path in search')),
2145 [('I', 'include', [], _('include names matching the given patterns')),
1779 ('X', 'exclude', [], _('exclude path from search'))],
2146 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
1780 "hg add [OPTION]... [FILE]..."),
2147 "hg add [OPTION]... [FILE]..."),
1781 "addremove":
2148 "addremove":
1782 (addremove,
2149 (addremove,
1783 [('I', 'include', [], _('include path in search')),
2150 [('I', 'include', [], _('include names matching the given patterns')),
1784 ('X', 'exclude', [], _('exclude path from search'))],
2151 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
1785 _("hg addremove [OPTION]... [FILE]...")),
2152 "hg addremove [OPTION]... [FILE]..."),
1786 "^annotate":
2153 "^annotate":
1787 (annotate,
2154 (annotate,
1788 [('r', 'rev', '', _('revision')),
2155 [('r', 'rev', '', _('annotate the specified revision')),
1789 ('a', 'text', None, _('treat all files as text')),
2156 ('a', 'text', None, _('treat all files as text')),
1790 ('u', 'user', None, _('show user')),
2157 ('u', 'user', None, _('list the author')),
1791 ('n', 'number', None, _('show revision number')),
2158 ('n', 'number', None, _('list the revision number (default)')),
1792 ('c', 'changeset', None, _('show changeset')),
2159 ('c', 'changeset', None, _('list the changeset')),
1793 ('I', 'include', [], _('include path in search')),
2160 ('I', 'include', [], _('include names matching the given patterns')),
1794 ('X', 'exclude', [], _('exclude path from search'))],
2161 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
1795 _('hg annotate [OPTION]... FILE...')),
2162 _('hg annotate [OPTION]... FILE...')),
1796 "bundle":
2163 "bundle":
1797 (bundle,
2164 (bundle,
1798 [],
2165 [],
1799 _('hg bundle FILE DEST')),
2166 _('hg bundle FILE DEST')),
1800 "cat":
2167 "cat":
1801 (cat,
2168 (cat,
1802 [('I', 'include', [], _('include path in search')),
2169 [('I', 'include', [], _('include names matching the given patterns')),
1803 ('X', 'exclude', [], _('exclude path from search')),
2170 ('X', 'exclude', [], _('exclude names matching the given patterns')),
1804 ('o', 'output', "", _('output to file')),
2171 ('o', 'output', "", _('print output to file with formatted name')),
1805 ('r', 'rev', '', _('revision'))],
2172 ('r', 'rev', '', _('print the given revision'))],
1806 _('hg cat [OPTION]... FILE...')),
2173 _('hg cat [OPTION]... FILE...')),
1807 "^clone":
2174 "^clone":
1808 (clone,
2175 (clone,
1809 [('U', 'noupdate', None, _('skip update after cloning')),
2176 [('U', 'noupdate', None, _('do not update the new working directory')),
1810 ('e', 'ssh', "", _('ssh command')),
2177 ('e', 'ssh', "", _('specify ssh command to use')),
1811 ('', 'pull', None, _('use pull protocol to copy metadata')),
2178 ('', 'pull', None, _('use pull protocol to copy metadata')),
1812 ('', 'remotecmd', "", _('remote hg command'))],
2179 ('', 'remotecmd', "", _('specify hg command to run on the remote side'))],
1813 _('hg clone [OPTION]... SOURCE [DEST]')),
2180 _('hg clone [OPTION]... SOURCE [DEST]')),
1814 "^commit|ci":
2181 "^commit|ci":
1815 (commit,
2182 (commit,
1816 [('A', 'addremove', None, _('run add/remove during commit')),
2183 [('A', 'addremove', None, _('run addremove during commit')),
1817 ('I', 'include', [], _('include path in search')),
2184 ('I', 'include', [], _('include names matching the given patterns')),
1818 ('X', 'exclude', [], _('exclude path from search')),
2185 ('X', 'exclude', [], _('exclude names matching the given patterns')),
1819 ('m', 'message', "", _('commit message')),
2186 ('m', 'message', "", _('use <text> as commit message')),
1820 ('t', 'text', "", _('commit message (deprecated: use -m)')),
2187 ('t', 'text', "", _('commit message (deprecated: use -m)')),
1821 ('l', 'logfile', "", _('commit message file')),
2188 ('l', 'logfile', "", _('read the commit message from <file>')),
1822 ('d', 'date', "", _('date code')),
2189 ('d', 'date', "", _('record datecode as commit date')),
1823 ('u', 'user', "", _('user'))],
2190 ('u', 'user', "", _('record user as commiter'))],
1824 _('hg commit [OPTION]... [FILE]...')),
2191 _('hg commit [OPTION]... [FILE]...')),
1825 "copy|cp": (copy,
2192 "copy|cp": (copy,
1826 [('I', 'include', [], _('include path in search')),
2193 [('I', 'include', [], _('include names matching the given patterns')),
1827 ('X', 'exclude', [], _('exclude path from search')),
2194 ('X', 'exclude', [], _('exclude names matching the given patterns')),
1828 ('A', 'after', None, _('record a copy after it has happened')),
2195 ('A', 'after', None, _('record a copy that has already occurred')),
1829 ('f', 'force', None, _('replace destination if it exists')),
2196 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1830 ('p', 'parents', None, _('append source path to dest'))],
2197 ('p', 'parents', None, _('append source path to dest'))],
1831 _('hg copy [OPTION]... [SOURCE]... DEST')),
2198 _('hg copy [OPTION]... [SOURCE]... DEST')),
1832 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
2199 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
1833 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
2200 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
1834 "debugconfig": (debugconfig, [], _('debugconfig')),
2201 "debugconfig": (debugconfig, [], _('debugconfig')),
1835 "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
2202 "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
1836 "debugstate": (debugstate, [], _('debugstate')),
2203 "debugstate": (debugstate, [], _('debugstate')),
1837 "debugdata": (debugdata, [], _('debugdata FILE REV')),
2204 "debugdata": (debugdata, [], _('debugdata FILE REV')),
1838 "debugindex": (debugindex, [], _('debugindex FILE')),
2205 "debugindex": (debugindex, [], _('debugindex FILE')),
1839 "debugindexdot": (debugindexdot, [], _('debugindexdot FILE')),
2206 "debugindexdot": (debugindexdot, [], _('debugindexdot FILE')),
1840 "debugrename": (debugrename, [], _('debugrename FILE [REV]')),
2207 "debugrename": (debugrename, [], _('debugrename FILE [REV]')),
1841 "debugwalk":
2208 "debugwalk":
1842 (debugwalk,
2209 (debugwalk,
1843 [('I', 'include', [], _('include path in search')),
2210 [('I', 'include', [], _('include names matching the given patterns')),
1844 ('X', 'exclude', [], _('exclude path from search'))],
2211 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
1845 _('debugwalk [OPTION]... [FILE]...')),
2212 _('debugwalk [OPTION]... [FILE]...')),
1846 "^diff":
2213 "^diff":
1847 (diff,
2214 (diff,
1848 [('r', 'rev', [], _('revision')),
2215 [('r', 'rev', [], _('revision')),
1849 ('a', 'text', None, _('treat all files as text')),
2216 ('a', 'text', None, _('treat all files as text')),
1850 ('I', 'include', [], _('include path in search')),
2217 ('I', 'include', [], _('include names matching the given patterns')),
1851 ('X', 'exclude', [], _('exclude path from search'))],
2218 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
1852 _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')),
2219 _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')),
1853 "^export":
2220 "^export":
1854 (export,
2221 (export,
1855 [('o', 'output', "", _('output to file')),
2222 [('o', 'output', "", _('print output to file with formatted name')),
1856 ('a', 'text', None, _('treat all files as text'))],
2223 ('a', 'text', None, _('treat all files as text'))],
1857 _("hg export [-a] [-o OUTFILE] REV...")),
2224 "hg export [-a] [-o OUTFILE] REV..."),
1858 "forget":
2225 "forget":
1859 (forget,
2226 (forget,
1860 [('I', 'include', [], _('include path in search')),
2227 [('I', 'include', [], _('include names matching the given patterns')),
1861 ('X', 'exclude', [], _('exclude path from search'))],
2228 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
1862 _("hg forget [OPTION]... FILE...")),
2229 "hg forget [OPTION]... FILE..."),
1863 "grep":
2230 "grep":
1864 (grep,
2231 (grep,
1865 [('0', 'print0', None, _('end fields with NUL')),
2232 [('0', 'print0', None, _('end fields with NUL')),
1866 ('I', 'include', [], _('include path in search')),
2233 ('I', 'include', [], _('include names matching the given patterns')),
1867 ('X', 'exclude', [], _('include path in search')),
2234 ('X', 'exclude', [], _('include names matching the given patterns')),
1868 ('', 'all', None, _('print all revisions with matches')),
2235 ('', 'all', None, _('print all revisions that match')),
1869 ('i', 'ignore-case', None, _('ignore case when matching')),
2236 ('i', 'ignore-case', None, _('ignore case when matching')),
1870 ('l', 'files-with-matches', None, _('print names of files and revs with matches')),
2237 ('l', 'files-with-matches', None, _('print only filenames and revs that match')),
1871 ('n', 'line-number', None, _('print line numbers')),
2238 ('n', 'line-number', None, _('print matching line numbers')),
1872 ('r', 'rev', [], _('search in revision rev')),
2239 ('r', 'rev', [], _('search in given revision range')),
1873 ('u', 'user', None, _('print user who made change'))],
2240 ('u', 'user', None, _('print user who committed change'))],
1874 _("hg grep [OPTION]... PATTERN [FILE]...")),
2241 "hg grep [OPTION]... PATTERN [FILE]..."),
1875 "heads":
2242 "heads":
1876 (heads,
2243 (heads,
1877 [('b', 'branches', None, _('find branch info'))],
2244 [('b', 'branches', None, _('find branch info'))],
1878 _('hg heads [-b]')),
2245 _('hg heads [-b]')),
1879 "help": (help_, [], _('hg help [COMMAND]')),
2246 "help": (help_, [], _('hg help [COMMAND]')),
1880 "identify|id": (identify, [], _('hg identify')),
2247 "identify|id": (identify, [], _('hg identify')),
1881 "import|patch":
2248 "import|patch":
1882 (import_,
2249 (import_,
1883 [('p', 'strip', 1, _('path strip')),
2250 [('p', 'strip', 1, _('directory strip option for patch. This has the same\n') +
1884 ('f', 'force', None, _('skip check for outstanding changes')),
2251 _('meaning as the corresponding patch option')),
2252 ('f', 'force', None, _('skip check for outstanding uncommitted changes')),
1885 ('b', 'base', "", _('base path'))],
2253 ('b', 'base', "", _('base path'))],
1886 _("hg import [-f] [-p NUM] [-b BASE] PATCH...")),
2254 "hg import [-f] [-p NUM] [-b BASE] PATCH..."),
1887 "incoming|in": (incoming,
2255 "incoming|in": (incoming,
1888 [('M', 'no-merges', None, _("do not show merges")),
2256 [('M', 'no-merges', None, _("do not show merges")),
1889 ('p', 'patch', None, _('show patch'))],
2257 ('p', 'patch', None, _('show patch'))],
1890 _('hg incoming [-p] [SOURCE]')),
2258 _('hg incoming [-p] [SOURCE]')),
1891 "^init": (init, [], _('hg init [DEST]')),
2259 "^init": (init, [], _('hg init [DEST]')),
1892 "locate":
2260 "locate":
1893 (locate,
2261 (locate,
1894 [('r', 'rev', '', _('revision')),
2262 [('r', 'rev', '', _('search the repository as it stood at rev')),
1895 ('0', 'print0', None, _('end filenames with NUL')),
2263 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
1896 ('f', 'fullpath', None, _('print complete paths')),
2264 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
1897 ('I', 'include', [], _('include path in search')),
2265 ('I', 'include', [], _('include names matching the given patterns')),
1898 ('X', 'exclude', [], _('exclude path from search'))],
2266 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
1899 _('hg locate [OPTION]... [PATTERN]...')),
2267 _('hg locate [OPTION]... [PATTERN]...')),
1900 "^log|history":
2268 "^log|history":
1901 (log,
2269 (log,
1902 [('I', 'include', [], _('include path in search')),
2270 [('I', 'include', [], _('include names matching the given patterns')),
1903 ('X', 'exclude', [], _('exclude path from search')),
2271 ('X', 'exclude', [], _('exclude names matching the given patterns')),
1904 ('b', 'branch', None, _('show branches')),
2272 ('b', 'branch', None, _('show branches')),
1905 ('k', 'keyword', [], _('search for a keyword')),
2273 ('k', 'keyword', [], _('search for a keyword')),
1906 ('r', 'rev', [], _('revision')),
2274 ('r', 'rev', [], _('show the specified revision or range')),
1907 ('M', 'no-merges', None, _("do not show merges")),
2275 ('M', 'no-merges', None, _("do not show merges")),
1908 ('m', 'only-merges', None, _("show only merges")),
2276 ('m', 'only-merges', None, _("show only merges")),
1909 ('p', 'patch', None, _('show patch'))],
2277 ('p', 'patch', None, _('show patch'))],
1910 _('hg log [-I] [-X] [-r REV]... [-p] [FILE]')),
2278 _('hg log [-I] [-X] [-r REV]... [-p] [FILE]')),
1911 "manifest": (manifest, [], _('hg manifest [REV]')),
2279 "manifest": (manifest, [], _('hg manifest [REV]')),
1912 "outgoing|out": (outgoing,
2280 "outgoing|out": (outgoing,
1913 [('M', 'no-merges', None, _("do not show merges")),
2281 [('M', 'no-merges', None, _("do not show merges")),
1914 ('p', 'patch', None, _('show patch'))],
2282 ('p', 'patch', None, _('show patch'))],
1915 _('hg outgoing [-p] [DEST]')),
2283 _('hg outgoing [-p] [DEST]')),
1916 "parents": (parents, [], _('hg parents [REV]')),
2284 "parents": (parents, [], _('hg parents [REV]')),
1917 "paths": (paths, [], _('hg paths [NAME]')),
2285 "paths": (paths, [], _('hg paths [NAME]')),
1918 "^pull":
2286 "^pull":
1919 (pull,
2287 (pull,
1920 [('u', 'update', None, _('update working directory')),
2288 [('u', 'update', None, _('update the working directory to tip after pull')),
1921 ('e', 'ssh', "", _('ssh command')),
2289 ('e', 'ssh', "", _('specify ssh command to use')),
1922 ('', 'remotecmd', "", _('remote hg command'))],
2290 ('', 'remotecmd', "", _('specify hg command to run on the remote side'))],
1923 _('hg pull [-u] [-e FILE] [--remotecmd FILE] [SOURCE]')),
2291 _('hg pull [-u] [-e FILE] [--remotecmd FILE] [SOURCE]')),
1924 "^push":
2292 "^push":
1925 (push,
2293 (push,
1926 [('f', 'force', None, _('force push')),
2294 [('f', 'force', None, _('force push')),
1927 ('e', 'ssh', "", _('ssh command')),
2295 ('e', 'ssh', "", _('specify ssh command to use')),
1928 ('', 'remotecmd', "", _('remote hg command'))],
2296 ('', 'remotecmd', "", _('specify hg command to run on the remote side'))],
1929 _('hg push [-f] [-e FILE] [--remotecmd FILE] [DEST]')),
2297 _('hg push [-f] [-e FILE] [--remotecmd FILE] [DEST]')),
1930 "rawcommit":
2298 "rawcommit":
1931 (rawcommit,
2299 (rawcommit,
1932 [('p', 'parent', [], _('parent')),
2300 [('p', 'parent', [], _('parent')),
1933 ('d', 'date', "", _('date code')),
2301 ('d', 'date', "", _('date code')),
1934 ('u', 'user', "", _('user')),
2302 ('u', 'user', "", _('user')),
1935 ('F', 'files', "", _('file list')),
2303 ('F', 'files', "", _('file list')),
1936 ('m', 'message', "", _('commit message')),
2304 ('m', 'message', "", _('commit message')),
1937 ('t', 'text', "", _('commit message (deprecated: use -m)')),
2305 ('t', 'text', "", _('commit message (deprecated: use -m)')),
1938 ('l', 'logfile', "", _('commit message file'))],
2306 ('l', 'logfile', "", _('commit message file'))],
1939 _('hg rawcommit [OPTION]... [FILE]...')),
2307 _('hg rawcommit [OPTION]... [FILE]...')),
1940 "recover": (recover, [], _("hg recover")),
2308 "recover": (recover, [], _("hg recover")),
1941 "^remove|rm": (remove,
2309 "^remove|rm": (remove,
1942 [('I', 'include', [], _('include path in search')),
2310 [('I', 'include', [], _('include names matching the given patterns')),
1943 ('X', 'exclude', [], _('exclude path from search'))],
2311 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
1944 _("hg remove [OPTION]... FILE...")),
2312 _("hg remove [OPTION]... FILE...")),
1945 "rename|mv": (rename,
2313 "rename|mv": (rename,
1946 [('I', 'include', [], _('include path in search')),
2314 [('I', 'include', [], _('include names matching the given patterns')),
1947 ('X', 'exclude', [], _('exclude path from search')),
2315 ('X', 'exclude', [], _('exclude names matching the given patterns')),
1948 ('A', 'after', None, _('record a copy after it has happened')),
2316 ('A', 'after', None, _('record a rename that has already occurred')),
1949 ('f', 'force', None, _('replace destination if it exists')),
2317 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1950 ('p', 'parents', None, _('append source path to dest'))],
2318 ('p', 'parents', None, _('append source path to dest'))],
1951 _('hg rename [OPTION]... [SOURCE]... DEST')),
2319 _('hg rename [OPTION]... [SOURCE]... DEST')),
1952 "^revert":
2320 "^revert":
1953 (revert,
2321 (revert,
1954 [("n", "nonrecursive", None, _("don't recurse into subdirs")),
2322 [("n", "nonrecursive", None, _("do not recurse into subdirectories")),
1955 ("r", "rev", "", _("revision"))],
2323 ("r", "rev", "", _("revision to revert to"))],
1956 _("hg revert [-n] [-r REV] [NAME]...")),
2324 _("hg revert [-n] [-r REV] [NAME]...")),
1957 "root": (root, [], _("hg root")),
2325 "root": (root, [], _("hg root")),
1958 "^serve":
2326 "^serve":
1959 (serve,
2327 (serve,
1960 [('A', 'accesslog', '', _('access log file')),
2328 [('A', 'accesslog', '', _('name of access log file to write to')),
1961 ('E', 'errorlog', '', _('error log file')),
2329 ('E', 'errorlog', '', _('name of error log file to write to')),
1962 ('p', 'port', 0, _('listen port')),
2330 ('p', 'port', 0, _('port to use (default: 8000)')),
1963 ('a', 'address', '', _('interface address')),
2331 ('a', 'address', '', _('address to use')),
1964 ('n', 'name', "", _('repository name')),
2332 ('n', 'name', "", _('name to show in web pages (default: working dir)')),
1965 ('', 'stdio', None, _('for remote clients')),
2333 ('', 'stdio', None, _('for remote clients')),
1966 ('t', 'templates', "", _('template directory')),
2334 ('t', 'templates', "", _('web templates to use')),
1967 ('', 'style', "", _('template style')),
2335 ('', 'style', "", _('template style to use')),
1968 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))],
2336 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))],
1969 _("hg serve [OPTION]...")),
2337 _("hg serve [OPTION]...")),
1970 "^status":
2338 "^status":
1971 (status,
2339 (status,
1972 [('m', 'modified', None, _('show only modified files')),
2340 [('m', 'modified', None, _('show only modified files')),
1973 ('a', 'added', None, _('show only added files')),
2341 ('a', 'added', None, _('show only added files')),
1974 ('r', 'removed', None, _('show only removed files')),
2342 ('r', 'removed', None, _('show only removed files')),
1975 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
2343 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
1976 ('n', 'no-status', None, _('hide status prefix')),
2344 ('n', 'no-status', None, _('hide status prefix')),
1977 ('0', 'print0', None, _('end filenames with NUL')),
2345 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
1978 ('I', 'include', [], _('include path in search')),
2346 ('I', 'include', [], _('include names matching the given patterns')),
1979 ('X', 'exclude', [], _('exclude path from search'))],
2347 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
1980 _("hg status [OPTION]... [FILE]...")),
2348 _("hg status [OPTION]... [FILE]...")),
1981 "tag":
2349 "tag":
1982 (tag,
2350 (tag,
1983 [('l', 'local', None, _('make the tag local')),
2351 [('l', 'local', None, _('make the tag local')),
1984 ('m', 'message', "", _('commit message')),
2352 ('m', 'message', "", _('message for tag commit log entry')),
1985 ('t', 'text', "", _('commit message (deprecated: use -m)')),
2353 ('t', 'text', "", _('commit message (deprecated: use -m)')),
1986 ('d', 'date', "", _('date code')),
2354 ('d', 'date', "", _('record datecode as commit date')),
1987 ('u', 'user', "", _('user'))],
2355 ('u', 'user', "", _('record user as commiter'))],
1988 _('hg tag [OPTION]... NAME [REV]')),
2356 _('hg tag [OPTION]... NAME [REV]')),
1989 "tags": (tags, [], _('hg tags')),
2357 "tags": (tags, [], _('hg tags')),
1990 "tip": (tip, [], _('hg tip')),
2358 "tip": (tip, [], _('hg tip')),
1991 "unbundle":
2359 "unbundle":
1992 (unbundle,
2360 (unbundle,
1993 [],
2361 [],
1994 _('hg unbundle FILE')),
2362 _('hg unbundle FILE')),
1995 "undo": (undo, [], _('hg undo')),
2363 "undo": (undo, [], _('hg undo')),
1996 "^update|up|checkout|co":
2364 "^update|up|checkout|co":
1997 (update,
2365 (update,
1998 [('b', 'branch', "", _('checkout the head of a specific branch')),
2366 [('b', 'branch', "", _('checkout the head of a specific branch')),
1999 ('m', 'merge', None, _('allow merging of conflicts')),
2367 ('m', 'merge', None, _('allow merging of branches')),
2000 ('C', 'clean', None, _('overwrite locally modified files'))],
2368 ('C', 'clean', None, _('overwrite locally modified files'))],
2001 _('hg update [-b TAG] [-m] [-C] [REV]')),
2369 _('hg update [-b TAG] [-m] [-C] [REV]')),
2002 "verify": (verify, [], _('hg verify')),
2370 "verify": (verify, [], _('hg verify')),
2003 "version": (show_version, [], _('hg version')),
2371 "version": (show_version, [], _('hg version')),
2004 }
2372 }
2005
2373
2006 globalopts = [
2374 globalopts = [
2007 ('R', 'repository', "", _('repository root directory')),
2375 ('R', 'repository', "", _("repository root directory")),
2008 ('', 'cwd', '', _('change working directory')),
2376 ('', 'cwd', '', _("change working directory")),
2009 ('y', 'noninteractive', None, _('run non-interactively')),
2377 ('y', 'noninteractive', None, _("do not prompt, assume 'yes' for any required answers")),
2010 ('q', 'quiet', None, _('quiet mode')),
2378 ('q', 'quiet', None, _("suppress output")),
2011 ('v', 'verbose', None, _('verbose mode')),
2379 ('v', 'verbose', None, _("enable additional output")),
2012 ('', 'debug', None, _('debug mode')),
2380 ('', 'debug', None, _("enable debugging output")),
2013 ('', 'debugger', None, _('start debugger')),
2381 ('', 'debugger', None, _("start debugger")),
2014 ('', 'traceback', None, _('print traceback on exception')),
2382 ('', 'traceback', None, _("print traceback on exception")),
2015 ('', 'time', None, _('time how long the command takes')),
2383 ('', 'time', None, _("time how long the command takes")),
2016 ('', 'profile', None, _('profile')),
2384 ('', 'profile', None, _("print command execution profile")),
2017 ('', 'version', None, _('output version information and exit')),
2385 ('', 'version', None, _("output version information and exit")),
2018 ('h', 'help', None, _('display help and exit')),
2386 ('h', 'help', None, _("display help and exit")),
2019 ]
2387 ]
2020
2388
2021 norepo = ("clone init version help debugancestor debugconfig debugdata"
2389 norepo = ("clone init version help debugancestor debugconfig debugdata"
2022 " debugindex debugindexdot paths")
2390 " debugindex debugindexdot paths")
2023
2391
2024 def find(cmd):
2392 def find(cmd):
2025 for e in table.keys():
2393 for e in table.keys():
2026 if re.match("(%s)$" % e, cmd):
2394 if re.match("(%s)$" % e, cmd):
2027 return e, table[e]
2395 return e, table[e]
2028
2396
2029 raise UnknownCommand(cmd)
2397 raise UnknownCommand(cmd)
2030
2398
2031 class SignalInterrupt(Exception):
2399 class SignalInterrupt(Exception):
2032 """Exception raised on SIGTERM and SIGHUP."""
2400 """Exception raised on SIGTERM and SIGHUP."""
2033
2401
2034 def catchterm(*args):
2402 def catchterm(*args):
2035 raise SignalInterrupt
2403 raise SignalInterrupt
2036
2404
2037 def run():
2405 def run():
2038 sys.exit(dispatch(sys.argv[1:]))
2406 sys.exit(dispatch(sys.argv[1:]))
2039
2407
2040 class ParseError(Exception):
2408 class ParseError(Exception):
2041 """Exception raised on errors in parsing the command line."""
2409 """Exception raised on errors in parsing the command line."""
2042
2410
2043 def parse(args):
2411 def parse(args):
2044 options = {}
2412 options = {}
2045 cmdoptions = {}
2413 cmdoptions = {}
2046
2414
2047 try:
2415 try:
2048 args = fancyopts.fancyopts(args, globalopts, options)
2416 args = fancyopts.fancyopts(args, globalopts, options)
2049 except fancyopts.getopt.GetoptError, inst:
2417 except fancyopts.getopt.GetoptError, inst:
2050 raise ParseError(None, inst)
2418 raise ParseError(None, inst)
2051
2419
2052 if args:
2420 if args:
2053 cmd, args = args[0], args[1:]
2421 cmd, args = args[0], args[1:]
2054 i = find(cmd)[1]
2422 i = find(cmd)[1]
2055 c = list(i[1])
2423 c = list(i[1])
2056 else:
2424 else:
2057 cmd = None
2425 cmd = None
2058 c = []
2426 c = []
2059
2427
2060 # combine global options into local
2428 # combine global options into local
2061 for o in globalopts:
2429 for o in globalopts:
2062 c.append((o[0], o[1], options[o[1]], o[3]))
2430 c.append((o[0], o[1], options[o[1]], o[3]))
2063
2431
2064 try:
2432 try:
2065 args = fancyopts.fancyopts(args, c, cmdoptions)
2433 args = fancyopts.fancyopts(args, c, cmdoptions)
2066 except fancyopts.getopt.GetoptError, inst:
2434 except fancyopts.getopt.GetoptError, inst:
2067 raise ParseError(cmd, inst)
2435 raise ParseError(cmd, inst)
2068
2436
2069 # separate global options back out
2437 # separate global options back out
2070 for o in globalopts:
2438 for o in globalopts:
2071 n = o[1]
2439 n = o[1]
2072 options[n] = cmdoptions[n]
2440 options[n] = cmdoptions[n]
2073 del cmdoptions[n]
2441 del cmdoptions[n]
2074
2442
2075 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
2443 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
2076
2444
2077 def dispatch(args):
2445 def dispatch(args):
2078 signal.signal(signal.SIGTERM, catchterm)
2446 signal.signal(signal.SIGTERM, catchterm)
2079 try:
2447 try:
2080 signal.signal(signal.SIGHUP, catchterm)
2448 signal.signal(signal.SIGHUP, catchterm)
2081 except AttributeError:
2449 except AttributeError:
2082 pass
2450 pass
2083
2451
2084 u = ui.ui()
2452 u = ui.ui()
2085 external = []
2453 external = []
2086 for x in u.extensions():
2454 for x in u.extensions():
2087 def on_exception(Exception, inst):
2455 def on_exception(Exception, inst):
2088 u.warn(_("*** failed to import extension %s\n") % x[1])
2456 u.warn(_("*** failed to import extension %s\n") % x[1])
2089 u.warn("%s\n" % inst)
2457 u.warn("%s\n" % inst)
2090 if "--traceback" in sys.argv[1:]:
2458 if "--traceback" in sys.argv[1:]:
2091 traceback.print_exc()
2459 traceback.print_exc()
2092 if x[1]:
2460 if x[1]:
2093 try:
2461 try:
2094 mod = imp.load_source(x[0], x[1])
2462 mod = imp.load_source(x[0], x[1])
2095 except Exception, inst:
2463 except Exception, inst:
2096 on_exception(Exception, inst)
2464 on_exception(Exception, inst)
2097 continue
2465 continue
2098 else:
2466 else:
2099 def importh(name):
2467 def importh(name):
2100 mod = __import__(name)
2468 mod = __import__(name)
2101 components = name.split('.')
2469 components = name.split('.')
2102 for comp in components[1:]:
2470 for comp in components[1:]:
2103 mod = getattr(mod, comp)
2471 mod = getattr(mod, comp)
2104 return mod
2472 return mod
2105 try:
2473 try:
2106 mod = importh(x[0])
2474 mod = importh(x[0])
2107 except Exception, inst:
2475 except Exception, inst:
2108 on_exception(Exception, inst)
2476 on_exception(Exception, inst)
2109 continue
2477 continue
2110
2478
2111 external.append(mod)
2479 external.append(mod)
2112 for x in external:
2480 for x in external:
2113 cmdtable = getattr(x, 'cmdtable', {})
2481 cmdtable = getattr(x, 'cmdtable', {})
2114 for t in cmdtable:
2482 for t in cmdtable:
2115 if t in table:
2483 if t in table:
2116 u.warn(_("module %s overrides %s\n") % (x.__name__, t))
2484 u.warn(_("module %s overrides %s\n") % (x.__name__, t))
2117 table.update(cmdtable)
2485 table.update(cmdtable)
2118
2486
2119 try:
2487 try:
2120 cmd, func, args, options, cmdoptions = parse(args)
2488 cmd, func, args, options, cmdoptions = parse(args)
2121 except ParseError, inst:
2489 except ParseError, inst:
2122 if inst.args[0]:
2490 if inst.args[0]:
2123 u.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
2491 u.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
2124 help_(u, inst.args[0])
2492 help_(u, inst.args[0])
2125 else:
2493 else:
2126 u.warn(_("hg: %s\n") % inst.args[1])
2494 u.warn(_("hg: %s\n") % inst.args[1])
2127 help_(u, 'shortlist')
2495 help_(u, 'shortlist')
2128 sys.exit(-1)
2496 sys.exit(-1)
2129 except UnknownCommand, inst:
2497 except UnknownCommand, inst:
2130 u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
2498 u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
2131 help_(u, 'shortlist')
2499 help_(u, 'shortlist')
2132 sys.exit(1)
2500 sys.exit(1)
2133
2501
2134 if options["time"]:
2502 if options["time"]:
2135 def get_times():
2503 def get_times():
2136 t = os.times()
2504 t = os.times()
2137 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
2505 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
2138 t = (t[0], t[1], t[2], t[3], time.clock())
2506 t = (t[0], t[1], t[2], t[3], time.clock())
2139 return t
2507 return t
2140 s = get_times()
2508 s = get_times()
2141 def print_time():
2509 def print_time():
2142 t = get_times()
2510 t = get_times()
2143 u.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
2511 u.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
2144 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
2512 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
2145 atexit.register(print_time)
2513 atexit.register(print_time)
2146
2514
2147 u.updateopts(options["verbose"], options["debug"], options["quiet"],
2515 u.updateopts(options["verbose"], options["debug"], options["quiet"],
2148 not options["noninteractive"])
2516 not options["noninteractive"])
2149
2517
2150 # enter the debugger before command execution
2518 # enter the debugger before command execution
2151 if options['debugger']:
2519 if options['debugger']:
2152 pdb.set_trace()
2520 pdb.set_trace()
2153
2521
2154 try:
2522 try:
2155 try:
2523 try:
2156 if options['help']:
2524 if options['help']:
2157 help_(u, cmd, options['version'])
2525 help_(u, cmd, options['version'])
2158 sys.exit(0)
2526 sys.exit(0)
2159 elif options['version']:
2527 elif options['version']:
2160 show_version(u)
2528 show_version(u)
2161 sys.exit(0)
2529 sys.exit(0)
2162 elif not cmd:
2530 elif not cmd:
2163 help_(u, 'shortlist')
2531 help_(u, 'shortlist')
2164 sys.exit(0)
2532 sys.exit(0)
2165
2533
2166 if options['cwd']:
2534 if options['cwd']:
2167 try:
2535 try:
2168 os.chdir(options['cwd'])
2536 os.chdir(options['cwd'])
2169 except OSError, inst:
2537 except OSError, inst:
2170 raise util.Abort('%s: %s' %
2538 raise util.Abort('%s: %s' %
2171 (options['cwd'], inst.strerror))
2539 (options['cwd'], inst.strerror))
2172
2540
2173 if cmd not in norepo.split():
2541 if cmd not in norepo.split():
2174 path = options["repository"] or ""
2542 path = options["repository"] or ""
2175 repo = hg.repository(ui=u, path=path)
2543 repo = hg.repository(ui=u, path=path)
2176 for x in external:
2544 for x in external:
2177 if hasattr(x, 'reposetup'): x.reposetup(u, repo)
2545 if hasattr(x, 'reposetup'): x.reposetup(u, repo)
2178 d = lambda: func(u, repo, *args, **cmdoptions)
2546 d = lambda: func(u, repo, *args, **cmdoptions)
2179 else:
2547 else:
2180 d = lambda: func(u, *args, **cmdoptions)
2548 d = lambda: func(u, *args, **cmdoptions)
2181
2549
2182 if options['profile']:
2550 if options['profile']:
2183 import hotshot, hotshot.stats
2551 import hotshot, hotshot.stats
2184 prof = hotshot.Profile("hg.prof")
2552 prof = hotshot.Profile("hg.prof")
2185 r = prof.runcall(d)
2553 r = prof.runcall(d)
2186 prof.close()
2554 prof.close()
2187 stats = hotshot.stats.load("hg.prof")
2555 stats = hotshot.stats.load("hg.prof")
2188 stats.strip_dirs()
2556 stats.strip_dirs()
2189 stats.sort_stats('time', 'calls')
2557 stats.sort_stats('time', 'calls')
2190 stats.print_stats(40)
2558 stats.print_stats(40)
2191 return r
2559 return r
2192 else:
2560 else:
2193 return d()
2561 return d()
2194 except:
2562 except:
2195 # enter the debugger when we hit an exception
2563 # enter the debugger when we hit an exception
2196 if options['debugger']:
2564 if options['debugger']:
2197 pdb.post_mortem(sys.exc_info()[2])
2565 pdb.post_mortem(sys.exc_info()[2])
2198 if options['traceback']:
2566 if options['traceback']:
2199 traceback.print_exc()
2567 traceback.print_exc()
2200 raise
2568 raise
2201 except hg.RepoError, inst:
2569 except hg.RepoError, inst:
2202 u.warn(_("abort: "), inst, "!\n")
2570 u.warn(_("abort: "), inst, "!\n")
2203 except revlog.RevlogError, inst:
2571 except revlog.RevlogError, inst:
2204 u.warn(_("abort: "), inst, "!\n")
2572 u.warn(_("abort: "), inst, "!\n")
2205 except SignalInterrupt:
2573 except SignalInterrupt:
2206 u.warn(_("killed!\n"))
2574 u.warn(_("killed!\n"))
2207 except KeyboardInterrupt:
2575 except KeyboardInterrupt:
2208 try:
2576 try:
2209 u.warn(_("interrupted!\n"))
2577 u.warn(_("interrupted!\n"))
2210 except IOError, inst:
2578 except IOError, inst:
2211 if inst.errno == errno.EPIPE:
2579 if inst.errno == errno.EPIPE:
2212 if u.debugflag:
2580 if u.debugflag:
2213 u.warn(_("\nbroken pipe\n"))
2581 u.warn(_("\nbroken pipe\n"))
2214 else:
2582 else:
2215 raise
2583 raise
2216 except IOError, inst:
2584 except IOError, inst:
2217 if hasattr(inst, "code"):
2585 if hasattr(inst, "code"):
2218 u.warn(_("abort: %s\n") % inst)
2586 u.warn(_("abort: %s\n") % inst)
2219 elif hasattr(inst, "reason"):
2587 elif hasattr(inst, "reason"):
2220 u.warn(_("abort: error: %s\n") % inst.reason[1])
2588 u.warn(_("abort: error: %s\n") % inst.reason[1])
2221 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
2589 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
2222 if u.debugflag:
2590 if u.debugflag:
2223 u.warn(_("broken pipe\n"))
2591 u.warn(_("broken pipe\n"))
2224 elif getattr(inst, "strerror", None):
2592 elif getattr(inst, "strerror", None):
2225 if getattr(inst, "filename", None):
2593 if getattr(inst, "filename", None):
2226 u.warn(_("abort: %s - %s\n") % (inst.strerror, inst.filename))
2594 u.warn(_("abort: %s - %s\n") % (inst.strerror, inst.filename))
2227 else:
2595 else:
2228 u.warn(_("abort: %s\n") % inst.strerror)
2596 u.warn(_("abort: %s\n") % inst.strerror)
2229 else:
2597 else:
2230 raise
2598 raise
2231 except OSError, inst:
2599 except OSError, inst:
2232 if hasattr(inst, "filename"):
2600 if hasattr(inst, "filename"):
2233 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
2601 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
2234 else:
2602 else:
2235 u.warn(_("abort: %s\n") % inst.strerror)
2603 u.warn(_("abort: %s\n") % inst.strerror)
2236 except util.Abort, inst:
2604 except util.Abort, inst:
2237 u.warn(_('abort: '), inst.args[0] % inst.args[1:], '\n')
2605 u.warn(_('abort: '), inst.args[0] % inst.args[1:], '\n')
2238 sys.exit(1)
2606 sys.exit(1)
2239 except TypeError, inst:
2607 except TypeError, inst:
2240 # was this an argument error?
2608 # was this an argument error?
2241 tb = traceback.extract_tb(sys.exc_info()[2])
2609 tb = traceback.extract_tb(sys.exc_info()[2])
2242 if len(tb) > 2: # no
2610 if len(tb) > 2: # no
2243 raise
2611 raise
2244 u.debug(inst, "\n")
2612 u.debug(inst, "\n")
2245 u.warn(_("%s: invalid arguments\n") % cmd)
2613 u.warn(_("%s: invalid arguments\n") % cmd)
2246 help_(u, cmd)
2614 help_(u, cmd)
2247 except UnknownCommand, inst:
2615 except UnknownCommand, inst:
2248 u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
2616 u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
2249 help_(u, 'shortlist')
2617 help_(u, 'shortlist')
2250 except SystemExit:
2618 except SystemExit:
2251 # don't catch this in the catch-all below
2619 # don't catch this in the catch-all below
2252 raise
2620 raise
2253 except:
2621 except:
2254 u.warn(_("** unknown exception encountered, details follow\n"))
2622 u.warn(_("** unknown exception encountered, details follow\n"))
2255 u.warn(_("** report bug details to mercurial@selenic.com\n"))
2623 u.warn(_("** report bug details to mercurial@selenic.com\n"))
2256 raise
2624 raise
2257
2625
2258 sys.exit(-1)
2626 sys.exit(-1)
@@ -1,211 +1,244
1 Mercurial Distributed SCM
1 Mercurial Distributed SCM
2
2
3 basic commands (use "hg help" for the full list or option "-v" for details):
3 basic commands (use "hg help" for the full list or option "-v" for details):
4
4
5 add add the specified files on the next commit
5 add add the specified files on the next commit
6 annotate show changeset information per file line
6 annotate show changeset information per file line
7 clone make a copy of an existing repository
7 clone make a copy of an existing repository
8 commit commit the specified files or all outstanding changes
8 commit commit the specified files or all outstanding changes
9 diff diff working directory (or selected files)
9 diff diff working directory (or selected files)
10 export dump the header and diffs for one or more changesets
10 export dump the header and diffs for one or more changesets
11 init create a new repository in the given directory
11 init create a new repository in the given directory
12 log show revision history of entire repository or files
12 log show revision history of entire repository or files
13 pull pull changes from the specified source
13 pull pull changes from the specified source
14 push push changes to the specified destination
14 push push changes to the specified destination
15 remove remove the specified files on the next commit
15 remove remove the specified files on the next commit
16 revert revert modified files or dirs back to their unmodified states
16 revert revert modified files or dirs back to their unmodified states
17 serve export the repository via HTTP
17 serve export the repository via HTTP
18 status show changed files in the working directory
18 status show changed files in the working directory
19 update update or merge working directory
19 update update or merge working directory
20 add add the specified files on the next commit
20 add add the specified files on the next commit
21 annotate show changeset information per file line
21 annotate show changeset information per file line
22 clone make a copy of an existing repository
22 clone make a copy of an existing repository
23 commit commit the specified files or all outstanding changes
23 commit commit the specified files or all outstanding changes
24 diff diff working directory (or selected files)
24 diff diff working directory (or selected files)
25 export dump the header and diffs for one or more changesets
25 export dump the header and diffs for one or more changesets
26 init create a new repository in the given directory
26 init create a new repository in the given directory
27 log show revision history of entire repository or files
27 log show revision history of entire repository or files
28 pull pull changes from the specified source
28 pull pull changes from the specified source
29 push push changes to the specified destination
29 push push changes to the specified destination
30 remove remove the specified files on the next commit
30 remove remove the specified files on the next commit
31 revert revert modified files or dirs back to their unmodified states
31 revert revert modified files or dirs back to their unmodified states
32 serve export the repository via HTTP
32 serve export the repository via HTTP
33 status show changed files in the working directory
33 status show changed files in the working directory
34 update update or merge working directory
34 update update or merge working directory
35 Mercurial Distributed SCM
35 Mercurial Distributed SCM
36
36
37 list of commands (use "hg help -v" to show aliases and global options):
37 list of commands (use "hg help -v" to show aliases and global options):
38
38
39 add add the specified files on the next commit
39 add add the specified files on the next commit
40 addremove add all new files, delete all missing files
40 addremove add all new files, delete all missing files
41 annotate show changeset information per file line
41 annotate show changeset information per file line
42 bundle create a changegroup file
42 bundle create a changegroup file
43 cat output the latest or given revisions of files
43 cat output the latest or given revisions of files
44 clone make a copy of an existing repository
44 clone make a copy of an existing repository
45 commit commit the specified files or all outstanding changes
45 commit commit the specified files or all outstanding changes
46 copy mark files as copied for the next commit
46 copy mark files as copied for the next commit
47 diff diff working directory (or selected files)
47 diff diff working directory (or selected files)
48 export dump the header and diffs for one or more changesets
48 export dump the header and diffs for one or more changesets
49 forget don't add the specified files on the next commit
49 forget don't add the specified files on the next commit
50 grep search for a pattern in specified files and revisions
50 grep search for a pattern in specified files and revisions
51 heads show current repository heads
51 heads show current repository heads
52 help show help for a given command or all commands
52 help show help for a given command or all commands
53 identify print information about the working copy
53 identify print information about the working copy
54 import import an ordered set of patches
54 import import an ordered set of patches
55 incoming show new changesets found in source
55 incoming show new changesets found in source
56 init create a new repository in the given directory
56 init create a new repository in the given directory
57 locate locate files matching specific patterns
57 locate locate files matching specific patterns
58 log show revision history of entire repository or files
58 log show revision history of entire repository or files
59 manifest output the latest or given revision of the project manifest
59 manifest output the latest or given revision of the project manifest
60 outgoing show changesets not found in destination
60 outgoing show changesets not found in destination
61 parents show the parents of the working dir or revision
61 parents show the parents of the working dir or revision
62 paths show definition of symbolic path names
62 paths show definition of symbolic path names
63 pull pull changes from the specified source
63 pull pull changes from the specified source
64 push push changes to the specified destination
64 push push changes to the specified destination
65 rawcommit raw commit interface
65 rawcommit raw commit interface
66 recover roll back an interrupted transaction
66 recover roll back an interrupted transaction
67 remove remove the specified files on the next commit
67 remove remove the specified files on the next commit
68 rename rename files; equivalent of copy + remove
68 rename rename files; equivalent of copy + remove
69 revert revert modified files or dirs back to their unmodified states
69 revert revert modified files or dirs back to their unmodified states
70 root print the root (top) of the current working dir
70 root print the root (top) of the current working dir
71 serve export the repository via HTTP
71 serve export the repository via HTTP
72 status show changed files in the working directory
72 status show changed files in the working directory
73 tag add a tag for the current tip or a given revision
73 tag add a tag for the current tip or a given revision
74 tags list repository tags
74 tags list repository tags
75 tip show the tip revision
75 tip show the tip revision
76 unbundle apply a changegroup file
76 unbundle apply a changegroup file
77 undo undo the last commit or pull
77 undo undo the last commit or pull
78 update update or merge working directory
78 update update or merge working directory
79 verify verify the integrity of the repository
79 verify verify the integrity of the repository
80 version output version and copyright information
80 version output version and copyright information
81 add add the specified files on the next commit
81 add add the specified files on the next commit
82 addremove add all new files, delete all missing files
82 addremove add all new files, delete all missing files
83 annotate show changeset information per file line
83 annotate show changeset information per file line
84 bundle create a changegroup file
84 bundle create a changegroup file
85 cat output the latest or given revisions of files
85 cat output the latest or given revisions of files
86 clone make a copy of an existing repository
86 clone make a copy of an existing repository
87 commit commit the specified files or all outstanding changes
87 commit commit the specified files or all outstanding changes
88 copy mark files as copied for the next commit
88 copy mark files as copied for the next commit
89 diff diff working directory (or selected files)
89 diff diff working directory (or selected files)
90 export dump the header and diffs for one or more changesets
90 export dump the header and diffs for one or more changesets
91 forget don't add the specified files on the next commit
91 forget don't add the specified files on the next commit
92 grep search for a pattern in specified files and revisions
92 grep search for a pattern in specified files and revisions
93 heads show current repository heads
93 heads show current repository heads
94 help show help for a given command or all commands
94 help show help for a given command or all commands
95 identify print information about the working copy
95 identify print information about the working copy
96 import import an ordered set of patches
96 import import an ordered set of patches
97 incoming show new changesets found in source
97 incoming show new changesets found in source
98 init create a new repository in the given directory
98 init create a new repository in the given directory
99 locate locate files matching specific patterns
99 locate locate files matching specific patterns
100 log show revision history of entire repository or files
100 log show revision history of entire repository or files
101 manifest output the latest or given revision of the project manifest
101 manifest output the latest or given revision of the project manifest
102 outgoing show changesets not found in destination
102 outgoing show changesets not found in destination
103 parents show the parents of the working dir or revision
103 parents show the parents of the working dir or revision
104 paths show definition of symbolic path names
104 paths show definition of symbolic path names
105 pull pull changes from the specified source
105 pull pull changes from the specified source
106 push push changes to the specified destination
106 push push changes to the specified destination
107 rawcommit raw commit interface
107 rawcommit raw commit interface
108 recover roll back an interrupted transaction
108 recover roll back an interrupted transaction
109 remove remove the specified files on the next commit
109 remove remove the specified files on the next commit
110 rename rename files; equivalent of copy + remove
110 rename rename files; equivalent of copy + remove
111 revert revert modified files or dirs back to their unmodified states
111 revert revert modified files or dirs back to their unmodified states
112 root print the root (top) of the current working dir
112 root print the root (top) of the current working dir
113 serve export the repository via HTTP
113 serve export the repository via HTTP
114 status show changed files in the working directory
114 status show changed files in the working directory
115 tag add a tag for the current tip or a given revision
115 tag add a tag for the current tip or a given revision
116 tags list repository tags
116 tags list repository tags
117 tip show the tip revision
117 tip show the tip revision
118 unbundle apply a changegroup file
118 unbundle apply a changegroup file
119 undo undo the last commit or pull
119 undo undo the last commit or pull
120 update update or merge working directory
120 update update or merge working directory
121 verify verify the integrity of the repository
121 verify verify the integrity of the repository
122 version output version and copyright information
122 version output version and copyright information
123 hg add [OPTION]... [FILE]...
123 hg add [OPTION]... [FILE]...
124
124
125 add the specified files on the next commit
125 add the specified files on the next commit
126
126
127 Schedule files to be version controlled and added to the repository.
128
129 The files will be added to the repository at the next commit.
130
131 If no names are given, add all files in the current directory and
132 its subdirectories.
133
127 options:
134 options:
128
135
129 -I --include include path in search
136 -I --include include names matching the given patterns
130 -X --exclude exclude path from search
137 -X --exclude exclude names matching the given patterns
131 hg add: option --skjdfks not recognized
138 hg add: option --skjdfks not recognized
132 hg add [OPTION]... [FILE]...
139 hg add [OPTION]... [FILE]...
133
140
134 add the specified files on the next commit
141 add the specified files on the next commit
135
142
143 Schedule files to be version controlled and added to the repository.
144
145 The files will be added to the repository at the next commit.
146
147 If no names are given, add all files in the current directory and
148 its subdirectories.
149
136 options:
150 options:
137
151
138 -I --include include path in search
152 -I --include include names matching the given patterns
139 -X --exclude exclude path from search
153 -X --exclude exclude names matching the given patterns
140 hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...
154 hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...
141
155
142 diff working directory (or selected files)
156 diff working directory (or selected files)
143
157
158 Show differences between revisions for the specified files.
159
160 Differences between files are shown using the unified diff format.
161
162 When two revision arguments are given, then changes are shown
163 between those revisions. If only one revision is specified then
164 that revision is compared to the working directory, and, when no
165 revisions are specified, the working directory files are compared
166 to its parent.
167
168 Without the -a option, diff will avoid generating diffs of files
169 it detects as binary. With -a, diff will generate a diff anyway,
170 probably with undesirable results.
171
144 options:
172 options:
145
173
146 -r --rev revision
174 -r --rev revision
147 -a --text treat all files as text
175 -a --text treat all files as text
148 -I --include include path in search
176 -I --include include names matching the given patterns
149 -X --exclude exclude path from search
177 -X --exclude exclude names matching the given patterns
150 hg status [OPTION]... [FILE]...
178 hg status [OPTION]... [FILE]...
151
179
152 show changed files in the working directory
180 show changed files in the working directory
153
181
182 Show changed files in the working directory. If no names are
183 given, all files are shown. Otherwise, only files matching the
184 given names are shown.
185
186 The codes used to show the status of files are:
154 M = modified
187 M = modified
155 A = added
188 A = added
156 R = removed
189 R = removed
157 ? = not tracked
190 ? = not tracked
158
191
159 options:
192 options:
160
193
161 -m --modified show only modified files
194 -m --modified show only modified files
162 -a --added show only added files
195 -a --added show only added files
163 -r --removed show only removed files
196 -r --removed show only removed files
164 -u --unknown show only unknown (not tracked) files
197 -u --unknown show only unknown (not tracked) files
165 -n --no-status hide status prefix
198 -n --no-status hide status prefix
166 -0 --print0 end filenames with NUL
199 -0 --print0 end filenames with NUL, for use with xargs
167 -I --include include path in search
200 -I --include include names matching the given patterns
168 -X --exclude exclude path from search
201 -X --exclude exclude names matching the given patterns
169 hg status [OPTION]... [FILE]...
202 hg status [OPTION]... [FILE]...
170
203
171 show changed files in the working directory
204 show changed files in the working directory
172 hg: unknown command 'foo'
205 hg: unknown command 'foo'
173 Mercurial Distributed SCM
206 Mercurial Distributed SCM
174
207
175 basic commands (use "hg help" for the full list or option "-v" for details):
208 basic commands (use "hg help" for the full list or option "-v" for details):
176
209
177 add add the specified files on the next commit
210 add add the specified files on the next commit
178 annotate show changeset information per file line
211 annotate show changeset information per file line
179 clone make a copy of an existing repository
212 clone make a copy of an existing repository
180 commit commit the specified files or all outstanding changes
213 commit commit the specified files or all outstanding changes
181 diff diff working directory (or selected files)
214 diff diff working directory (or selected files)
182 export dump the header and diffs for one or more changesets
215 export dump the header and diffs for one or more changesets
183 init create a new repository in the given directory
216 init create a new repository in the given directory
184 log show revision history of entire repository or files
217 log show revision history of entire repository or files
185 pull pull changes from the specified source
218 pull pull changes from the specified source
186 push push changes to the specified destination
219 push push changes to the specified destination
187 remove remove the specified files on the next commit
220 remove remove the specified files on the next commit
188 revert revert modified files or dirs back to their unmodified states
221 revert revert modified files or dirs back to their unmodified states
189 serve export the repository via HTTP
222 serve export the repository via HTTP
190 status show changed files in the working directory
223 status show changed files in the working directory
191 update update or merge working directory
224 update update or merge working directory
192 hg: unknown command 'skjdfks'
225 hg: unknown command 'skjdfks'
193 Mercurial Distributed SCM
226 Mercurial Distributed SCM
194
227
195 basic commands (use "hg help" for the full list or option "-v" for details):
228 basic commands (use "hg help" for the full list or option "-v" for details):
196
229
197 add add the specified files on the next commit
230 add add the specified files on the next commit
198 annotate show changeset information per file line
231 annotate show changeset information per file line
199 clone make a copy of an existing repository
232 clone make a copy of an existing repository
200 commit commit the specified files or all outstanding changes
233 commit commit the specified files or all outstanding changes
201 diff diff working directory (or selected files)
234 diff diff working directory (or selected files)
202 export dump the header and diffs for one or more changesets
235 export dump the header and diffs for one or more changesets
203 init create a new repository in the given directory
236 init create a new repository in the given directory
204 log show revision history of entire repository or files
237 log show revision history of entire repository or files
205 pull pull changes from the specified source
238 pull pull changes from the specified source
206 push push changes to the specified destination
239 push push changes to the specified destination
207 remove remove the specified files on the next commit
240 remove remove the specified files on the next commit
208 revert revert modified files or dirs back to their unmodified states
241 revert revert modified files or dirs back to their unmodified states
209 serve export the repository via HTTP
242 serve export the repository via HTTP
210 status show changed files in the working directory
243 status show changed files in the working directory
211 update update or merge working directory
244 update update or merge working directory
General Comments 0
You need to be logged in to leave comments. Login now