##// END OF EJS Templates
addremove: do not deprecate....
Vadim Gelfer -
r2955:9d1c3529 default
parent child Browse files
Show More
@@ -1,3533 +1,3527 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from demandload import demandload
8 from demandload import demandload
9 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 templater bundlerepo")
12 demandload(globals(), "fancyopts ui hg util lock revlog templater bundlerepo")
13 demandload(globals(), "fnmatch mdiff random signal tempfile time")
13 demandload(globals(), "fnmatch mdiff random signal tempfile time")
14 demandload(globals(), "traceback errno socket version struct atexit sets bz2")
14 demandload(globals(), "traceback errno socket version struct atexit sets bz2")
15 demandload(globals(), "archival cStringIO changegroup email.Parser")
15 demandload(globals(), "archival cStringIO changegroup email.Parser")
16 demandload(globals(), "hgweb.server sshserver")
16 demandload(globals(), "hgweb.server sshserver")
17
17
18 class UnknownCommand(Exception):
18 class UnknownCommand(Exception):
19 """Exception raised if command is not in the command table."""
19 """Exception raised if command is not in the command table."""
20 class AmbiguousCommand(Exception):
20 class AmbiguousCommand(Exception):
21 """Exception raised if command shortcut matches more than one command."""
21 """Exception raised if command shortcut matches more than one command."""
22
22
23 def bail_if_changed(repo):
23 def bail_if_changed(repo):
24 modified, added, removed, deleted, unknown = repo.changes()
24 modified, added, removed, deleted, unknown = repo.changes()
25 if modified or added or removed or deleted:
25 if modified or added or removed or deleted:
26 raise util.Abort(_("outstanding uncommitted changes"))
26 raise util.Abort(_("outstanding uncommitted changes"))
27
27
28 def filterfiles(filters, files):
28 def filterfiles(filters, files):
29 l = [x for x in files if x in filters]
29 l = [x for x in files if x in filters]
30
30
31 for t in filters:
31 for t in filters:
32 if t and t[-1] != "/":
32 if t and t[-1] != "/":
33 t += "/"
33 t += "/"
34 l += [x for x in files if x.startswith(t)]
34 l += [x for x in files if x.startswith(t)]
35 return l
35 return l
36
36
37 def relpath(repo, args):
37 def relpath(repo, args):
38 cwd = repo.getcwd()
38 cwd = repo.getcwd()
39 if cwd:
39 if cwd:
40 return [util.normpath(os.path.join(cwd, x)) for x in args]
40 return [util.normpath(os.path.join(cwd, x)) for x in args]
41 return args
41 return args
42
42
43 def matchpats(repo, pats=[], opts={}, head=''):
43 def matchpats(repo, pats=[], opts={}, head=''):
44 cwd = repo.getcwd()
44 cwd = repo.getcwd()
45 if not pats and cwd:
45 if not pats and cwd:
46 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
46 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
47 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
47 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
48 cwd = ''
48 cwd = ''
49 return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
49 return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
50 opts.get('exclude'), head)
50 opts.get('exclude'), head)
51
51
52 def makewalk(repo, pats, opts, node=None, head='', badmatch=None):
52 def makewalk(repo, pats, opts, node=None, head='', badmatch=None):
53 files, matchfn, anypats = matchpats(repo, pats, opts, head)
53 files, matchfn, anypats = matchpats(repo, pats, opts, head)
54 exact = dict(zip(files, files))
54 exact = dict(zip(files, files))
55 def walk():
55 def walk():
56 for src, fn in repo.walk(node=node, files=files, match=matchfn,
56 for src, fn in repo.walk(node=node, files=files, match=matchfn,
57 badmatch=badmatch):
57 badmatch=badmatch):
58 yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact
58 yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact
59 return files, matchfn, walk()
59 return files, matchfn, walk()
60
60
61 def walk(repo, pats, opts, node=None, head='', badmatch=None):
61 def walk(repo, pats, opts, node=None, head='', badmatch=None):
62 files, matchfn, results = makewalk(repo, pats, opts, node, head, badmatch)
62 files, matchfn, results = makewalk(repo, pats, opts, node, head, badmatch)
63 for r in results:
63 for r in results:
64 yield r
64 yield r
65
65
66 def walkchangerevs(ui, repo, pats, opts):
66 def walkchangerevs(ui, repo, pats, opts):
67 '''Iterate over files and the revs they changed in.
67 '''Iterate over files and the revs they changed in.
68
68
69 Callers most commonly need to iterate backwards over the history
69 Callers most commonly need to iterate backwards over the history
70 it is interested in. Doing so has awful (quadratic-looking)
70 it is interested in. Doing so has awful (quadratic-looking)
71 performance, so we use iterators in a "windowed" way.
71 performance, so we use iterators in a "windowed" way.
72
72
73 We walk a window of revisions in the desired order. Within the
73 We walk a window of revisions in the desired order. Within the
74 window, we first walk forwards to gather data, then in the desired
74 window, we first walk forwards to gather data, then in the desired
75 order (usually backwards) to display it.
75 order (usually backwards) to display it.
76
76
77 This function returns an (iterator, getchange, matchfn) tuple. The
77 This function returns an (iterator, getchange, matchfn) tuple. The
78 getchange function returns the changelog entry for a numeric
78 getchange function returns the changelog entry for a numeric
79 revision. The iterator yields 3-tuples. They will be of one of
79 revision. The iterator yields 3-tuples. They will be of one of
80 the following forms:
80 the following forms:
81
81
82 "window", incrementing, lastrev: stepping through a window,
82 "window", incrementing, lastrev: stepping through a window,
83 positive if walking forwards through revs, last rev in the
83 positive if walking forwards through revs, last rev in the
84 sequence iterated over - use to reset state for the current window
84 sequence iterated over - use to reset state for the current window
85
85
86 "add", rev, fns: out-of-order traversal of the given file names
86 "add", rev, fns: out-of-order traversal of the given file names
87 fns, which changed during revision rev - use to gather data for
87 fns, which changed during revision rev - use to gather data for
88 possible display
88 possible display
89
89
90 "iter", rev, None: in-order traversal of the revs earlier iterated
90 "iter", rev, None: in-order traversal of the revs earlier iterated
91 over with "add" - use to display data'''
91 over with "add" - use to display data'''
92
92
93 def increasing_windows(start, end, windowsize=8, sizelimit=512):
93 def increasing_windows(start, end, windowsize=8, sizelimit=512):
94 if start < end:
94 if start < end:
95 while start < end:
95 while start < end:
96 yield start, min(windowsize, end-start)
96 yield start, min(windowsize, end-start)
97 start += windowsize
97 start += windowsize
98 if windowsize < sizelimit:
98 if windowsize < sizelimit:
99 windowsize *= 2
99 windowsize *= 2
100 else:
100 else:
101 while start > end:
101 while start > end:
102 yield start, min(windowsize, start-end-1)
102 yield start, min(windowsize, start-end-1)
103 start -= windowsize
103 start -= windowsize
104 if windowsize < sizelimit:
104 if windowsize < sizelimit:
105 windowsize *= 2
105 windowsize *= 2
106
106
107
107
108 files, matchfn, anypats = matchpats(repo, pats, opts)
108 files, matchfn, anypats = matchpats(repo, pats, opts)
109
109
110 if repo.changelog.count() == 0:
110 if repo.changelog.count() == 0:
111 return [], False, matchfn
111 return [], False, matchfn
112
112
113 revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
113 revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
114 wanted = {}
114 wanted = {}
115 slowpath = anypats
115 slowpath = anypats
116 fncache = {}
116 fncache = {}
117
117
118 chcache = {}
118 chcache = {}
119 def getchange(rev):
119 def getchange(rev):
120 ch = chcache.get(rev)
120 ch = chcache.get(rev)
121 if ch is None:
121 if ch is None:
122 chcache[rev] = ch = repo.changelog.read(repo.lookup(str(rev)))
122 chcache[rev] = ch = repo.changelog.read(repo.lookup(str(rev)))
123 return ch
123 return ch
124
124
125 if not slowpath and not files:
125 if not slowpath and not files:
126 # No files, no patterns. Display all revs.
126 # No files, no patterns. Display all revs.
127 wanted = dict(zip(revs, revs))
127 wanted = dict(zip(revs, revs))
128 if not slowpath:
128 if not slowpath:
129 # Only files, no patterns. Check the history of each file.
129 # Only files, no patterns. Check the history of each file.
130 def filerevgen(filelog):
130 def filerevgen(filelog):
131 cl_count = repo.changelog.count()
131 cl_count = repo.changelog.count()
132 for i, window in increasing_windows(filelog.count()-1, -1):
132 for i, window in increasing_windows(filelog.count()-1, -1):
133 revs = []
133 revs = []
134 for j in xrange(i - window, i + 1):
134 for j in xrange(i - window, i + 1):
135 revs.append(filelog.linkrev(filelog.node(j)))
135 revs.append(filelog.linkrev(filelog.node(j)))
136 revs.reverse()
136 revs.reverse()
137 for rev in revs:
137 for rev in revs:
138 # only yield rev for which we have the changelog, it can
138 # only yield rev for which we have the changelog, it can
139 # happen while doing "hg log" during a pull or commit
139 # happen while doing "hg log" during a pull or commit
140 if rev < cl_count:
140 if rev < cl_count:
141 yield rev
141 yield rev
142
142
143 minrev, maxrev = min(revs), max(revs)
143 minrev, maxrev = min(revs), max(revs)
144 for file_ in files:
144 for file_ in files:
145 filelog = repo.file(file_)
145 filelog = repo.file(file_)
146 # A zero count may be a directory or deleted file, so
146 # A zero count may be a directory or deleted file, so
147 # try to find matching entries on the slow path.
147 # try to find matching entries on the slow path.
148 if filelog.count() == 0:
148 if filelog.count() == 0:
149 slowpath = True
149 slowpath = True
150 break
150 break
151 for rev in filerevgen(filelog):
151 for rev in filerevgen(filelog):
152 if rev <= maxrev:
152 if rev <= maxrev:
153 if rev < minrev:
153 if rev < minrev:
154 break
154 break
155 fncache.setdefault(rev, [])
155 fncache.setdefault(rev, [])
156 fncache[rev].append(file_)
156 fncache[rev].append(file_)
157 wanted[rev] = 1
157 wanted[rev] = 1
158 if slowpath:
158 if slowpath:
159 # The slow path checks files modified in every changeset.
159 # The slow path checks files modified in every changeset.
160 def changerevgen():
160 def changerevgen():
161 for i, window in increasing_windows(repo.changelog.count()-1, -1):
161 for i, window in increasing_windows(repo.changelog.count()-1, -1):
162 for j in xrange(i - window, i + 1):
162 for j in xrange(i - window, i + 1):
163 yield j, getchange(j)[3]
163 yield j, getchange(j)[3]
164
164
165 for rev, changefiles in changerevgen():
165 for rev, changefiles in changerevgen():
166 matches = filter(matchfn, changefiles)
166 matches = filter(matchfn, changefiles)
167 if matches:
167 if matches:
168 fncache[rev] = matches
168 fncache[rev] = matches
169 wanted[rev] = 1
169 wanted[rev] = 1
170
170
171 def iterate():
171 def iterate():
172 for i, window in increasing_windows(0, len(revs)):
172 for i, window in increasing_windows(0, len(revs)):
173 yield 'window', revs[0] < revs[-1], revs[-1]
173 yield 'window', revs[0] < revs[-1], revs[-1]
174 nrevs = [rev for rev in revs[i:i+window]
174 nrevs = [rev for rev in revs[i:i+window]
175 if rev in wanted]
175 if rev in wanted]
176 srevs = list(nrevs)
176 srevs = list(nrevs)
177 srevs.sort()
177 srevs.sort()
178 for rev in srevs:
178 for rev in srevs:
179 fns = fncache.get(rev) or filter(matchfn, getchange(rev)[3])
179 fns = fncache.get(rev) or filter(matchfn, getchange(rev)[3])
180 yield 'add', rev, fns
180 yield 'add', rev, fns
181 for rev in nrevs:
181 for rev in nrevs:
182 yield 'iter', rev, None
182 yield 'iter', rev, None
183 return iterate(), getchange, matchfn
183 return iterate(), getchange, matchfn
184
184
185 revrangesep = ':'
185 revrangesep = ':'
186
186
187 def revfix(repo, val, defval):
187 def revfix(repo, val, defval):
188 '''turn user-level id of changeset into rev number.
188 '''turn user-level id of changeset into rev number.
189 user-level id can be tag, changeset, rev number, or negative rev
189 user-level id can be tag, changeset, rev number, or negative rev
190 number relative to number of revs (-1 is tip, etc).'''
190 number relative to number of revs (-1 is tip, etc).'''
191 if not val:
191 if not val:
192 return defval
192 return defval
193 try:
193 try:
194 num = int(val)
194 num = int(val)
195 if str(num) != val:
195 if str(num) != val:
196 raise ValueError
196 raise ValueError
197 if num < 0:
197 if num < 0:
198 num += repo.changelog.count()
198 num += repo.changelog.count()
199 if num < 0:
199 if num < 0:
200 num = 0
200 num = 0
201 elif num >= repo.changelog.count():
201 elif num >= repo.changelog.count():
202 raise ValueError
202 raise ValueError
203 except ValueError:
203 except ValueError:
204 try:
204 try:
205 num = repo.changelog.rev(repo.lookup(val))
205 num = repo.changelog.rev(repo.lookup(val))
206 except KeyError:
206 except KeyError:
207 raise util.Abort(_('invalid revision identifier %s'), val)
207 raise util.Abort(_('invalid revision identifier %s'), val)
208 return num
208 return num
209
209
210 def revpair(ui, repo, revs):
210 def revpair(ui, repo, revs):
211 '''return pair of nodes, given list of revisions. second item can
211 '''return pair of nodes, given list of revisions. second item can
212 be None, meaning use working dir.'''
212 be None, meaning use working dir.'''
213 if not revs:
213 if not revs:
214 return repo.dirstate.parents()[0], None
214 return repo.dirstate.parents()[0], None
215 end = None
215 end = None
216 if len(revs) == 1:
216 if len(revs) == 1:
217 start = revs[0]
217 start = revs[0]
218 if revrangesep in start:
218 if revrangesep in start:
219 start, end = start.split(revrangesep, 1)
219 start, end = start.split(revrangesep, 1)
220 start = revfix(repo, start, 0)
220 start = revfix(repo, start, 0)
221 end = revfix(repo, end, repo.changelog.count() - 1)
221 end = revfix(repo, end, repo.changelog.count() - 1)
222 else:
222 else:
223 start = revfix(repo, start, None)
223 start = revfix(repo, start, None)
224 elif len(revs) == 2:
224 elif len(revs) == 2:
225 if revrangesep in revs[0] or revrangesep in revs[1]:
225 if revrangesep in revs[0] or revrangesep in revs[1]:
226 raise util.Abort(_('too many revisions specified'))
226 raise util.Abort(_('too many revisions specified'))
227 start = revfix(repo, revs[0], None)
227 start = revfix(repo, revs[0], None)
228 end = revfix(repo, revs[1], None)
228 end = revfix(repo, revs[1], None)
229 else:
229 else:
230 raise util.Abort(_('too many revisions specified'))
230 raise util.Abort(_('too many revisions specified'))
231 if end is not None: end = repo.lookup(str(end))
231 if end is not None: end = repo.lookup(str(end))
232 return repo.lookup(str(start)), end
232 return repo.lookup(str(start)), end
233
233
234 def revrange(ui, repo, revs):
234 def revrange(ui, repo, revs):
235 """Yield revision as strings from a list of revision specifications."""
235 """Yield revision as strings from a list of revision specifications."""
236 seen = {}
236 seen = {}
237 for spec in revs:
237 for spec in revs:
238 if revrangesep in spec:
238 if revrangesep in spec:
239 start, end = spec.split(revrangesep, 1)
239 start, end = spec.split(revrangesep, 1)
240 start = revfix(repo, start, 0)
240 start = revfix(repo, start, 0)
241 end = revfix(repo, end, repo.changelog.count() - 1)
241 end = revfix(repo, end, repo.changelog.count() - 1)
242 step = start > end and -1 or 1
242 step = start > end and -1 or 1
243 for rev in xrange(start, end+step, step):
243 for rev in xrange(start, end+step, step):
244 if rev in seen:
244 if rev in seen:
245 continue
245 continue
246 seen[rev] = 1
246 seen[rev] = 1
247 yield str(rev)
247 yield str(rev)
248 else:
248 else:
249 rev = revfix(repo, spec, None)
249 rev = revfix(repo, spec, None)
250 if rev in seen:
250 if rev in seen:
251 continue
251 continue
252 seen[rev] = 1
252 seen[rev] = 1
253 yield str(rev)
253 yield str(rev)
254
254
255 def make_filename(repo, pat, node,
255 def make_filename(repo, pat, node,
256 total=None, seqno=None, revwidth=None, pathname=None):
256 total=None, seqno=None, revwidth=None, pathname=None):
257 node_expander = {
257 node_expander = {
258 'H': lambda: hex(node),
258 'H': lambda: hex(node),
259 'R': lambda: str(repo.changelog.rev(node)),
259 'R': lambda: str(repo.changelog.rev(node)),
260 'h': lambda: short(node),
260 'h': lambda: short(node),
261 }
261 }
262 expander = {
262 expander = {
263 '%': lambda: '%',
263 '%': lambda: '%',
264 'b': lambda: os.path.basename(repo.root),
264 'b': lambda: os.path.basename(repo.root),
265 }
265 }
266
266
267 try:
267 try:
268 if node:
268 if node:
269 expander.update(node_expander)
269 expander.update(node_expander)
270 if node and revwidth is not None:
270 if node and revwidth is not None:
271 expander['r'] = lambda: str(r.rev(node)).zfill(revwidth)
271 expander['r'] = lambda: str(r.rev(node)).zfill(revwidth)
272 if total is not None:
272 if total is not None:
273 expander['N'] = lambda: str(total)
273 expander['N'] = lambda: str(total)
274 if seqno is not None:
274 if seqno is not None:
275 expander['n'] = lambda: str(seqno)
275 expander['n'] = lambda: str(seqno)
276 if total is not None and seqno is not None:
276 if total is not None and seqno is not None:
277 expander['n'] = lambda:str(seqno).zfill(len(str(total)))
277 expander['n'] = lambda:str(seqno).zfill(len(str(total)))
278 if pathname is not None:
278 if pathname is not None:
279 expander['s'] = lambda: os.path.basename(pathname)
279 expander['s'] = lambda: os.path.basename(pathname)
280 expander['d'] = lambda: os.path.dirname(pathname) or '.'
280 expander['d'] = lambda: os.path.dirname(pathname) or '.'
281 expander['p'] = lambda: pathname
281 expander['p'] = lambda: pathname
282
282
283 newname = []
283 newname = []
284 patlen = len(pat)
284 patlen = len(pat)
285 i = 0
285 i = 0
286 while i < patlen:
286 while i < patlen:
287 c = pat[i]
287 c = pat[i]
288 if c == '%':
288 if c == '%':
289 i += 1
289 i += 1
290 c = pat[i]
290 c = pat[i]
291 c = expander[c]()
291 c = expander[c]()
292 newname.append(c)
292 newname.append(c)
293 i += 1
293 i += 1
294 return ''.join(newname)
294 return ''.join(newname)
295 except KeyError, inst:
295 except KeyError, inst:
296 raise util.Abort(_("invalid format spec '%%%s' in output file name"),
296 raise util.Abort(_("invalid format spec '%%%s' in output file name"),
297 inst.args[0])
297 inst.args[0])
298
298
299 def make_file(repo, pat, node=None,
299 def make_file(repo, pat, node=None,
300 total=None, seqno=None, revwidth=None, mode='wb', pathname=None):
300 total=None, seqno=None, revwidth=None, mode='wb', pathname=None):
301 if not pat or pat == '-':
301 if not pat or pat == '-':
302 return 'w' in mode and sys.stdout or sys.stdin
302 return 'w' in mode and sys.stdout or sys.stdin
303 if hasattr(pat, 'write') and 'w' in mode:
303 if hasattr(pat, 'write') and 'w' in mode:
304 return pat
304 return pat
305 if hasattr(pat, 'read') and 'r' in mode:
305 if hasattr(pat, 'read') and 'r' in mode:
306 return pat
306 return pat
307 return open(make_filename(repo, pat, node, total, seqno, revwidth,
307 return open(make_filename(repo, pat, node, total, seqno, revwidth,
308 pathname),
308 pathname),
309 mode)
309 mode)
310
310
311 def write_bundle(cg, filename=None, compress=True):
311 def write_bundle(cg, filename=None, compress=True):
312 """Write a bundle file and return its filename.
312 """Write a bundle file and return its filename.
313
313
314 Existing files will not be overwritten.
314 Existing files will not be overwritten.
315 If no filename is specified, a temporary file is created.
315 If no filename is specified, a temporary file is created.
316 bz2 compression can be turned off.
316 bz2 compression can be turned off.
317 The bundle file will be deleted in case of errors.
317 The bundle file will be deleted in case of errors.
318 """
318 """
319 class nocompress(object):
319 class nocompress(object):
320 def compress(self, x):
320 def compress(self, x):
321 return x
321 return x
322 def flush(self):
322 def flush(self):
323 return ""
323 return ""
324
324
325 fh = None
325 fh = None
326 cleanup = None
326 cleanup = None
327 try:
327 try:
328 if filename:
328 if filename:
329 if os.path.exists(filename):
329 if os.path.exists(filename):
330 raise util.Abort(_("file '%s' already exists"), filename)
330 raise util.Abort(_("file '%s' already exists"), filename)
331 fh = open(filename, "wb")
331 fh = open(filename, "wb")
332 else:
332 else:
333 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
333 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
334 fh = os.fdopen(fd, "wb")
334 fh = os.fdopen(fd, "wb")
335 cleanup = filename
335 cleanup = filename
336
336
337 if compress:
337 if compress:
338 fh.write("HG10")
338 fh.write("HG10")
339 z = bz2.BZ2Compressor(9)
339 z = bz2.BZ2Compressor(9)
340 else:
340 else:
341 fh.write("HG10UN")
341 fh.write("HG10UN")
342 z = nocompress()
342 z = nocompress()
343 # parse the changegroup data, otherwise we will block
343 # parse the changegroup data, otherwise we will block
344 # in case of sshrepo because we don't know the end of the stream
344 # in case of sshrepo because we don't know the end of the stream
345
345
346 # an empty chunkiter is the end of the changegroup
346 # an empty chunkiter is the end of the changegroup
347 empty = False
347 empty = False
348 while not empty:
348 while not empty:
349 empty = True
349 empty = True
350 for chunk in changegroup.chunkiter(cg):
350 for chunk in changegroup.chunkiter(cg):
351 empty = False
351 empty = False
352 fh.write(z.compress(changegroup.genchunk(chunk)))
352 fh.write(z.compress(changegroup.genchunk(chunk)))
353 fh.write(z.compress(changegroup.closechunk()))
353 fh.write(z.compress(changegroup.closechunk()))
354 fh.write(z.flush())
354 fh.write(z.flush())
355 cleanup = None
355 cleanup = None
356 return filename
356 return filename
357 finally:
357 finally:
358 if fh is not None:
358 if fh is not None:
359 fh.close()
359 fh.close()
360 if cleanup is not None:
360 if cleanup is not None:
361 os.unlink(cleanup)
361 os.unlink(cleanup)
362
362
363 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always,
363 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always,
364 changes=None, text=False, opts={}):
364 changes=None, text=False, opts={}):
365 if not node1:
365 if not node1:
366 node1 = repo.dirstate.parents()[0]
366 node1 = repo.dirstate.parents()[0]
367 # reading the data for node1 early allows it to play nicely
367 # reading the data for node1 early allows it to play nicely
368 # with repo.changes and the revlog cache.
368 # with repo.changes and the revlog cache.
369 change = repo.changelog.read(node1)
369 change = repo.changelog.read(node1)
370 mmap = repo.manifest.read(change[0])
370 mmap = repo.manifest.read(change[0])
371 date1 = util.datestr(change[2])
371 date1 = util.datestr(change[2])
372
372
373 if not changes:
373 if not changes:
374 changes = repo.changes(node1, node2, files, match=match)
374 changes = repo.changes(node1, node2, files, match=match)
375 modified, added, removed, deleted, unknown = changes
375 modified, added, removed, deleted, unknown = changes
376 if files:
376 if files:
377 modified, added, removed = map(lambda x: filterfiles(files, x),
377 modified, added, removed = map(lambda x: filterfiles(files, x),
378 (modified, added, removed))
378 (modified, added, removed))
379
379
380 if not modified and not added and not removed:
380 if not modified and not added and not removed:
381 return
381 return
382
382
383 if node2:
383 if node2:
384 change = repo.changelog.read(node2)
384 change = repo.changelog.read(node2)
385 mmap2 = repo.manifest.read(change[0])
385 mmap2 = repo.manifest.read(change[0])
386 _date2 = util.datestr(change[2])
386 _date2 = util.datestr(change[2])
387 def date2(f):
387 def date2(f):
388 return _date2
388 return _date2
389 def read(f):
389 def read(f):
390 return repo.file(f).read(mmap2[f])
390 return repo.file(f).read(mmap2[f])
391 else:
391 else:
392 tz = util.makedate()[1]
392 tz = util.makedate()[1]
393 _date2 = util.datestr()
393 _date2 = util.datestr()
394 def date2(f):
394 def date2(f):
395 try:
395 try:
396 return util.datestr((os.lstat(repo.wjoin(f)).st_mtime, tz))
396 return util.datestr((os.lstat(repo.wjoin(f)).st_mtime, tz))
397 except OSError, err:
397 except OSError, err:
398 if err.errno != errno.ENOENT: raise
398 if err.errno != errno.ENOENT: raise
399 return _date2
399 return _date2
400 def read(f):
400 def read(f):
401 return repo.wread(f)
401 return repo.wread(f)
402
402
403 if ui.quiet:
403 if ui.quiet:
404 r = None
404 r = None
405 else:
405 else:
406 hexfunc = ui.verbose and hex or short
406 hexfunc = ui.verbose and hex or short
407 r = [hexfunc(node) for node in [node1, node2] if node]
407 r = [hexfunc(node) for node in [node1, node2] if node]
408
408
409 diffopts = ui.diffopts()
409 diffopts = ui.diffopts()
410 showfunc = opts.get('show_function') or diffopts['showfunc']
410 showfunc = opts.get('show_function') or diffopts['showfunc']
411 ignorews = opts.get('ignore_all_space') or diffopts['ignorews']
411 ignorews = opts.get('ignore_all_space') or diffopts['ignorews']
412 ignorewsamount = opts.get('ignore_space_change') or \
412 ignorewsamount = opts.get('ignore_space_change') or \
413 diffopts['ignorewsamount']
413 diffopts['ignorewsamount']
414 ignoreblanklines = opts.get('ignore_blank_lines') or \
414 ignoreblanklines = opts.get('ignore_blank_lines') or \
415 diffopts['ignoreblanklines']
415 diffopts['ignoreblanklines']
416 for f in modified:
416 for f in modified:
417 to = None
417 to = None
418 if f in mmap:
418 if f in mmap:
419 to = repo.file(f).read(mmap[f])
419 to = repo.file(f).read(mmap[f])
420 tn = read(f)
420 tn = read(f)
421 fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, text=text,
421 fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, text=text,
422 showfunc=showfunc, ignorews=ignorews,
422 showfunc=showfunc, ignorews=ignorews,
423 ignorewsamount=ignorewsamount,
423 ignorewsamount=ignorewsamount,
424 ignoreblanklines=ignoreblanklines))
424 ignoreblanklines=ignoreblanklines))
425 for f in added:
425 for f in added:
426 to = None
426 to = None
427 tn = read(f)
427 tn = read(f)
428 fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, text=text,
428 fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, text=text,
429 showfunc=showfunc, ignorews=ignorews,
429 showfunc=showfunc, ignorews=ignorews,
430 ignorewsamount=ignorewsamount,
430 ignorewsamount=ignorewsamount,
431 ignoreblanklines=ignoreblanklines))
431 ignoreblanklines=ignoreblanklines))
432 for f in removed:
432 for f in removed:
433 to = repo.file(f).read(mmap[f])
433 to = repo.file(f).read(mmap[f])
434 tn = None
434 tn = None
435 fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, text=text,
435 fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, text=text,
436 showfunc=showfunc, ignorews=ignorews,
436 showfunc=showfunc, ignorews=ignorews,
437 ignorewsamount=ignorewsamount,
437 ignorewsamount=ignorewsamount,
438 ignoreblanklines=ignoreblanklines))
438 ignoreblanklines=ignoreblanklines))
439
439
440 def trimuser(ui, name, rev, revcache):
440 def trimuser(ui, name, rev, revcache):
441 """trim the name of the user who committed a change"""
441 """trim the name of the user who committed a change"""
442 user = revcache.get(rev)
442 user = revcache.get(rev)
443 if user is None:
443 if user is None:
444 user = revcache[rev] = ui.shortuser(name)
444 user = revcache[rev] = ui.shortuser(name)
445 return user
445 return user
446
446
447 class changeset_printer(object):
447 class changeset_printer(object):
448 '''show changeset information when templating not requested.'''
448 '''show changeset information when templating not requested.'''
449
449
450 def __init__(self, ui, repo):
450 def __init__(self, ui, repo):
451 self.ui = ui
451 self.ui = ui
452 self.repo = repo
452 self.repo = repo
453
453
454 def show(self, rev=0, changenode=None, brinfo=None):
454 def show(self, rev=0, changenode=None, brinfo=None):
455 '''show a single changeset or file revision'''
455 '''show a single changeset or file revision'''
456 log = self.repo.changelog
456 log = self.repo.changelog
457 if changenode is None:
457 if changenode is None:
458 changenode = log.node(rev)
458 changenode = log.node(rev)
459 elif not rev:
459 elif not rev:
460 rev = log.rev(changenode)
460 rev = log.rev(changenode)
461
461
462 if self.ui.quiet:
462 if self.ui.quiet:
463 self.ui.write("%d:%s\n" % (rev, short(changenode)))
463 self.ui.write("%d:%s\n" % (rev, short(changenode)))
464 return
464 return
465
465
466 changes = log.read(changenode)
466 changes = log.read(changenode)
467 date = util.datestr(changes[2])
467 date = util.datestr(changes[2])
468
468
469 parents = [(log.rev(p), self.ui.verbose and hex(p) or short(p))
469 parents = [(log.rev(p), self.ui.verbose and hex(p) or short(p))
470 for p in log.parents(changenode)
470 for p in log.parents(changenode)
471 if self.ui.debugflag or p != nullid]
471 if self.ui.debugflag or p != nullid]
472 if (not self.ui.debugflag and len(parents) == 1 and
472 if (not self.ui.debugflag and len(parents) == 1 and
473 parents[0][0] == rev-1):
473 parents[0][0] == rev-1):
474 parents = []
474 parents = []
475
475
476 if self.ui.verbose:
476 if self.ui.verbose:
477 self.ui.write(_("changeset: %d:%s\n") % (rev, hex(changenode)))
477 self.ui.write(_("changeset: %d:%s\n") % (rev, hex(changenode)))
478 else:
478 else:
479 self.ui.write(_("changeset: %d:%s\n") % (rev, short(changenode)))
479 self.ui.write(_("changeset: %d:%s\n") % (rev, short(changenode)))
480
480
481 for tag in self.repo.nodetags(changenode):
481 for tag in self.repo.nodetags(changenode):
482 self.ui.status(_("tag: %s\n") % tag)
482 self.ui.status(_("tag: %s\n") % tag)
483 for parent in parents:
483 for parent in parents:
484 self.ui.write(_("parent: %d:%s\n") % parent)
484 self.ui.write(_("parent: %d:%s\n") % parent)
485
485
486 if brinfo and changenode in brinfo:
486 if brinfo and changenode in brinfo:
487 br = brinfo[changenode]
487 br = brinfo[changenode]
488 self.ui.write(_("branch: %s\n") % " ".join(br))
488 self.ui.write(_("branch: %s\n") % " ".join(br))
489
489
490 self.ui.debug(_("manifest: %d:%s\n") %
490 self.ui.debug(_("manifest: %d:%s\n") %
491 (self.repo.manifest.rev(changes[0]), hex(changes[0])))
491 (self.repo.manifest.rev(changes[0]), hex(changes[0])))
492 self.ui.status(_("user: %s\n") % changes[1])
492 self.ui.status(_("user: %s\n") % changes[1])
493 self.ui.status(_("date: %s\n") % date)
493 self.ui.status(_("date: %s\n") % date)
494
494
495 if self.ui.debugflag:
495 if self.ui.debugflag:
496 files = self.repo.changes(log.parents(changenode)[0], changenode)
496 files = self.repo.changes(log.parents(changenode)[0], changenode)
497 for key, value in zip([_("files:"), _("files+:"), _("files-:")],
497 for key, value in zip([_("files:"), _("files+:"), _("files-:")],
498 files):
498 files):
499 if value:
499 if value:
500 self.ui.note("%-12s %s\n" % (key, " ".join(value)))
500 self.ui.note("%-12s %s\n" % (key, " ".join(value)))
501 else:
501 else:
502 self.ui.note(_("files: %s\n") % " ".join(changes[3]))
502 self.ui.note(_("files: %s\n") % " ".join(changes[3]))
503
503
504 description = changes[4].strip()
504 description = changes[4].strip()
505 if description:
505 if description:
506 if self.ui.verbose:
506 if self.ui.verbose:
507 self.ui.status(_("description:\n"))
507 self.ui.status(_("description:\n"))
508 self.ui.status(description)
508 self.ui.status(description)
509 self.ui.status("\n\n")
509 self.ui.status("\n\n")
510 else:
510 else:
511 self.ui.status(_("summary: %s\n") %
511 self.ui.status(_("summary: %s\n") %
512 description.splitlines()[0])
512 description.splitlines()[0])
513 self.ui.status("\n")
513 self.ui.status("\n")
514
514
515 def show_changeset(ui, repo, opts):
515 def show_changeset(ui, repo, opts):
516 '''show one changeset. uses template or regular display. caller
516 '''show one changeset. uses template or regular display. caller
517 can pass in 'style' and 'template' options in opts.'''
517 can pass in 'style' and 'template' options in opts.'''
518
518
519 tmpl = opts.get('template')
519 tmpl = opts.get('template')
520 if tmpl:
520 if tmpl:
521 tmpl = templater.parsestring(tmpl, quoted=False)
521 tmpl = templater.parsestring(tmpl, quoted=False)
522 else:
522 else:
523 tmpl = ui.config('ui', 'logtemplate')
523 tmpl = ui.config('ui', 'logtemplate')
524 if tmpl: tmpl = templater.parsestring(tmpl)
524 if tmpl: tmpl = templater.parsestring(tmpl)
525 mapfile = opts.get('style') or ui.config('ui', 'style')
525 mapfile = opts.get('style') or ui.config('ui', 'style')
526 if tmpl or mapfile:
526 if tmpl or mapfile:
527 if mapfile:
527 if mapfile:
528 if not os.path.isfile(mapfile):
528 if not os.path.isfile(mapfile):
529 mapname = templater.templatepath('map-cmdline.' + mapfile)
529 mapname = templater.templatepath('map-cmdline.' + mapfile)
530 if not mapname: mapname = templater.templatepath(mapfile)
530 if not mapname: mapname = templater.templatepath(mapfile)
531 if mapname: mapfile = mapname
531 if mapname: mapfile = mapname
532 try:
532 try:
533 t = templater.changeset_templater(ui, repo, mapfile)
533 t = templater.changeset_templater(ui, repo, mapfile)
534 except SyntaxError, inst:
534 except SyntaxError, inst:
535 raise util.Abort(inst.args[0])
535 raise util.Abort(inst.args[0])
536 if tmpl: t.use_template(tmpl)
536 if tmpl: t.use_template(tmpl)
537 return t
537 return t
538 return changeset_printer(ui, repo)
538 return changeset_printer(ui, repo)
539
539
540 def show_version(ui):
540 def show_version(ui):
541 """output version and copyright information"""
541 """output version and copyright information"""
542 ui.write(_("Mercurial Distributed SCM (version %s)\n")
542 ui.write(_("Mercurial Distributed SCM (version %s)\n")
543 % version.get_version())
543 % version.get_version())
544 ui.status(_(
544 ui.status(_(
545 "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
545 "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
546 "This is free software; see the source for copying conditions. "
546 "This is free software; see the source for copying conditions. "
547 "There is NO\nwarranty; "
547 "There is NO\nwarranty; "
548 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
548 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
549 ))
549 ))
550
550
551 def help_(ui, name=None, with_version=False):
551 def help_(ui, name=None, with_version=False):
552 """show help for a command, extension, or list of commands
552 """show help for a command, extension, or list of commands
553
553
554 With no arguments, print a list of commands and short help.
554 With no arguments, print a list of commands and short help.
555
555
556 Given a command name, print help for that command.
556 Given a command name, print help for that command.
557
557
558 Given an extension name, print help for that extension, and the
558 Given an extension name, print help for that extension, and the
559 commands it provides."""
559 commands it provides."""
560 option_lists = []
560 option_lists = []
561
561
562 def helpcmd(name):
562 def helpcmd(name):
563 if with_version:
563 if with_version:
564 show_version(ui)
564 show_version(ui)
565 ui.write('\n')
565 ui.write('\n')
566 aliases, i = findcmd(name)
566 aliases, i = findcmd(name)
567 # synopsis
567 # synopsis
568 ui.write("%s\n\n" % i[2])
568 ui.write("%s\n\n" % i[2])
569
569
570 # description
570 # description
571 doc = i[0].__doc__
571 doc = i[0].__doc__
572 if not doc:
572 if not doc:
573 doc = _("(No help text available)")
573 doc = _("(No help text available)")
574 if ui.quiet:
574 if ui.quiet:
575 doc = doc.splitlines(0)[0]
575 doc = doc.splitlines(0)[0]
576 ui.write("%s\n" % doc.rstrip())
576 ui.write("%s\n" % doc.rstrip())
577
577
578 if not ui.quiet:
578 if not ui.quiet:
579 # aliases
579 # aliases
580 if len(aliases) > 1:
580 if len(aliases) > 1:
581 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
581 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
582
582
583 # options
583 # options
584 if i[1]:
584 if i[1]:
585 option_lists.append(("options", i[1]))
585 option_lists.append(("options", i[1]))
586
586
587 def helplist(select=None):
587 def helplist(select=None):
588 h = {}
588 h = {}
589 cmds = {}
589 cmds = {}
590 for c, e in table.items():
590 for c, e in table.items():
591 f = c.split("|", 1)[0]
591 f = c.split("|", 1)[0]
592 if select and not select(f):
592 if select and not select(f):
593 continue
593 continue
594 if name == "shortlist" and not f.startswith("^"):
594 if name == "shortlist" and not f.startswith("^"):
595 continue
595 continue
596 f = f.lstrip("^")
596 f = f.lstrip("^")
597 if not ui.debugflag and f.startswith("debug"):
597 if not ui.debugflag and f.startswith("debug"):
598 continue
598 continue
599 doc = e[0].__doc__
599 doc = e[0].__doc__
600 if not doc:
600 if not doc:
601 doc = _("(No help text available)")
601 doc = _("(No help text available)")
602 h[f] = doc.splitlines(0)[0].rstrip()
602 h[f] = doc.splitlines(0)[0].rstrip()
603 cmds[f] = c.lstrip("^")
603 cmds[f] = c.lstrip("^")
604
604
605 fns = h.keys()
605 fns = h.keys()
606 fns.sort()
606 fns.sort()
607 m = max(map(len, fns))
607 m = max(map(len, fns))
608 for f in fns:
608 for f in fns:
609 if ui.verbose:
609 if ui.verbose:
610 commands = cmds[f].replace("|",", ")
610 commands = cmds[f].replace("|",", ")
611 ui.write(" %s:\n %s\n"%(commands, h[f]))
611 ui.write(" %s:\n %s\n"%(commands, h[f]))
612 else:
612 else:
613 ui.write(' %-*s %s\n' % (m, f, h[f]))
613 ui.write(' %-*s %s\n' % (m, f, h[f]))
614
614
615 def helpext(name):
615 def helpext(name):
616 try:
616 try:
617 mod = findext(name)
617 mod = findext(name)
618 except KeyError:
618 except KeyError:
619 raise UnknownCommand(name)
619 raise UnknownCommand(name)
620
620
621 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
621 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
622 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
622 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
623 for d in doc[1:]:
623 for d in doc[1:]:
624 ui.write(d, '\n')
624 ui.write(d, '\n')
625
625
626 ui.status('\n')
626 ui.status('\n')
627 if ui.verbose:
627 if ui.verbose:
628 ui.status(_('list of commands:\n\n'))
628 ui.status(_('list of commands:\n\n'))
629 else:
629 else:
630 ui.status(_('list of commands (use "hg help -v %s" '
630 ui.status(_('list of commands (use "hg help -v %s" '
631 'to show aliases and global options):\n\n') % name)
631 'to show aliases and global options):\n\n') % name)
632
632
633 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in mod.cmdtable])
633 modcmds = dict.fromkeys([c.split('|', 1)[0] for c in mod.cmdtable])
634 helplist(modcmds.has_key)
634 helplist(modcmds.has_key)
635
635
636 if name and name != 'shortlist':
636 if name and name != 'shortlist':
637 try:
637 try:
638 helpcmd(name)
638 helpcmd(name)
639 except UnknownCommand:
639 except UnknownCommand:
640 helpext(name)
640 helpext(name)
641
641
642 else:
642 else:
643 # program name
643 # program name
644 if ui.verbose or with_version:
644 if ui.verbose or with_version:
645 show_version(ui)
645 show_version(ui)
646 else:
646 else:
647 ui.status(_("Mercurial Distributed SCM\n"))
647 ui.status(_("Mercurial Distributed SCM\n"))
648 ui.status('\n')
648 ui.status('\n')
649
649
650 # list of commands
650 # list of commands
651 if name == "shortlist":
651 if name == "shortlist":
652 ui.status(_('basic commands (use "hg help" '
652 ui.status(_('basic commands (use "hg help" '
653 'for the full list or option "-v" for details):\n\n'))
653 'for the full list or option "-v" for details):\n\n'))
654 elif ui.verbose:
654 elif ui.verbose:
655 ui.status(_('list of commands:\n\n'))
655 ui.status(_('list of commands:\n\n'))
656 else:
656 else:
657 ui.status(_('list of commands (use "hg help -v" '
657 ui.status(_('list of commands (use "hg help -v" '
658 'to show aliases and global options):\n\n'))
658 'to show aliases and global options):\n\n'))
659
659
660 helplist()
660 helplist()
661
661
662 # global options
662 # global options
663 if ui.verbose:
663 if ui.verbose:
664 option_lists.append(("global options", globalopts))
664 option_lists.append(("global options", globalopts))
665
665
666 # list all option lists
666 # list all option lists
667 opt_output = []
667 opt_output = []
668 for title, options in option_lists:
668 for title, options in option_lists:
669 opt_output.append(("\n%s:\n" % title, None))
669 opt_output.append(("\n%s:\n" % title, None))
670 for shortopt, longopt, default, desc in options:
670 for shortopt, longopt, default, desc in options:
671 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
671 opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
672 longopt and " --%s" % longopt),
672 longopt and " --%s" % longopt),
673 "%s%s" % (desc,
673 "%s%s" % (desc,
674 default
674 default
675 and _(" (default: %s)") % default
675 and _(" (default: %s)") % default
676 or "")))
676 or "")))
677
677
678 if opt_output:
678 if opt_output:
679 opts_len = max([len(line[0]) for line in opt_output if line[1]])
679 opts_len = max([len(line[0]) for line in opt_output if line[1]])
680 for first, second in opt_output:
680 for first, second in opt_output:
681 if second:
681 if second:
682 ui.write(" %-*s %s\n" % (opts_len, first, second))
682 ui.write(" %-*s %s\n" % (opts_len, first, second))
683 else:
683 else:
684 ui.write("%s\n" % first)
684 ui.write("%s\n" % first)
685
685
686 # Commands start here, listed alphabetically
686 # Commands start here, listed alphabetically
687
687
688 def add(ui, repo, *pats, **opts):
688 def add(ui, repo, *pats, **opts):
689 """add the specified files on the next commit
689 """add the specified files on the next commit
690
690
691 Schedule files to be version controlled and added to the repository.
691 Schedule files to be version controlled and added to the repository.
692
692
693 The files will be added to the repository at the next commit.
693 The files will be added to the repository at the next commit.
694
694
695 If no names are given, add all files in the repository.
695 If no names are given, add all files in the repository.
696 """
696 """
697
697
698 names = []
698 names = []
699 for src, abs, rel, exact in walk(repo, pats, opts):
699 for src, abs, rel, exact in walk(repo, pats, opts):
700 if exact:
700 if exact:
701 if ui.verbose:
701 if ui.verbose:
702 ui.status(_('adding %s\n') % rel)
702 ui.status(_('adding %s\n') % rel)
703 names.append(abs)
703 names.append(abs)
704 elif repo.dirstate.state(abs) == '?':
704 elif repo.dirstate.state(abs) == '?':
705 ui.status(_('adding %s\n') % rel)
705 ui.status(_('adding %s\n') % rel)
706 names.append(abs)
706 names.append(abs)
707 if not opts.get('dry_run'):
707 if not opts.get('dry_run'):
708 repo.add(names)
708 repo.add(names)
709
709
710 def addremove(ui, repo, *pats, **opts):
710 def addremove(ui, repo, *pats, **opts):
711 """add all new files, delete all missing files (DEPRECATED)
711 """add all new files, delete all missing files (DEPRECATED)
712
712
713 (DEPRECATED)
714 Add all new files and remove all missing files from the repository.
713 Add all new files and remove all missing files from the repository.
715
714
716 New files are ignored if they match any of the patterns in .hgignore. As
715 New files are ignored if they match any of the patterns in .hgignore. As
717 with add, these changes take effect at the next commit.
716 with add, these changes take effect at the next commit.
718
719 This command is now deprecated and will be removed in a future
720 release. Please use add and remove --after instead.
721 """
717 """
722 ui.warn(_('(the addremove command is deprecated; use add and remove '
723 '--after instead)\n'))
724 return addremove_lock(ui, repo, pats, opts)
718 return addremove_lock(ui, repo, pats, opts)
725
719
726 def addremove_lock(ui, repo, pats, opts, wlock=None):
720 def addremove_lock(ui, repo, pats, opts, wlock=None):
727 add, remove = [], []
721 add, remove = [], []
728 for src, abs, rel, exact in walk(repo, pats, opts):
722 for src, abs, rel, exact in walk(repo, pats, opts):
729 if src == 'f' and repo.dirstate.state(abs) == '?':
723 if src == 'f' and repo.dirstate.state(abs) == '?':
730 add.append(abs)
724 add.append(abs)
731 if ui.verbose or not exact:
725 if ui.verbose or not exact:
732 ui.status(_('adding %s\n') % ((pats and rel) or abs))
726 ui.status(_('adding %s\n') % ((pats and rel) or abs))
733 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
727 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
734 remove.append(abs)
728 remove.append(abs)
735 if ui.verbose or not exact:
729 if ui.verbose or not exact:
736 ui.status(_('removing %s\n') % ((pats and rel) or abs))
730 ui.status(_('removing %s\n') % ((pats and rel) or abs))
737 if not opts.get('dry_run'):
731 if not opts.get('dry_run'):
738 repo.add(add, wlock=wlock)
732 repo.add(add, wlock=wlock)
739 repo.remove(remove, wlock=wlock)
733 repo.remove(remove, wlock=wlock)
740
734
741 def annotate(ui, repo, *pats, **opts):
735 def annotate(ui, repo, *pats, **opts):
742 """show changeset information per file line
736 """show changeset information per file line
743
737
744 List changes in files, showing the revision id responsible for each line
738 List changes in files, showing the revision id responsible for each line
745
739
746 This command is useful to discover who did a change or when a change took
740 This command is useful to discover who did a change or when a change took
747 place.
741 place.
748
742
749 Without the -a option, annotate will avoid processing files it
743 Without the -a option, annotate will avoid processing files it
750 detects as binary. With -a, annotate will generate an annotation
744 detects as binary. With -a, annotate will generate an annotation
751 anyway, probably with undesirable results.
745 anyway, probably with undesirable results.
752 """
746 """
753 def getnode(rev):
747 def getnode(rev):
754 return short(repo.changelog.node(rev))
748 return short(repo.changelog.node(rev))
755
749
756 ucache = {}
750 ucache = {}
757 def getname(rev):
751 def getname(rev):
758 try:
752 try:
759 return ucache[rev]
753 return ucache[rev]
760 except:
754 except:
761 u = trimuser(ui, repo.changectx(rev).user(), rev, ucache)
755 u = trimuser(ui, repo.changectx(rev).user(), rev, ucache)
762 ucache[rev] = u
756 ucache[rev] = u
763 return u
757 return u
764
758
765 dcache = {}
759 dcache = {}
766 def getdate(rev):
760 def getdate(rev):
767 datestr = dcache.get(rev)
761 datestr = dcache.get(rev)
768 if datestr is None:
762 if datestr is None:
769 datestr = dcache[rev] = util.datestr(repo.changectx(rev).date())
763 datestr = dcache[rev] = util.datestr(repo.changectx(rev).date())
770 return datestr
764 return datestr
771
765
772 if not pats:
766 if not pats:
773 raise util.Abort(_('at least one file name or pattern required'))
767 raise util.Abort(_('at least one file name or pattern required'))
774
768
775 opmap = [['user', getname], ['number', str], ['changeset', getnode],
769 opmap = [['user', getname], ['number', str], ['changeset', getnode],
776 ['date', getdate]]
770 ['date', getdate]]
777 if not opts['user'] and not opts['changeset'] and not opts['date']:
771 if not opts['user'] and not opts['changeset'] and not opts['date']:
778 opts['number'] = 1
772 opts['number'] = 1
779
773
780 ctx = repo.changectx(opts['rev'] or repo.dirstate.parents()[0])
774 ctx = repo.changectx(opts['rev'] or repo.dirstate.parents()[0])
781
775
782 for src, abs, rel, exact in walk(repo, pats, opts, node=ctx.node()):
776 for src, abs, rel, exact in walk(repo, pats, opts, node=ctx.node()):
783 fctx = ctx.filectx(abs)
777 fctx = ctx.filectx(abs)
784 if not opts['text'] and util.binary(fctx.data()):
778 if not opts['text'] and util.binary(fctx.data()):
785 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
779 ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
786 continue
780 continue
787
781
788 lines = fctx.annotate()
782 lines = fctx.annotate()
789 pieces = []
783 pieces = []
790
784
791 for o, f in opmap:
785 for o, f in opmap:
792 if opts[o]:
786 if opts[o]:
793 l = [f(n) for n, dummy in lines]
787 l = [f(n) for n, dummy in lines]
794 if l:
788 if l:
795 m = max(map(len, l))
789 m = max(map(len, l))
796 pieces.append(["%*s" % (m, x) for x in l])
790 pieces.append(["%*s" % (m, x) for x in l])
797
791
798 if pieces:
792 if pieces:
799 for p, l in zip(zip(*pieces), lines):
793 for p, l in zip(zip(*pieces), lines):
800 ui.write("%s: %s" % (" ".join(p), l[1]))
794 ui.write("%s: %s" % (" ".join(p), l[1]))
801
795
802 def archive(ui, repo, dest, **opts):
796 def archive(ui, repo, dest, **opts):
803 '''create unversioned archive of a repository revision
797 '''create unversioned archive of a repository revision
804
798
805 By default, the revision used is the parent of the working
799 By default, the revision used is the parent of the working
806 directory; use "-r" to specify a different revision.
800 directory; use "-r" to specify a different revision.
807
801
808 To specify the type of archive to create, use "-t". Valid
802 To specify the type of archive to create, use "-t". Valid
809 types are:
803 types are:
810
804
811 "files" (default): a directory full of files
805 "files" (default): a directory full of files
812 "tar": tar archive, uncompressed
806 "tar": tar archive, uncompressed
813 "tbz2": tar archive, compressed using bzip2
807 "tbz2": tar archive, compressed using bzip2
814 "tgz": tar archive, compressed using gzip
808 "tgz": tar archive, compressed using gzip
815 "uzip": zip archive, uncompressed
809 "uzip": zip archive, uncompressed
816 "zip": zip archive, compressed using deflate
810 "zip": zip archive, compressed using deflate
817
811
818 The exact name of the destination archive or directory is given
812 The exact name of the destination archive or directory is given
819 using a format string; see "hg help export" for details.
813 using a format string; see "hg help export" for details.
820
814
821 Each member added to an archive file has a directory prefix
815 Each member added to an archive file has a directory prefix
822 prepended. Use "-p" to specify a format string for the prefix.
816 prepended. Use "-p" to specify a format string for the prefix.
823 The default is the basename of the archive, with suffixes removed.
817 The default is the basename of the archive, with suffixes removed.
824 '''
818 '''
825
819
826 if opts['rev']:
820 if opts['rev']:
827 node = repo.lookup(opts['rev'])
821 node = repo.lookup(opts['rev'])
828 else:
822 else:
829 node, p2 = repo.dirstate.parents()
823 node, p2 = repo.dirstate.parents()
830 if p2 != nullid:
824 if p2 != nullid:
831 raise util.Abort(_('uncommitted merge - please provide a '
825 raise util.Abort(_('uncommitted merge - please provide a '
832 'specific revision'))
826 'specific revision'))
833
827
834 dest = make_filename(repo, dest, node)
828 dest = make_filename(repo, dest, node)
835 if os.path.realpath(dest) == repo.root:
829 if os.path.realpath(dest) == repo.root:
836 raise util.Abort(_('repository root cannot be destination'))
830 raise util.Abort(_('repository root cannot be destination'))
837 dummy, matchfn, dummy = matchpats(repo, [], opts)
831 dummy, matchfn, dummy = matchpats(repo, [], opts)
838 kind = opts.get('type') or 'files'
832 kind = opts.get('type') or 'files'
839 prefix = opts['prefix']
833 prefix = opts['prefix']
840 if dest == '-':
834 if dest == '-':
841 if kind == 'files':
835 if kind == 'files':
842 raise util.Abort(_('cannot archive plain files to stdout'))
836 raise util.Abort(_('cannot archive plain files to stdout'))
843 dest = sys.stdout
837 dest = sys.stdout
844 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
838 if not prefix: prefix = os.path.basename(repo.root) + '-%h'
845 prefix = make_filename(repo, prefix, node)
839 prefix = make_filename(repo, prefix, node)
846 archival.archive(repo, dest, node, kind, not opts['no_decode'],
840 archival.archive(repo, dest, node, kind, not opts['no_decode'],
847 matchfn, prefix)
841 matchfn, prefix)
848
842
849 def backout(ui, repo, rev, **opts):
843 def backout(ui, repo, rev, **opts):
850 '''reverse effect of earlier changeset
844 '''reverse effect of earlier changeset
851
845
852 Commit the backed out changes as a new changeset. The new
846 Commit the backed out changes as a new changeset. The new
853 changeset is a child of the backed out changeset.
847 changeset is a child of the backed out changeset.
854
848
855 If you back out a changeset other than the tip, a new head is
849 If you back out a changeset other than the tip, a new head is
856 created. This head is the parent of the working directory. If
850 created. This head is the parent of the working directory. If
857 you back out an old changeset, your working directory will appear
851 you back out an old changeset, your working directory will appear
858 old after the backout. You should merge the backout changeset
852 old after the backout. You should merge the backout changeset
859 with another head.
853 with another head.
860
854
861 The --merge option remembers the parent of the working directory
855 The --merge option remembers the parent of the working directory
862 before starting the backout, then merges the new head with that
856 before starting the backout, then merges the new head with that
863 changeset afterwards. This saves you from doing the merge by
857 changeset afterwards. This saves you from doing the merge by
864 hand. The result of this merge is not committed, as for a normal
858 hand. The result of this merge is not committed, as for a normal
865 merge.'''
859 merge.'''
866
860
867 bail_if_changed(repo)
861 bail_if_changed(repo)
868 op1, op2 = repo.dirstate.parents()
862 op1, op2 = repo.dirstate.parents()
869 if op2 != nullid:
863 if op2 != nullid:
870 raise util.Abort(_('outstanding uncommitted merge'))
864 raise util.Abort(_('outstanding uncommitted merge'))
871 node = repo.lookup(rev)
865 node = repo.lookup(rev)
872 p1, p2 = repo.changelog.parents(node)
866 p1, p2 = repo.changelog.parents(node)
873 if p1 == nullid:
867 if p1 == nullid:
874 raise util.Abort(_('cannot back out a change with no parents'))
868 raise util.Abort(_('cannot back out a change with no parents'))
875 if p2 != nullid:
869 if p2 != nullid:
876 if not opts['parent']:
870 if not opts['parent']:
877 raise util.Abort(_('cannot back out a merge changeset without '
871 raise util.Abort(_('cannot back out a merge changeset without '
878 '--parent'))
872 '--parent'))
879 p = repo.lookup(opts['parent'])
873 p = repo.lookup(opts['parent'])
880 if p not in (p1, p2):
874 if p not in (p1, p2):
881 raise util.Abort(_('%s is not a parent of %s' %
875 raise util.Abort(_('%s is not a parent of %s' %
882 (short(p), short(node))))
876 (short(p), short(node))))
883 parent = p
877 parent = p
884 else:
878 else:
885 if opts['parent']:
879 if opts['parent']:
886 raise util.Abort(_('cannot use --parent on non-merge changeset'))
880 raise util.Abort(_('cannot use --parent on non-merge changeset'))
887 parent = p1
881 parent = p1
888 repo.update(node, force=True, show_stats=False)
882 repo.update(node, force=True, show_stats=False)
889 revert_opts = opts.copy()
883 revert_opts = opts.copy()
890 revert_opts['rev'] = hex(parent)
884 revert_opts['rev'] = hex(parent)
891 revert(ui, repo, **revert_opts)
885 revert(ui, repo, **revert_opts)
892 commit_opts = opts.copy()
886 commit_opts = opts.copy()
893 commit_opts['addremove'] = False
887 commit_opts['addremove'] = False
894 if not commit_opts['message'] and not commit_opts['logfile']:
888 if not commit_opts['message'] and not commit_opts['logfile']:
895 commit_opts['message'] = _("Backed out changeset %s") % (hex(node))
889 commit_opts['message'] = _("Backed out changeset %s") % (hex(node))
896 commit_opts['force_editor'] = True
890 commit_opts['force_editor'] = True
897 commit(ui, repo, **commit_opts)
891 commit(ui, repo, **commit_opts)
898 def nice(node):
892 def nice(node):
899 return '%d:%s' % (repo.changelog.rev(node), short(node))
893 return '%d:%s' % (repo.changelog.rev(node), short(node))
900 ui.status(_('changeset %s backs out changeset %s\n') %
894 ui.status(_('changeset %s backs out changeset %s\n') %
901 (nice(repo.changelog.tip()), nice(node)))
895 (nice(repo.changelog.tip()), nice(node)))
902 if op1 != node:
896 if op1 != node:
903 if opts['merge']:
897 if opts['merge']:
904 ui.status(_('merging with changeset %s\n') % nice(op1))
898 ui.status(_('merging with changeset %s\n') % nice(op1))
905 doupdate(ui, repo, hex(op1), **opts)
899 doupdate(ui, repo, hex(op1), **opts)
906 else:
900 else:
907 ui.status(_('the backout changeset is a new head - '
901 ui.status(_('the backout changeset is a new head - '
908 'do not forget to merge\n'))
902 'do not forget to merge\n'))
909 ui.status(_('(use "backout -m" if you want to auto-merge)\n'))
903 ui.status(_('(use "backout -m" if you want to auto-merge)\n'))
910
904
911 def bundle(ui, repo, fname, dest=None, **opts):
905 def bundle(ui, repo, fname, dest=None, **opts):
912 """create a changegroup file
906 """create a changegroup file
913
907
914 Generate a compressed changegroup file collecting all changesets
908 Generate a compressed changegroup file collecting all changesets
915 not found in the other repository.
909 not found in the other repository.
916
910
917 This file can then be transferred using conventional means and
911 This file can then be transferred using conventional means and
918 applied to another repository with the unbundle command. This is
912 applied to another repository with the unbundle command. This is
919 useful when native push and pull are not available or when
913 useful when native push and pull are not available or when
920 exporting an entire repository is undesirable. The standard file
914 exporting an entire repository is undesirable. The standard file
921 extension is ".hg".
915 extension is ".hg".
922
916
923 Unlike import/export, this exactly preserves all changeset
917 Unlike import/export, this exactly preserves all changeset
924 contents including permissions, rename data, and revision history.
918 contents including permissions, rename data, and revision history.
925 """
919 """
926 dest = ui.expandpath(dest or 'default-push', dest or 'default')
920 dest = ui.expandpath(dest or 'default-push', dest or 'default')
927 other = hg.repository(ui, dest)
921 other = hg.repository(ui, dest)
928 o = repo.findoutgoing(other, force=opts['force'])
922 o = repo.findoutgoing(other, force=opts['force'])
929 cg = repo.changegroup(o, 'bundle')
923 cg = repo.changegroup(o, 'bundle')
930 write_bundle(cg, fname)
924 write_bundle(cg, fname)
931
925
932 def cat(ui, repo, file1, *pats, **opts):
926 def cat(ui, repo, file1, *pats, **opts):
933 """output the latest or given revisions of files
927 """output the latest or given revisions of files
934
928
935 Print the specified files as they were at the given revision.
929 Print the specified files as they were at the given revision.
936 If no revision is given then the tip is used.
930 If no revision is given then the tip is used.
937
931
938 Output may be to a file, in which case the name of the file is
932 Output may be to a file, in which case the name of the file is
939 given using a format string. The formatting rules are the same as
933 given using a format string. The formatting rules are the same as
940 for the export command, with the following additions:
934 for the export command, with the following additions:
941
935
942 %s basename of file being printed
936 %s basename of file being printed
943 %d dirname of file being printed, or '.' if in repo root
937 %d dirname of file being printed, or '.' if in repo root
944 %p root-relative path name of file being printed
938 %p root-relative path name of file being printed
945 """
939 """
946 ctx = repo.changectx(opts['rev'] or -1)
940 ctx = repo.changectx(opts['rev'] or -1)
947 for src, abs, rel, exact in walk(repo, (file1,) + pats, opts, ctx.node()):
941 for src, abs, rel, exact in walk(repo, (file1,) + pats, opts, ctx.node()):
948 fp = make_file(repo, opts['output'], ctx.node(), pathname=abs)
942 fp = make_file(repo, opts['output'], ctx.node(), pathname=abs)
949 fp.write(ctx.filectx(abs).data())
943 fp.write(ctx.filectx(abs).data())
950
944
951 def clone(ui, source, dest=None, **opts):
945 def clone(ui, source, dest=None, **opts):
952 """make a copy of an existing repository
946 """make a copy of an existing repository
953
947
954 Create a copy of an existing repository in a new directory.
948 Create a copy of an existing repository in a new directory.
955
949
956 If no destination directory name is specified, it defaults to the
950 If no destination directory name is specified, it defaults to the
957 basename of the source.
951 basename of the source.
958
952
959 The location of the source is added to the new repository's
953 The location of the source is added to the new repository's
960 .hg/hgrc file, as the default to be used for future pulls.
954 .hg/hgrc file, as the default to be used for future pulls.
961
955
962 For efficiency, hardlinks are used for cloning whenever the source
956 For efficiency, hardlinks are used for cloning whenever the source
963 and destination are on the same filesystem. Some filesystems,
957 and destination are on the same filesystem. Some filesystems,
964 such as AFS, implement hardlinking incorrectly, but do not report
958 such as AFS, implement hardlinking incorrectly, but do not report
965 errors. In these cases, use the --pull option to avoid
959 errors. In these cases, use the --pull option to avoid
966 hardlinking.
960 hardlinking.
967
961
968 See pull for valid source format details.
962 See pull for valid source format details.
969
963
970 It is possible to specify an ssh:// URL as the destination, but no
964 It is possible to specify an ssh:// URL as the destination, but no
971 .hg/hgrc will be created on the remote side. Look at the help text
965 .hg/hgrc will be created on the remote side. Look at the help text
972 for the pull command for important details about ssh:// URLs.
966 for the pull command for important details about ssh:// URLs.
973 """
967 """
974 ui.setconfig_remoteopts(**opts)
968 ui.setconfig_remoteopts(**opts)
975 hg.clone(ui, ui.expandpath(source), dest,
969 hg.clone(ui, ui.expandpath(source), dest,
976 pull=opts['pull'],
970 pull=opts['pull'],
977 stream=opts['uncompressed'],
971 stream=opts['uncompressed'],
978 rev=opts['rev'],
972 rev=opts['rev'],
979 update=not opts['noupdate'])
973 update=not opts['noupdate'])
980
974
981 def commit(ui, repo, *pats, **opts):
975 def commit(ui, repo, *pats, **opts):
982 """commit the specified files or all outstanding changes
976 """commit the specified files or all outstanding changes
983
977
984 Commit changes to the given files into the repository.
978 Commit changes to the given files into the repository.
985
979
986 If a list of files is omitted, all changes reported by "hg status"
980 If a list of files is omitted, all changes reported by "hg status"
987 will be committed.
981 will be committed.
988
982
989 If no commit message is specified, the editor configured in your hgrc
983 If no commit message is specified, the editor configured in your hgrc
990 or in the EDITOR environment variable is started to enter a message.
984 or in the EDITOR environment variable is started to enter a message.
991 """
985 """
992 message = opts['message']
986 message = opts['message']
993 logfile = opts['logfile']
987 logfile = opts['logfile']
994
988
995 if message and logfile:
989 if message and logfile:
996 raise util.Abort(_('options --message and --logfile are mutually '
990 raise util.Abort(_('options --message and --logfile are mutually '
997 'exclusive'))
991 'exclusive'))
998 if not message and logfile:
992 if not message and logfile:
999 try:
993 try:
1000 if logfile == '-':
994 if logfile == '-':
1001 message = sys.stdin.read()
995 message = sys.stdin.read()
1002 else:
996 else:
1003 message = open(logfile).read()
997 message = open(logfile).read()
1004 except IOError, inst:
998 except IOError, inst:
1005 raise util.Abort(_("can't read commit message '%s': %s") %
999 raise util.Abort(_("can't read commit message '%s': %s") %
1006 (logfile, inst.strerror))
1000 (logfile, inst.strerror))
1007
1001
1008 if opts['addremove']:
1002 if opts['addremove']:
1009 addremove_lock(ui, repo, pats, opts)
1003 addremove_lock(ui, repo, pats, opts)
1010 fns, match, anypats = matchpats(repo, pats, opts)
1004 fns, match, anypats = matchpats(repo, pats, opts)
1011 if pats:
1005 if pats:
1012 modified, added, removed, deleted, unknown = (
1006 modified, added, removed, deleted, unknown = (
1013 repo.changes(files=fns, match=match))
1007 repo.changes(files=fns, match=match))
1014 files = modified + added + removed
1008 files = modified + added + removed
1015 else:
1009 else:
1016 files = []
1010 files = []
1017 try:
1011 try:
1018 repo.commit(files, message, opts['user'], opts['date'], match,
1012 repo.commit(files, message, opts['user'], opts['date'], match,
1019 force_editor=opts.get('force_editor'))
1013 force_editor=opts.get('force_editor'))
1020 except ValueError, inst:
1014 except ValueError, inst:
1021 raise util.Abort(str(inst))
1015 raise util.Abort(str(inst))
1022
1016
1023 def docopy(ui, repo, pats, opts, wlock):
1017 def docopy(ui, repo, pats, opts, wlock):
1024 # called with the repo lock held
1018 # called with the repo lock held
1025 cwd = repo.getcwd()
1019 cwd = repo.getcwd()
1026 errors = 0
1020 errors = 0
1027 copied = []
1021 copied = []
1028 targets = {}
1022 targets = {}
1029
1023
1030 def okaytocopy(abs, rel, exact):
1024 def okaytocopy(abs, rel, exact):
1031 reasons = {'?': _('is not managed'),
1025 reasons = {'?': _('is not managed'),
1032 'a': _('has been marked for add'),
1026 'a': _('has been marked for add'),
1033 'r': _('has been marked for remove')}
1027 'r': _('has been marked for remove')}
1034 state = repo.dirstate.state(abs)
1028 state = repo.dirstate.state(abs)
1035 reason = reasons.get(state)
1029 reason = reasons.get(state)
1036 if reason:
1030 if reason:
1037 if state == 'a':
1031 if state == 'a':
1038 origsrc = repo.dirstate.copied(abs)
1032 origsrc = repo.dirstate.copied(abs)
1039 if origsrc is not None:
1033 if origsrc is not None:
1040 return origsrc
1034 return origsrc
1041 if exact:
1035 if exact:
1042 ui.warn(_('%s: not copying - file %s\n') % (rel, reason))
1036 ui.warn(_('%s: not copying - file %s\n') % (rel, reason))
1043 else:
1037 else:
1044 return abs
1038 return abs
1045
1039
1046 def copy(origsrc, abssrc, relsrc, target, exact):
1040 def copy(origsrc, abssrc, relsrc, target, exact):
1047 abstarget = util.canonpath(repo.root, cwd, target)
1041 abstarget = util.canonpath(repo.root, cwd, target)
1048 reltarget = util.pathto(cwd, abstarget)
1042 reltarget = util.pathto(cwd, abstarget)
1049 prevsrc = targets.get(abstarget)
1043 prevsrc = targets.get(abstarget)
1050 if prevsrc is not None:
1044 if prevsrc is not None:
1051 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
1045 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
1052 (reltarget, abssrc, prevsrc))
1046 (reltarget, abssrc, prevsrc))
1053 return
1047 return
1054 if (not opts['after'] and os.path.exists(reltarget) or
1048 if (not opts['after'] and os.path.exists(reltarget) or
1055 opts['after'] and repo.dirstate.state(abstarget) not in '?r'):
1049 opts['after'] and repo.dirstate.state(abstarget) not in '?r'):
1056 if not opts['force']:
1050 if not opts['force']:
1057 ui.warn(_('%s: not overwriting - file exists\n') %
1051 ui.warn(_('%s: not overwriting - file exists\n') %
1058 reltarget)
1052 reltarget)
1059 return
1053 return
1060 if not opts['after'] and not opts.get('dry_run'):
1054 if not opts['after'] and not opts.get('dry_run'):
1061 os.unlink(reltarget)
1055 os.unlink(reltarget)
1062 if opts['after']:
1056 if opts['after']:
1063 if not os.path.exists(reltarget):
1057 if not os.path.exists(reltarget):
1064 return
1058 return
1065 else:
1059 else:
1066 targetdir = os.path.dirname(reltarget) or '.'
1060 targetdir = os.path.dirname(reltarget) or '.'
1067 if not os.path.isdir(targetdir) and not opts.get('dry_run'):
1061 if not os.path.isdir(targetdir) and not opts.get('dry_run'):
1068 os.makedirs(targetdir)
1062 os.makedirs(targetdir)
1069 try:
1063 try:
1070 restore = repo.dirstate.state(abstarget) == 'r'
1064 restore = repo.dirstate.state(abstarget) == 'r'
1071 if restore and not opts.get('dry_run'):
1065 if restore and not opts.get('dry_run'):
1072 repo.undelete([abstarget], wlock)
1066 repo.undelete([abstarget], wlock)
1073 try:
1067 try:
1074 if not opts.get('dry_run'):
1068 if not opts.get('dry_run'):
1075 shutil.copyfile(relsrc, reltarget)
1069 shutil.copyfile(relsrc, reltarget)
1076 shutil.copymode(relsrc, reltarget)
1070 shutil.copymode(relsrc, reltarget)
1077 restore = False
1071 restore = False
1078 finally:
1072 finally:
1079 if restore:
1073 if restore:
1080 repo.remove([abstarget], wlock)
1074 repo.remove([abstarget], wlock)
1081 except shutil.Error, inst:
1075 except shutil.Error, inst:
1082 raise util.Abort(str(inst))
1076 raise util.Abort(str(inst))
1083 except IOError, inst:
1077 except IOError, inst:
1084 if inst.errno == errno.ENOENT:
1078 if inst.errno == errno.ENOENT:
1085 ui.warn(_('%s: deleted in working copy\n') % relsrc)
1079 ui.warn(_('%s: deleted in working copy\n') % relsrc)
1086 else:
1080 else:
1087 ui.warn(_('%s: cannot copy - %s\n') %
1081 ui.warn(_('%s: cannot copy - %s\n') %
1088 (relsrc, inst.strerror))
1082 (relsrc, inst.strerror))
1089 errors += 1
1083 errors += 1
1090 return
1084 return
1091 if ui.verbose or not exact:
1085 if ui.verbose or not exact:
1092 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
1086 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
1093 targets[abstarget] = abssrc
1087 targets[abstarget] = abssrc
1094 if abstarget != origsrc and not opts.get('dry_run'):
1088 if abstarget != origsrc and not opts.get('dry_run'):
1095 repo.copy(origsrc, abstarget, wlock)
1089 repo.copy(origsrc, abstarget, wlock)
1096 copied.append((abssrc, relsrc, exact))
1090 copied.append((abssrc, relsrc, exact))
1097
1091
1098 def targetpathfn(pat, dest, srcs):
1092 def targetpathfn(pat, dest, srcs):
1099 if os.path.isdir(pat):
1093 if os.path.isdir(pat):
1100 abspfx = util.canonpath(repo.root, cwd, pat)
1094 abspfx = util.canonpath(repo.root, cwd, pat)
1101 if destdirexists:
1095 if destdirexists:
1102 striplen = len(os.path.split(abspfx)[0])
1096 striplen = len(os.path.split(abspfx)[0])
1103 else:
1097 else:
1104 striplen = len(abspfx)
1098 striplen = len(abspfx)
1105 if striplen:
1099 if striplen:
1106 striplen += len(os.sep)
1100 striplen += len(os.sep)
1107 res = lambda p: os.path.join(dest, p[striplen:])
1101 res = lambda p: os.path.join(dest, p[striplen:])
1108 elif destdirexists:
1102 elif destdirexists:
1109 res = lambda p: os.path.join(dest, os.path.basename(p))
1103 res = lambda p: os.path.join(dest, os.path.basename(p))
1110 else:
1104 else:
1111 res = lambda p: dest
1105 res = lambda p: dest
1112 return res
1106 return res
1113
1107
1114 def targetpathafterfn(pat, dest, srcs):
1108 def targetpathafterfn(pat, dest, srcs):
1115 if util.patkind(pat, None)[0]:
1109 if util.patkind(pat, None)[0]:
1116 # a mercurial pattern
1110 # a mercurial pattern
1117 res = lambda p: os.path.join(dest, os.path.basename(p))
1111 res = lambda p: os.path.join(dest, os.path.basename(p))
1118 else:
1112 else:
1119 abspfx = util.canonpath(repo.root, cwd, pat)
1113 abspfx = util.canonpath(repo.root, cwd, pat)
1120 if len(abspfx) < len(srcs[0][0]):
1114 if len(abspfx) < len(srcs[0][0]):
1121 # A directory. Either the target path contains the last
1115 # A directory. Either the target path contains the last
1122 # component of the source path or it does not.
1116 # component of the source path or it does not.
1123 def evalpath(striplen):
1117 def evalpath(striplen):
1124 score = 0
1118 score = 0
1125 for s in srcs:
1119 for s in srcs:
1126 t = os.path.join(dest, s[0][striplen:])
1120 t = os.path.join(dest, s[0][striplen:])
1127 if os.path.exists(t):
1121 if os.path.exists(t):
1128 score += 1
1122 score += 1
1129 return score
1123 return score
1130
1124
1131 striplen = len(abspfx)
1125 striplen = len(abspfx)
1132 if striplen:
1126 if striplen:
1133 striplen += len(os.sep)
1127 striplen += len(os.sep)
1134 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
1128 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
1135 score = evalpath(striplen)
1129 score = evalpath(striplen)
1136 striplen1 = len(os.path.split(abspfx)[0])
1130 striplen1 = len(os.path.split(abspfx)[0])
1137 if striplen1:
1131 if striplen1:
1138 striplen1 += len(os.sep)
1132 striplen1 += len(os.sep)
1139 if evalpath(striplen1) > score:
1133 if evalpath(striplen1) > score:
1140 striplen = striplen1
1134 striplen = striplen1
1141 res = lambda p: os.path.join(dest, p[striplen:])
1135 res = lambda p: os.path.join(dest, p[striplen:])
1142 else:
1136 else:
1143 # a file
1137 # a file
1144 if destdirexists:
1138 if destdirexists:
1145 res = lambda p: os.path.join(dest, os.path.basename(p))
1139 res = lambda p: os.path.join(dest, os.path.basename(p))
1146 else:
1140 else:
1147 res = lambda p: dest
1141 res = lambda p: dest
1148 return res
1142 return res
1149
1143
1150
1144
1151 pats = list(pats)
1145 pats = list(pats)
1152 if not pats:
1146 if not pats:
1153 raise util.Abort(_('no source or destination specified'))
1147 raise util.Abort(_('no source or destination specified'))
1154 if len(pats) == 1:
1148 if len(pats) == 1:
1155 raise util.Abort(_('no destination specified'))
1149 raise util.Abort(_('no destination specified'))
1156 dest = pats.pop()
1150 dest = pats.pop()
1157 destdirexists = os.path.isdir(dest)
1151 destdirexists = os.path.isdir(dest)
1158 if (len(pats) > 1 or util.patkind(pats[0], None)[0]) and not destdirexists:
1152 if (len(pats) > 1 or util.patkind(pats[0], None)[0]) and not destdirexists:
1159 raise util.Abort(_('with multiple sources, destination must be an '
1153 raise util.Abort(_('with multiple sources, destination must be an '
1160 'existing directory'))
1154 'existing directory'))
1161 if opts['after']:
1155 if opts['after']:
1162 tfn = targetpathafterfn
1156 tfn = targetpathafterfn
1163 else:
1157 else:
1164 tfn = targetpathfn
1158 tfn = targetpathfn
1165 copylist = []
1159 copylist = []
1166 for pat in pats:
1160 for pat in pats:
1167 srcs = []
1161 srcs = []
1168 for tag, abssrc, relsrc, exact in walk(repo, [pat], opts):
1162 for tag, abssrc, relsrc, exact in walk(repo, [pat], opts):
1169 origsrc = okaytocopy(abssrc, relsrc, exact)
1163 origsrc = okaytocopy(abssrc, relsrc, exact)
1170 if origsrc:
1164 if origsrc:
1171 srcs.append((origsrc, abssrc, relsrc, exact))
1165 srcs.append((origsrc, abssrc, relsrc, exact))
1172 if not srcs:
1166 if not srcs:
1173 continue
1167 continue
1174 copylist.append((tfn(pat, dest, srcs), srcs))
1168 copylist.append((tfn(pat, dest, srcs), srcs))
1175 if not copylist:
1169 if not copylist:
1176 raise util.Abort(_('no files to copy'))
1170 raise util.Abort(_('no files to copy'))
1177
1171
1178 for targetpath, srcs in copylist:
1172 for targetpath, srcs in copylist:
1179 for origsrc, abssrc, relsrc, exact in srcs:
1173 for origsrc, abssrc, relsrc, exact in srcs:
1180 copy(origsrc, abssrc, relsrc, targetpath(abssrc), exact)
1174 copy(origsrc, abssrc, relsrc, targetpath(abssrc), exact)
1181
1175
1182 if errors:
1176 if errors:
1183 ui.warn(_('(consider using --after)\n'))
1177 ui.warn(_('(consider using --after)\n'))
1184 return errors, copied
1178 return errors, copied
1185
1179
1186 def copy(ui, repo, *pats, **opts):
1180 def copy(ui, repo, *pats, **opts):
1187 """mark files as copied for the next commit
1181 """mark files as copied for the next commit
1188
1182
1189 Mark dest as having copies of source files. If dest is a
1183 Mark dest as having copies of source files. If dest is a
1190 directory, copies are put in that directory. If dest is a file,
1184 directory, copies are put in that directory. If dest is a file,
1191 there can only be one source.
1185 there can only be one source.
1192
1186
1193 By default, this command copies the contents of files as they
1187 By default, this command copies the contents of files as they
1194 stand in the working directory. If invoked with --after, the
1188 stand in the working directory. If invoked with --after, the
1195 operation is recorded, but no copying is performed.
1189 operation is recorded, but no copying is performed.
1196
1190
1197 This command takes effect in the next commit.
1191 This command takes effect in the next commit.
1198
1192
1199 NOTE: This command should be treated as experimental. While it
1193 NOTE: This command should be treated as experimental. While it
1200 should properly record copied files, this information is not yet
1194 should properly record copied files, this information is not yet
1201 fully used by merge, nor fully reported by log.
1195 fully used by merge, nor fully reported by log.
1202 """
1196 """
1203 wlock = repo.wlock(0)
1197 wlock = repo.wlock(0)
1204 errs, copied = docopy(ui, repo, pats, opts, wlock)
1198 errs, copied = docopy(ui, repo, pats, opts, wlock)
1205 return errs
1199 return errs
1206
1200
1207 def debugancestor(ui, index, rev1, rev2):
1201 def debugancestor(ui, index, rev1, rev2):
1208 """find the ancestor revision of two revisions in a given index"""
1202 """find the ancestor revision of two revisions in a given index"""
1209 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index, "", 0)
1203 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index, "", 0)
1210 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
1204 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
1211 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1205 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1212
1206
1213 def debugcomplete(ui, cmd='', **opts):
1207 def debugcomplete(ui, cmd='', **opts):
1214 """returns the completion list associated with the given command"""
1208 """returns the completion list associated with the given command"""
1215
1209
1216 if opts['options']:
1210 if opts['options']:
1217 options = []
1211 options = []
1218 otables = [globalopts]
1212 otables = [globalopts]
1219 if cmd:
1213 if cmd:
1220 aliases, entry = findcmd(cmd)
1214 aliases, entry = findcmd(cmd)
1221 otables.append(entry[1])
1215 otables.append(entry[1])
1222 for t in otables:
1216 for t in otables:
1223 for o in t:
1217 for o in t:
1224 if o[0]:
1218 if o[0]:
1225 options.append('-%s' % o[0])
1219 options.append('-%s' % o[0])
1226 options.append('--%s' % o[1])
1220 options.append('--%s' % o[1])
1227 ui.write("%s\n" % "\n".join(options))
1221 ui.write("%s\n" % "\n".join(options))
1228 return
1222 return
1229
1223
1230 clist = findpossible(cmd).keys()
1224 clist = findpossible(cmd).keys()
1231 clist.sort()
1225 clist.sort()
1232 ui.write("%s\n" % "\n".join(clist))
1226 ui.write("%s\n" % "\n".join(clist))
1233
1227
1234 def debugrebuildstate(ui, repo, rev=None):
1228 def debugrebuildstate(ui, repo, rev=None):
1235 """rebuild the dirstate as it would look like for the given revision"""
1229 """rebuild the dirstate as it would look like for the given revision"""
1236 if not rev:
1230 if not rev:
1237 rev = repo.changelog.tip()
1231 rev = repo.changelog.tip()
1238 else:
1232 else:
1239 rev = repo.lookup(rev)
1233 rev = repo.lookup(rev)
1240 change = repo.changelog.read(rev)
1234 change = repo.changelog.read(rev)
1241 n = change[0]
1235 n = change[0]
1242 files = repo.manifest.readflags(n)
1236 files = repo.manifest.readflags(n)
1243 wlock = repo.wlock()
1237 wlock = repo.wlock()
1244 repo.dirstate.rebuild(rev, files.iteritems())
1238 repo.dirstate.rebuild(rev, files.iteritems())
1245
1239
1246 def debugcheckstate(ui, repo):
1240 def debugcheckstate(ui, repo):
1247 """validate the correctness of the current dirstate"""
1241 """validate the correctness of the current dirstate"""
1248 parent1, parent2 = repo.dirstate.parents()
1242 parent1, parent2 = repo.dirstate.parents()
1249 repo.dirstate.read()
1243 repo.dirstate.read()
1250 dc = repo.dirstate.map
1244 dc = repo.dirstate.map
1251 keys = dc.keys()
1245 keys = dc.keys()
1252 keys.sort()
1246 keys.sort()
1253 m1n = repo.changelog.read(parent1)[0]
1247 m1n = repo.changelog.read(parent1)[0]
1254 m2n = repo.changelog.read(parent2)[0]
1248 m2n = repo.changelog.read(parent2)[0]
1255 m1 = repo.manifest.read(m1n)
1249 m1 = repo.manifest.read(m1n)
1256 m2 = repo.manifest.read(m2n)
1250 m2 = repo.manifest.read(m2n)
1257 errors = 0
1251 errors = 0
1258 for f in dc:
1252 for f in dc:
1259 state = repo.dirstate.state(f)
1253 state = repo.dirstate.state(f)
1260 if state in "nr" and f not in m1:
1254 if state in "nr" and f not in m1:
1261 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1255 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1262 errors += 1
1256 errors += 1
1263 if state in "a" and f in m1:
1257 if state in "a" and f in m1:
1264 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1258 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1265 errors += 1
1259 errors += 1
1266 if state in "m" and f not in m1 and f not in m2:
1260 if state in "m" and f not in m1 and f not in m2:
1267 ui.warn(_("%s in state %s, but not in either manifest\n") %
1261 ui.warn(_("%s in state %s, but not in either manifest\n") %
1268 (f, state))
1262 (f, state))
1269 errors += 1
1263 errors += 1
1270 for f in m1:
1264 for f in m1:
1271 state = repo.dirstate.state(f)
1265 state = repo.dirstate.state(f)
1272 if state not in "nrm":
1266 if state not in "nrm":
1273 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1267 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1274 errors += 1
1268 errors += 1
1275 if errors:
1269 if errors:
1276 error = _(".hg/dirstate inconsistent with current parent's manifest")
1270 error = _(".hg/dirstate inconsistent with current parent's manifest")
1277 raise util.Abort(error)
1271 raise util.Abort(error)
1278
1272
1279 def debugconfig(ui, repo, *values):
1273 def debugconfig(ui, repo, *values):
1280 """show combined config settings from all hgrc files
1274 """show combined config settings from all hgrc files
1281
1275
1282 With no args, print names and values of all config items.
1276 With no args, print names and values of all config items.
1283
1277
1284 With one arg of the form section.name, print just the value of
1278 With one arg of the form section.name, print just the value of
1285 that config item.
1279 that config item.
1286
1280
1287 With multiple args, print names and values of all config items
1281 With multiple args, print names and values of all config items
1288 with matching section names."""
1282 with matching section names."""
1289
1283
1290 if values:
1284 if values:
1291 if len([v for v in values if '.' in v]) > 1:
1285 if len([v for v in values if '.' in v]) > 1:
1292 raise util.Abort(_('only one config item permitted'))
1286 raise util.Abort(_('only one config item permitted'))
1293 for section, name, value in ui.walkconfig():
1287 for section, name, value in ui.walkconfig():
1294 sectname = section + '.' + name
1288 sectname = section + '.' + name
1295 if values:
1289 if values:
1296 for v in values:
1290 for v in values:
1297 if v == section:
1291 if v == section:
1298 ui.write('%s=%s\n' % (sectname, value))
1292 ui.write('%s=%s\n' % (sectname, value))
1299 elif v == sectname:
1293 elif v == sectname:
1300 ui.write(value, '\n')
1294 ui.write(value, '\n')
1301 else:
1295 else:
1302 ui.write('%s=%s\n' % (sectname, value))
1296 ui.write('%s=%s\n' % (sectname, value))
1303
1297
1304 def debugsetparents(ui, repo, rev1, rev2=None):
1298 def debugsetparents(ui, repo, rev1, rev2=None):
1305 """manually set the parents of the current working directory
1299 """manually set the parents of the current working directory
1306
1300
1307 This is useful for writing repository conversion tools, but should
1301 This is useful for writing repository conversion tools, but should
1308 be used with care.
1302 be used with care.
1309 """
1303 """
1310
1304
1311 if not rev2:
1305 if not rev2:
1312 rev2 = hex(nullid)
1306 rev2 = hex(nullid)
1313
1307
1314 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
1308 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
1315
1309
1316 def debugstate(ui, repo):
1310 def debugstate(ui, repo):
1317 """show the contents of the current dirstate"""
1311 """show the contents of the current dirstate"""
1318 repo.dirstate.read()
1312 repo.dirstate.read()
1319 dc = repo.dirstate.map
1313 dc = repo.dirstate.map
1320 keys = dc.keys()
1314 keys = dc.keys()
1321 keys.sort()
1315 keys.sort()
1322 for file_ in keys:
1316 for file_ in keys:
1323 ui.write("%c %3o %10d %s %s\n"
1317 ui.write("%c %3o %10d %s %s\n"
1324 % (dc[file_][0], dc[file_][1] & 0777, dc[file_][2],
1318 % (dc[file_][0], dc[file_][1] & 0777, dc[file_][2],
1325 time.strftime("%x %X",
1319 time.strftime("%x %X",
1326 time.localtime(dc[file_][3])), file_))
1320 time.localtime(dc[file_][3])), file_))
1327 for f in repo.dirstate.copies:
1321 for f in repo.dirstate.copies:
1328 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copies[f], f))
1322 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copies[f], f))
1329
1323
1330 def debugdata(ui, file_, rev):
1324 def debugdata(ui, file_, rev):
1331 """dump the contents of an data file revision"""
1325 """dump the contents of an data file revision"""
1332 r = revlog.revlog(util.opener(os.getcwd(), audit=False),
1326 r = revlog.revlog(util.opener(os.getcwd(), audit=False),
1333 file_[:-2] + ".i", file_, 0)
1327 file_[:-2] + ".i", file_, 0)
1334 try:
1328 try:
1335 ui.write(r.revision(r.lookup(rev)))
1329 ui.write(r.revision(r.lookup(rev)))
1336 except KeyError:
1330 except KeyError:
1337 raise util.Abort(_('invalid revision identifier %s'), rev)
1331 raise util.Abort(_('invalid revision identifier %s'), rev)
1338
1332
1339 def debugindex(ui, file_):
1333 def debugindex(ui, file_):
1340 """dump the contents of an index file"""
1334 """dump the contents of an index file"""
1341 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0)
1335 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0)
1342 ui.write(" rev offset length base linkrev" +
1336 ui.write(" rev offset length base linkrev" +
1343 " nodeid p1 p2\n")
1337 " nodeid p1 p2\n")
1344 for i in range(r.count()):
1338 for i in range(r.count()):
1345 node = r.node(i)
1339 node = r.node(i)
1346 pp = r.parents(node)
1340 pp = r.parents(node)
1347 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1341 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1348 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
1342 i, r.start(i), r.length(i), r.base(i), r.linkrev(node),
1349 short(node), short(pp[0]), short(pp[1])))
1343 short(node), short(pp[0]), short(pp[1])))
1350
1344
1351 def debugindexdot(ui, file_):
1345 def debugindexdot(ui, file_):
1352 """dump an index DAG as a .dot file"""
1346 """dump an index DAG as a .dot file"""
1353 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0)
1347 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0)
1354 ui.write("digraph G {\n")
1348 ui.write("digraph G {\n")
1355 for i in range(r.count()):
1349 for i in range(r.count()):
1356 node = r.node(i)
1350 node = r.node(i)
1357 pp = r.parents(node)
1351 pp = r.parents(node)
1358 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1352 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1359 if pp[1] != nullid:
1353 if pp[1] != nullid:
1360 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1354 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1361 ui.write("}\n")
1355 ui.write("}\n")
1362
1356
1363 def debugrename(ui, repo, file, rev=None):
1357 def debugrename(ui, repo, file, rev=None):
1364 """dump rename information"""
1358 """dump rename information"""
1365 r = repo.file(relpath(repo, [file])[0])
1359 r = repo.file(relpath(repo, [file])[0])
1366 if rev:
1360 if rev:
1367 try:
1361 try:
1368 # assume all revision numbers are for changesets
1362 # assume all revision numbers are for changesets
1369 n = repo.lookup(rev)
1363 n = repo.lookup(rev)
1370 change = repo.changelog.read(n)
1364 change = repo.changelog.read(n)
1371 m = repo.manifest.read(change[0])
1365 m = repo.manifest.read(change[0])
1372 n = m[relpath(repo, [file])[0]]
1366 n = m[relpath(repo, [file])[0]]
1373 except (hg.RepoError, KeyError):
1367 except (hg.RepoError, KeyError):
1374 n = r.lookup(rev)
1368 n = r.lookup(rev)
1375 else:
1369 else:
1376 n = r.tip()
1370 n = r.tip()
1377 m = r.renamed(n)
1371 m = r.renamed(n)
1378 if m:
1372 if m:
1379 ui.write(_("renamed from %s:%s\n") % (m[0], hex(m[1])))
1373 ui.write(_("renamed from %s:%s\n") % (m[0], hex(m[1])))
1380 else:
1374 else:
1381 ui.write(_("not renamed\n"))
1375 ui.write(_("not renamed\n"))
1382
1376
1383 def debugwalk(ui, repo, *pats, **opts):
1377 def debugwalk(ui, repo, *pats, **opts):
1384 """show how files match on given patterns"""
1378 """show how files match on given patterns"""
1385 items = list(walk(repo, pats, opts))
1379 items = list(walk(repo, pats, opts))
1386 if not items:
1380 if not items:
1387 return
1381 return
1388 fmt = '%%s %%-%ds %%-%ds %%s' % (
1382 fmt = '%%s %%-%ds %%-%ds %%s' % (
1389 max([len(abs) for (src, abs, rel, exact) in items]),
1383 max([len(abs) for (src, abs, rel, exact) in items]),
1390 max([len(rel) for (src, abs, rel, exact) in items]))
1384 max([len(rel) for (src, abs, rel, exact) in items]))
1391 for src, abs, rel, exact in items:
1385 for src, abs, rel, exact in items:
1392 line = fmt % (src, abs, rel, exact and 'exact' or '')
1386 line = fmt % (src, abs, rel, exact and 'exact' or '')
1393 ui.write("%s\n" % line.rstrip())
1387 ui.write("%s\n" % line.rstrip())
1394
1388
1395 def diff(ui, repo, *pats, **opts):
1389 def diff(ui, repo, *pats, **opts):
1396 """diff repository (or selected files)
1390 """diff repository (or selected files)
1397
1391
1398 Show differences between revisions for the specified files.
1392 Show differences between revisions for the specified files.
1399
1393
1400 Differences between files are shown using the unified diff format.
1394 Differences between files are shown using the unified diff format.
1401
1395
1402 When two revision arguments are given, then changes are shown
1396 When two revision arguments are given, then changes are shown
1403 between those revisions. If only one revision is specified then
1397 between those revisions. If only one revision is specified then
1404 that revision is compared to the working directory, and, when no
1398 that revision is compared to the working directory, and, when no
1405 revisions are specified, the working directory files are compared
1399 revisions are specified, the working directory files are compared
1406 to its parent.
1400 to its parent.
1407
1401
1408 Without the -a option, diff will avoid generating diffs of files
1402 Without the -a option, diff will avoid generating diffs of files
1409 it detects as binary. With -a, diff will generate a diff anyway,
1403 it detects as binary. With -a, diff will generate a diff anyway,
1410 probably with undesirable results.
1404 probably with undesirable results.
1411 """
1405 """
1412 node1, node2 = revpair(ui, repo, opts['rev'])
1406 node1, node2 = revpair(ui, repo, opts['rev'])
1413
1407
1414 fns, matchfn, anypats = matchpats(repo, pats, opts)
1408 fns, matchfn, anypats = matchpats(repo, pats, opts)
1415
1409
1416 dodiff(sys.stdout, ui, repo, node1, node2, fns, match=matchfn,
1410 dodiff(sys.stdout, ui, repo, node1, node2, fns, match=matchfn,
1417 text=opts['text'], opts=opts)
1411 text=opts['text'], opts=opts)
1418
1412
1419 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
1413 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
1420 node = repo.lookup(changeset)
1414 node = repo.lookup(changeset)
1421 parents = [p for p in repo.changelog.parents(node) if p != nullid]
1415 parents = [p for p in repo.changelog.parents(node) if p != nullid]
1422 if opts['switch_parent']:
1416 if opts['switch_parent']:
1423 parents.reverse()
1417 parents.reverse()
1424 prev = (parents and parents[0]) or nullid
1418 prev = (parents and parents[0]) or nullid
1425 change = repo.changelog.read(node)
1419 change = repo.changelog.read(node)
1426
1420
1427 fp = make_file(repo, opts['output'], node, total=total, seqno=seqno,
1421 fp = make_file(repo, opts['output'], node, total=total, seqno=seqno,
1428 revwidth=revwidth)
1422 revwidth=revwidth)
1429 if fp != sys.stdout:
1423 if fp != sys.stdout:
1430 ui.note("%s\n" % fp.name)
1424 ui.note("%s\n" % fp.name)
1431
1425
1432 fp.write("# HG changeset patch\n")
1426 fp.write("# HG changeset patch\n")
1433 fp.write("# User %s\n" % change[1])
1427 fp.write("# User %s\n" % change[1])
1434 fp.write("# Date %d %d\n" % change[2])
1428 fp.write("# Date %d %d\n" % change[2])
1435 fp.write("# Node ID %s\n" % hex(node))
1429 fp.write("# Node ID %s\n" % hex(node))
1436 fp.write("# Parent %s\n" % hex(prev))
1430 fp.write("# Parent %s\n" % hex(prev))
1437 if len(parents) > 1:
1431 if len(parents) > 1:
1438 fp.write("# Parent %s\n" % hex(parents[1]))
1432 fp.write("# Parent %s\n" % hex(parents[1]))
1439 fp.write(change[4].rstrip())
1433 fp.write(change[4].rstrip())
1440 fp.write("\n\n")
1434 fp.write("\n\n")
1441
1435
1442 dodiff(fp, ui, repo, prev, node, text=opts['text'])
1436 dodiff(fp, ui, repo, prev, node, text=opts['text'])
1443 if fp != sys.stdout:
1437 if fp != sys.stdout:
1444 fp.close()
1438 fp.close()
1445
1439
1446 def export(ui, repo, *changesets, **opts):
1440 def export(ui, repo, *changesets, **opts):
1447 """dump the header and diffs for one or more changesets
1441 """dump the header and diffs for one or more changesets
1448
1442
1449 Print the changeset header and diffs for one or more revisions.
1443 Print the changeset header and diffs for one or more revisions.
1450
1444
1451 The information shown in the changeset header is: author,
1445 The information shown in the changeset header is: author,
1452 changeset hash, parent and commit comment.
1446 changeset hash, parent and commit comment.
1453
1447
1454 Output may be to a file, in which case the name of the file is
1448 Output may be to a file, in which case the name of the file is
1455 given using a format string. The formatting rules are as follows:
1449 given using a format string. The formatting rules are as follows:
1456
1450
1457 %% literal "%" character
1451 %% literal "%" character
1458 %H changeset hash (40 bytes of hexadecimal)
1452 %H changeset hash (40 bytes of hexadecimal)
1459 %N number of patches being generated
1453 %N number of patches being generated
1460 %R changeset revision number
1454 %R changeset revision number
1461 %b basename of the exporting repository
1455 %b basename of the exporting repository
1462 %h short-form changeset hash (12 bytes of hexadecimal)
1456 %h short-form changeset hash (12 bytes of hexadecimal)
1463 %n zero-padded sequence number, starting at 1
1457 %n zero-padded sequence number, starting at 1
1464 %r zero-padded changeset revision number
1458 %r zero-padded changeset revision number
1465
1459
1466 Without the -a option, export will avoid generating diffs of files
1460 Without the -a option, export will avoid generating diffs of files
1467 it detects as binary. With -a, export will generate a diff anyway,
1461 it detects as binary. With -a, export will generate a diff anyway,
1468 probably with undesirable results.
1462 probably with undesirable results.
1469
1463
1470 With the --switch-parent option, the diff will be against the second
1464 With the --switch-parent option, the diff will be against the second
1471 parent. It can be useful to review a merge.
1465 parent. It can be useful to review a merge.
1472 """
1466 """
1473 if not changesets:
1467 if not changesets:
1474 raise util.Abort(_("export requires at least one changeset"))
1468 raise util.Abort(_("export requires at least one changeset"))
1475 seqno = 0
1469 seqno = 0
1476 revs = list(revrange(ui, repo, changesets))
1470 revs = list(revrange(ui, repo, changesets))
1477 total = len(revs)
1471 total = len(revs)
1478 revwidth = max(map(len, revs))
1472 revwidth = max(map(len, revs))
1479 msg = len(revs) > 1 and _("Exporting patches:\n") or _("Exporting patch:\n")
1473 msg = len(revs) > 1 and _("Exporting patches:\n") or _("Exporting patch:\n")
1480 ui.note(msg)
1474 ui.note(msg)
1481 for cset in revs:
1475 for cset in revs:
1482 seqno += 1
1476 seqno += 1
1483 doexport(ui, repo, cset, seqno, total, revwidth, opts)
1477 doexport(ui, repo, cset, seqno, total, revwidth, opts)
1484
1478
1485 def forget(ui, repo, *pats, **opts):
1479 def forget(ui, repo, *pats, **opts):
1486 """don't add the specified files on the next commit (DEPRECATED)
1480 """don't add the specified files on the next commit (DEPRECATED)
1487
1481
1488 (DEPRECATED)
1482 (DEPRECATED)
1489 Undo an 'hg add' scheduled for the next commit.
1483 Undo an 'hg add' scheduled for the next commit.
1490
1484
1491 This command is now deprecated and will be removed in a future
1485 This command is now deprecated and will be removed in a future
1492 release. Please use revert instead.
1486 release. Please use revert instead.
1493 """
1487 """
1494 ui.warn(_("(the forget command is deprecated; use revert instead)\n"))
1488 ui.warn(_("(the forget command is deprecated; use revert instead)\n"))
1495 forget = []
1489 forget = []
1496 for src, abs, rel, exact in walk(repo, pats, opts):
1490 for src, abs, rel, exact in walk(repo, pats, opts):
1497 if repo.dirstate.state(abs) == 'a':
1491 if repo.dirstate.state(abs) == 'a':
1498 forget.append(abs)
1492 forget.append(abs)
1499 if ui.verbose or not exact:
1493 if ui.verbose or not exact:
1500 ui.status(_('forgetting %s\n') % ((pats and rel) or abs))
1494 ui.status(_('forgetting %s\n') % ((pats and rel) or abs))
1501 repo.forget(forget)
1495 repo.forget(forget)
1502
1496
1503 def grep(ui, repo, pattern, *pats, **opts):
1497 def grep(ui, repo, pattern, *pats, **opts):
1504 """search for a pattern in specified files and revisions
1498 """search for a pattern in specified files and revisions
1505
1499
1506 Search revisions of files for a regular expression.
1500 Search revisions of files for a regular expression.
1507
1501
1508 This command behaves differently than Unix grep. It only accepts
1502 This command behaves differently than Unix grep. It only accepts
1509 Python/Perl regexps. It searches repository history, not the
1503 Python/Perl regexps. It searches repository history, not the
1510 working directory. It always prints the revision number in which
1504 working directory. It always prints the revision number in which
1511 a match appears.
1505 a match appears.
1512
1506
1513 By default, grep only prints output for the first revision of a
1507 By default, grep only prints output for the first revision of a
1514 file in which it finds a match. To get it to print every revision
1508 file in which it finds a match. To get it to print every revision
1515 that contains a change in match status ("-" for a match that
1509 that contains a change in match status ("-" for a match that
1516 becomes a non-match, or "+" for a non-match that becomes a match),
1510 becomes a non-match, or "+" for a non-match that becomes a match),
1517 use the --all flag.
1511 use the --all flag.
1518 """
1512 """
1519 reflags = 0
1513 reflags = 0
1520 if opts['ignore_case']:
1514 if opts['ignore_case']:
1521 reflags |= re.I
1515 reflags |= re.I
1522 regexp = re.compile(pattern, reflags)
1516 regexp = re.compile(pattern, reflags)
1523 sep, eol = ':', '\n'
1517 sep, eol = ':', '\n'
1524 if opts['print0']:
1518 if opts['print0']:
1525 sep = eol = '\0'
1519 sep = eol = '\0'
1526
1520
1527 fcache = {}
1521 fcache = {}
1528 def getfile(fn):
1522 def getfile(fn):
1529 if fn not in fcache:
1523 if fn not in fcache:
1530 fcache[fn] = repo.file(fn)
1524 fcache[fn] = repo.file(fn)
1531 return fcache[fn]
1525 return fcache[fn]
1532
1526
1533 def matchlines(body):
1527 def matchlines(body):
1534 begin = 0
1528 begin = 0
1535 linenum = 0
1529 linenum = 0
1536 while True:
1530 while True:
1537 match = regexp.search(body, begin)
1531 match = regexp.search(body, begin)
1538 if not match:
1532 if not match:
1539 break
1533 break
1540 mstart, mend = match.span()
1534 mstart, mend = match.span()
1541 linenum += body.count('\n', begin, mstart) + 1
1535 linenum += body.count('\n', begin, mstart) + 1
1542 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1536 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1543 lend = body.find('\n', mend)
1537 lend = body.find('\n', mend)
1544 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1538 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1545 begin = lend + 1
1539 begin = lend + 1
1546
1540
1547 class linestate(object):
1541 class linestate(object):
1548 def __init__(self, line, linenum, colstart, colend):
1542 def __init__(self, line, linenum, colstart, colend):
1549 self.line = line
1543 self.line = line
1550 self.linenum = linenum
1544 self.linenum = linenum
1551 self.colstart = colstart
1545 self.colstart = colstart
1552 self.colend = colend
1546 self.colend = colend
1553 def __eq__(self, other):
1547 def __eq__(self, other):
1554 return self.line == other.line
1548 return self.line == other.line
1555 def __hash__(self):
1549 def __hash__(self):
1556 return hash(self.line)
1550 return hash(self.line)
1557
1551
1558 matches = {}
1552 matches = {}
1559 def grepbody(fn, rev, body):
1553 def grepbody(fn, rev, body):
1560 matches[rev].setdefault(fn, {})
1554 matches[rev].setdefault(fn, {})
1561 m = matches[rev][fn]
1555 m = matches[rev][fn]
1562 for lnum, cstart, cend, line in matchlines(body):
1556 for lnum, cstart, cend, line in matchlines(body):
1563 s = linestate(line, lnum, cstart, cend)
1557 s = linestate(line, lnum, cstart, cend)
1564 m[s] = s
1558 m[s] = s
1565
1559
1566 # FIXME: prev isn't used, why ?
1560 # FIXME: prev isn't used, why ?
1567 prev = {}
1561 prev = {}
1568 ucache = {}
1562 ucache = {}
1569 def display(fn, rev, states, prevstates):
1563 def display(fn, rev, states, prevstates):
1570 diff = list(sets.Set(states).symmetric_difference(sets.Set(prevstates)))
1564 diff = list(sets.Set(states).symmetric_difference(sets.Set(prevstates)))
1571 diff.sort(lambda x, y: cmp(x.linenum, y.linenum))
1565 diff.sort(lambda x, y: cmp(x.linenum, y.linenum))
1572 counts = {'-': 0, '+': 0}
1566 counts = {'-': 0, '+': 0}
1573 filerevmatches = {}
1567 filerevmatches = {}
1574 for l in diff:
1568 for l in diff:
1575 if incrementing or not opts['all']:
1569 if incrementing or not opts['all']:
1576 change = ((l in prevstates) and '-') or '+'
1570 change = ((l in prevstates) and '-') or '+'
1577 r = rev
1571 r = rev
1578 else:
1572 else:
1579 change = ((l in states) and '-') or '+'
1573 change = ((l in states) and '-') or '+'
1580 r = prev[fn]
1574 r = prev[fn]
1581 cols = [fn, str(rev)]
1575 cols = [fn, str(rev)]
1582 if opts['line_number']:
1576 if opts['line_number']:
1583 cols.append(str(l.linenum))
1577 cols.append(str(l.linenum))
1584 if opts['all']:
1578 if opts['all']:
1585 cols.append(change)
1579 cols.append(change)
1586 if opts['user']:
1580 if opts['user']:
1587 cols.append(trimuser(ui, getchange(rev)[1], rev,
1581 cols.append(trimuser(ui, getchange(rev)[1], rev,
1588 ucache))
1582 ucache))
1589 if opts['files_with_matches']:
1583 if opts['files_with_matches']:
1590 c = (fn, rev)
1584 c = (fn, rev)
1591 if c in filerevmatches:
1585 if c in filerevmatches:
1592 continue
1586 continue
1593 filerevmatches[c] = 1
1587 filerevmatches[c] = 1
1594 else:
1588 else:
1595 cols.append(l.line)
1589 cols.append(l.line)
1596 ui.write(sep.join(cols), eol)
1590 ui.write(sep.join(cols), eol)
1597 counts[change] += 1
1591 counts[change] += 1
1598 return counts['+'], counts['-']
1592 return counts['+'], counts['-']
1599
1593
1600 fstate = {}
1594 fstate = {}
1601 skip = {}
1595 skip = {}
1602 changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts)
1596 changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts)
1603 count = 0
1597 count = 0
1604 incrementing = False
1598 incrementing = False
1605 for st, rev, fns in changeiter:
1599 for st, rev, fns in changeiter:
1606 if st == 'window':
1600 if st == 'window':
1607 incrementing = rev
1601 incrementing = rev
1608 matches.clear()
1602 matches.clear()
1609 elif st == 'add':
1603 elif st == 'add':
1610 change = repo.changelog.read(repo.lookup(str(rev)))
1604 change = repo.changelog.read(repo.lookup(str(rev)))
1611 mf = repo.manifest.read(change[0])
1605 mf = repo.manifest.read(change[0])
1612 matches[rev] = {}
1606 matches[rev] = {}
1613 for fn in fns:
1607 for fn in fns:
1614 if fn in skip:
1608 if fn in skip:
1615 continue
1609 continue
1616 fstate.setdefault(fn, {})
1610 fstate.setdefault(fn, {})
1617 try:
1611 try:
1618 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1612 grepbody(fn, rev, getfile(fn).read(mf[fn]))
1619 except KeyError:
1613 except KeyError:
1620 pass
1614 pass
1621 elif st == 'iter':
1615 elif st == 'iter':
1622 states = matches[rev].items()
1616 states = matches[rev].items()
1623 states.sort()
1617 states.sort()
1624 for fn, m in states:
1618 for fn, m in states:
1625 if fn in skip:
1619 if fn in skip:
1626 continue
1620 continue
1627 if incrementing or not opts['all'] or fstate[fn]:
1621 if incrementing or not opts['all'] or fstate[fn]:
1628 pos, neg = display(fn, rev, m, fstate[fn])
1622 pos, neg = display(fn, rev, m, fstate[fn])
1629 count += pos + neg
1623 count += pos + neg
1630 if pos and not opts['all']:
1624 if pos and not opts['all']:
1631 skip[fn] = True
1625 skip[fn] = True
1632 fstate[fn] = m
1626 fstate[fn] = m
1633 prev[fn] = rev
1627 prev[fn] = rev
1634
1628
1635 if not incrementing:
1629 if not incrementing:
1636 fstate = fstate.items()
1630 fstate = fstate.items()
1637 fstate.sort()
1631 fstate.sort()
1638 for fn, state in fstate:
1632 for fn, state in fstate:
1639 if fn in skip:
1633 if fn in skip:
1640 continue
1634 continue
1641 display(fn, rev, {}, state)
1635 display(fn, rev, {}, state)
1642 return (count == 0 and 1) or 0
1636 return (count == 0 and 1) or 0
1643
1637
1644 def heads(ui, repo, **opts):
1638 def heads(ui, repo, **opts):
1645 """show current repository heads
1639 """show current repository heads
1646
1640
1647 Show all repository head changesets.
1641 Show all repository head changesets.
1648
1642
1649 Repository "heads" are changesets that don't have children
1643 Repository "heads" are changesets that don't have children
1650 changesets. They are where development generally takes place and
1644 changesets. They are where development generally takes place and
1651 are the usual targets for update and merge operations.
1645 are the usual targets for update and merge operations.
1652 """
1646 """
1653 if opts['rev']:
1647 if opts['rev']:
1654 heads = repo.heads(repo.lookup(opts['rev']))
1648 heads = repo.heads(repo.lookup(opts['rev']))
1655 else:
1649 else:
1656 heads = repo.heads()
1650 heads = repo.heads()
1657 br = None
1651 br = None
1658 if opts['branches']:
1652 if opts['branches']:
1659 br = repo.branchlookup(heads)
1653 br = repo.branchlookup(heads)
1660 displayer = show_changeset(ui, repo, opts)
1654 displayer = show_changeset(ui, repo, opts)
1661 for n in heads:
1655 for n in heads:
1662 displayer.show(changenode=n, brinfo=br)
1656 displayer.show(changenode=n, brinfo=br)
1663
1657
1664 def identify(ui, repo):
1658 def identify(ui, repo):
1665 """print information about the working copy
1659 """print information about the working copy
1666
1660
1667 Print a short summary of the current state of the repo.
1661 Print a short summary of the current state of the repo.
1668
1662
1669 This summary identifies the repository state using one or two parent
1663 This summary identifies the repository state using one or two parent
1670 hash identifiers, followed by a "+" if there are uncommitted changes
1664 hash identifiers, followed by a "+" if there are uncommitted changes
1671 in the working directory, followed by a list of tags for this revision.
1665 in the working directory, followed by a list of tags for this revision.
1672 """
1666 """
1673 parents = [p for p in repo.dirstate.parents() if p != nullid]
1667 parents = [p for p in repo.dirstate.parents() if p != nullid]
1674 if not parents:
1668 if not parents:
1675 ui.write(_("unknown\n"))
1669 ui.write(_("unknown\n"))
1676 return
1670 return
1677
1671
1678 hexfunc = ui.verbose and hex or short
1672 hexfunc = ui.verbose and hex or short
1679 modified, added, removed, deleted, unknown = repo.changes()
1673 modified, added, removed, deleted, unknown = repo.changes()
1680 output = ["%s%s" %
1674 output = ["%s%s" %
1681 ('+'.join([hexfunc(parent) for parent in parents]),
1675 ('+'.join([hexfunc(parent) for parent in parents]),
1682 (modified or added or removed or deleted) and "+" or "")]
1676 (modified or added or removed or deleted) and "+" or "")]
1683
1677
1684 if not ui.quiet:
1678 if not ui.quiet:
1685 # multiple tags for a single parent separated by '/'
1679 # multiple tags for a single parent separated by '/'
1686 parenttags = ['/'.join(tags)
1680 parenttags = ['/'.join(tags)
1687 for tags in map(repo.nodetags, parents) if tags]
1681 for tags in map(repo.nodetags, parents) if tags]
1688 # tags for multiple parents separated by ' + '
1682 # tags for multiple parents separated by ' + '
1689 if parenttags:
1683 if parenttags:
1690 output.append(' + '.join(parenttags))
1684 output.append(' + '.join(parenttags))
1691
1685
1692 ui.write("%s\n" % ' '.join(output))
1686 ui.write("%s\n" % ' '.join(output))
1693
1687
1694 def import_(ui, repo, patch1, *patches, **opts):
1688 def import_(ui, repo, patch1, *patches, **opts):
1695 """import an ordered set of patches
1689 """import an ordered set of patches
1696
1690
1697 Import a list of patches and commit them individually.
1691 Import a list of patches and commit them individually.
1698
1692
1699 If there are outstanding changes in the working directory, import
1693 If there are outstanding changes in the working directory, import
1700 will abort unless given the -f flag.
1694 will abort unless given the -f flag.
1701
1695
1702 You can import a patch straight from a mail message. Even patches
1696 You can import a patch straight from a mail message. Even patches
1703 as attachments work (body part must be type text/plain or
1697 as attachments work (body part must be type text/plain or
1704 text/x-patch to be used). From and Subject headers of email
1698 text/x-patch to be used). From and Subject headers of email
1705 message are used as default committer and commit message. All
1699 message are used as default committer and commit message. All
1706 text/plain body parts before first diff are added to commit
1700 text/plain body parts before first diff are added to commit
1707 message.
1701 message.
1708
1702
1709 If imported patch was generated by hg export, user and description
1703 If imported patch was generated by hg export, user and description
1710 from patch override values from message headers and body. Values
1704 from patch override values from message headers and body. Values
1711 given on command line with -m and -u override these.
1705 given on command line with -m and -u override these.
1712
1706
1713 To read a patch from standard input, use patch name "-".
1707 To read a patch from standard input, use patch name "-".
1714 """
1708 """
1715 patches = (patch1,) + patches
1709 patches = (patch1,) + patches
1716
1710
1717 if not opts['force']:
1711 if not opts['force']:
1718 bail_if_changed(repo)
1712 bail_if_changed(repo)
1719
1713
1720 d = opts["base"]
1714 d = opts["base"]
1721 strip = opts["strip"]
1715 strip = opts["strip"]
1722
1716
1723 mailre = re.compile(r'(?:From |[\w-]+:)')
1717 mailre = re.compile(r'(?:From |[\w-]+:)')
1724
1718
1725 # attempt to detect the start of a patch
1719 # attempt to detect the start of a patch
1726 # (this heuristic is borrowed from quilt)
1720 # (this heuristic is borrowed from quilt)
1727 diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' +
1721 diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' +
1728 'retrieving revision [0-9]+(\.[0-9]+)*$|' +
1722 'retrieving revision [0-9]+(\.[0-9]+)*$|' +
1729 '(---|\*\*\*)[ \t])', re.MULTILINE)
1723 '(---|\*\*\*)[ \t])', re.MULTILINE)
1730
1724
1731 for patch in patches:
1725 for patch in patches:
1732 pf = os.path.join(d, patch)
1726 pf = os.path.join(d, patch)
1733
1727
1734 message = None
1728 message = None
1735 user = None
1729 user = None
1736 date = None
1730 date = None
1737 hgpatch = False
1731 hgpatch = False
1738
1732
1739 p = email.Parser.Parser()
1733 p = email.Parser.Parser()
1740 if pf == '-':
1734 if pf == '-':
1741 msg = p.parse(sys.stdin)
1735 msg = p.parse(sys.stdin)
1742 ui.status(_("applying patch from stdin\n"))
1736 ui.status(_("applying patch from stdin\n"))
1743 else:
1737 else:
1744 msg = p.parse(file(pf))
1738 msg = p.parse(file(pf))
1745 ui.status(_("applying %s\n") % patch)
1739 ui.status(_("applying %s\n") % patch)
1746
1740
1747 fd, tmpname = tempfile.mkstemp(prefix='hg-patch-')
1741 fd, tmpname = tempfile.mkstemp(prefix='hg-patch-')
1748 tmpfp = os.fdopen(fd, 'w')
1742 tmpfp = os.fdopen(fd, 'w')
1749 try:
1743 try:
1750 message = msg['Subject']
1744 message = msg['Subject']
1751 if message:
1745 if message:
1752 message = message.replace('\n\t', ' ')
1746 message = message.replace('\n\t', ' ')
1753 ui.debug('Subject: %s\n' % message)
1747 ui.debug('Subject: %s\n' % message)
1754 user = msg['From']
1748 user = msg['From']
1755 if user:
1749 if user:
1756 ui.debug('From: %s\n' % user)
1750 ui.debug('From: %s\n' % user)
1757 diffs_seen = 0
1751 diffs_seen = 0
1758 ok_types = ('text/plain', 'text/x-patch')
1752 ok_types = ('text/plain', 'text/x-patch')
1759 for part in msg.walk():
1753 for part in msg.walk():
1760 content_type = part.get_content_type()
1754 content_type = part.get_content_type()
1761 ui.debug('Content-Type: %s\n' % content_type)
1755 ui.debug('Content-Type: %s\n' % content_type)
1762 if content_type not in ok_types:
1756 if content_type not in ok_types:
1763 continue
1757 continue
1764 payload = part.get_payload(decode=True)
1758 payload = part.get_payload(decode=True)
1765 m = diffre.search(payload)
1759 m = diffre.search(payload)
1766 if m:
1760 if m:
1767 ui.debug(_('found patch at byte %d\n') % m.start(0))
1761 ui.debug(_('found patch at byte %d\n') % m.start(0))
1768 diffs_seen += 1
1762 diffs_seen += 1
1769 hgpatch = False
1763 hgpatch = False
1770 fp = cStringIO.StringIO()
1764 fp = cStringIO.StringIO()
1771 if message:
1765 if message:
1772 fp.write(message)
1766 fp.write(message)
1773 fp.write('\n')
1767 fp.write('\n')
1774 for line in payload[:m.start(0)].splitlines():
1768 for line in payload[:m.start(0)].splitlines():
1775 if line.startswith('# HG changeset patch'):
1769 if line.startswith('# HG changeset patch'):
1776 ui.debug(_('patch generated by hg export\n'))
1770 ui.debug(_('patch generated by hg export\n'))
1777 hgpatch = True
1771 hgpatch = True
1778 # drop earlier commit message content
1772 # drop earlier commit message content
1779 fp.seek(0)
1773 fp.seek(0)
1780 fp.truncate()
1774 fp.truncate()
1781 elif hgpatch:
1775 elif hgpatch:
1782 if line.startswith('# User '):
1776 if line.startswith('# User '):
1783 user = line[7:]
1777 user = line[7:]
1784 ui.debug('From: %s\n' % user)
1778 ui.debug('From: %s\n' % user)
1785 elif line.startswith("# Date "):
1779 elif line.startswith("# Date "):
1786 date = line[7:]
1780 date = line[7:]
1787 if not line.startswith('# '):
1781 if not line.startswith('# '):
1788 fp.write(line)
1782 fp.write(line)
1789 fp.write('\n')
1783 fp.write('\n')
1790 message = fp.getvalue()
1784 message = fp.getvalue()
1791 if tmpfp:
1785 if tmpfp:
1792 tmpfp.write(payload)
1786 tmpfp.write(payload)
1793 if not payload.endswith('\n'):
1787 if not payload.endswith('\n'):
1794 tmpfp.write('\n')
1788 tmpfp.write('\n')
1795 elif not diffs_seen and message and content_type == 'text/plain':
1789 elif not diffs_seen and message and content_type == 'text/plain':
1796 message += '\n' + payload
1790 message += '\n' + payload
1797
1791
1798 if opts['message']:
1792 if opts['message']:
1799 # pickup the cmdline msg
1793 # pickup the cmdline msg
1800 message = opts['message']
1794 message = opts['message']
1801 elif message:
1795 elif message:
1802 # pickup the patch msg
1796 # pickup the patch msg
1803 message = message.strip()
1797 message = message.strip()
1804 else:
1798 else:
1805 # launch the editor
1799 # launch the editor
1806 message = None
1800 message = None
1807 ui.debug(_('message:\n%s\n') % message)
1801 ui.debug(_('message:\n%s\n') % message)
1808
1802
1809 tmpfp.close()
1803 tmpfp.close()
1810 if not diffs_seen:
1804 if not diffs_seen:
1811 raise util.Abort(_('no diffs found'))
1805 raise util.Abort(_('no diffs found'))
1812
1806
1813 files = util.patch(strip, tmpname, ui)
1807 files = util.patch(strip, tmpname, ui)
1814 if len(files) > 0:
1808 if len(files) > 0:
1815 addremove_lock(ui, repo, files, {})
1809 addremove_lock(ui, repo, files, {})
1816 repo.commit(files, message, user, date)
1810 repo.commit(files, message, user, date)
1817 finally:
1811 finally:
1818 os.unlink(tmpname)
1812 os.unlink(tmpname)
1819
1813
1820 def incoming(ui, repo, source="default", **opts):
1814 def incoming(ui, repo, source="default", **opts):
1821 """show new changesets found in source
1815 """show new changesets found in source
1822
1816
1823 Show new changesets found in the specified path/URL or the default
1817 Show new changesets found in the specified path/URL or the default
1824 pull location. These are the changesets that would be pulled if a pull
1818 pull location. These are the changesets that would be pulled if a pull
1825 was requested.
1819 was requested.
1826
1820
1827 For remote repository, using --bundle avoids downloading the changesets
1821 For remote repository, using --bundle avoids downloading the changesets
1828 twice if the incoming is followed by a pull.
1822 twice if the incoming is followed by a pull.
1829
1823
1830 See pull for valid source format details.
1824 See pull for valid source format details.
1831 """
1825 """
1832 source = ui.expandpath(source)
1826 source = ui.expandpath(source)
1833 ui.setconfig_remoteopts(**opts)
1827 ui.setconfig_remoteopts(**opts)
1834
1828
1835 other = hg.repository(ui, source)
1829 other = hg.repository(ui, source)
1836 incoming = repo.findincoming(other, force=opts["force"])
1830 incoming = repo.findincoming(other, force=opts["force"])
1837 if not incoming:
1831 if not incoming:
1838 ui.status(_("no changes found\n"))
1832 ui.status(_("no changes found\n"))
1839 return
1833 return
1840
1834
1841 cleanup = None
1835 cleanup = None
1842 try:
1836 try:
1843 fname = opts["bundle"]
1837 fname = opts["bundle"]
1844 if fname or not other.local():
1838 if fname or not other.local():
1845 # create a bundle (uncompressed if other repo is not local)
1839 # create a bundle (uncompressed if other repo is not local)
1846 cg = other.changegroup(incoming, "incoming")
1840 cg = other.changegroup(incoming, "incoming")
1847 fname = cleanup = write_bundle(cg, fname, compress=other.local())
1841 fname = cleanup = write_bundle(cg, fname, compress=other.local())
1848 # keep written bundle?
1842 # keep written bundle?
1849 if opts["bundle"]:
1843 if opts["bundle"]:
1850 cleanup = None
1844 cleanup = None
1851 if not other.local():
1845 if not other.local():
1852 # use the created uncompressed bundlerepo
1846 # use the created uncompressed bundlerepo
1853 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1847 other = bundlerepo.bundlerepository(ui, repo.root, fname)
1854
1848
1855 revs = None
1849 revs = None
1856 if opts['rev']:
1850 if opts['rev']:
1857 revs = [other.lookup(rev) for rev in opts['rev']]
1851 revs = [other.lookup(rev) for rev in opts['rev']]
1858 o = other.changelog.nodesbetween(incoming, revs)[0]
1852 o = other.changelog.nodesbetween(incoming, revs)[0]
1859 if opts['newest_first']:
1853 if opts['newest_first']:
1860 o.reverse()
1854 o.reverse()
1861 displayer = show_changeset(ui, other, opts)
1855 displayer = show_changeset(ui, other, opts)
1862 for n in o:
1856 for n in o:
1863 parents = [p for p in other.changelog.parents(n) if p != nullid]
1857 parents = [p for p in other.changelog.parents(n) if p != nullid]
1864 if opts['no_merges'] and len(parents) == 2:
1858 if opts['no_merges'] and len(parents) == 2:
1865 continue
1859 continue
1866 displayer.show(changenode=n)
1860 displayer.show(changenode=n)
1867 if opts['patch']:
1861 if opts['patch']:
1868 prev = (parents and parents[0]) or nullid
1862 prev = (parents and parents[0]) or nullid
1869 dodiff(ui, ui, other, prev, n)
1863 dodiff(ui, ui, other, prev, n)
1870 ui.write("\n")
1864 ui.write("\n")
1871 finally:
1865 finally:
1872 if hasattr(other, 'close'):
1866 if hasattr(other, 'close'):
1873 other.close()
1867 other.close()
1874 if cleanup:
1868 if cleanup:
1875 os.unlink(cleanup)
1869 os.unlink(cleanup)
1876
1870
1877 def init(ui, dest=".", **opts):
1871 def init(ui, dest=".", **opts):
1878 """create a new repository in the given directory
1872 """create a new repository in the given directory
1879
1873
1880 Initialize a new repository in the given directory. If the given
1874 Initialize a new repository in the given directory. If the given
1881 directory does not exist, it is created.
1875 directory does not exist, it is created.
1882
1876
1883 If no directory is given, the current directory is used.
1877 If no directory is given, the current directory is used.
1884
1878
1885 It is possible to specify an ssh:// URL as the destination.
1879 It is possible to specify an ssh:// URL as the destination.
1886 Look at the help text for the pull command for important details
1880 Look at the help text for the pull command for important details
1887 about ssh:// URLs.
1881 about ssh:// URLs.
1888 """
1882 """
1889 ui.setconfig_remoteopts(**opts)
1883 ui.setconfig_remoteopts(**opts)
1890 hg.repository(ui, dest, create=1)
1884 hg.repository(ui, dest, create=1)
1891
1885
1892 def locate(ui, repo, *pats, **opts):
1886 def locate(ui, repo, *pats, **opts):
1893 """locate files matching specific patterns
1887 """locate files matching specific patterns
1894
1888
1895 Print all files under Mercurial control whose names match the
1889 Print all files under Mercurial control whose names match the
1896 given patterns.
1890 given patterns.
1897
1891
1898 This command searches the current directory and its
1892 This command searches the current directory and its
1899 subdirectories. To search an entire repository, move to the root
1893 subdirectories. To search an entire repository, move to the root
1900 of the repository.
1894 of the repository.
1901
1895
1902 If no patterns are given to match, this command prints all file
1896 If no patterns are given to match, this command prints all file
1903 names.
1897 names.
1904
1898
1905 If you want to feed the output of this command into the "xargs"
1899 If you want to feed the output of this command into the "xargs"
1906 command, use the "-0" option to both this command and "xargs".
1900 command, use the "-0" option to both this command and "xargs".
1907 This will avoid the problem of "xargs" treating single filenames
1901 This will avoid the problem of "xargs" treating single filenames
1908 that contain white space as multiple filenames.
1902 that contain white space as multiple filenames.
1909 """
1903 """
1910 end = opts['print0'] and '\0' or '\n'
1904 end = opts['print0'] and '\0' or '\n'
1911 rev = opts['rev']
1905 rev = opts['rev']
1912 if rev:
1906 if rev:
1913 node = repo.lookup(rev)
1907 node = repo.lookup(rev)
1914 else:
1908 else:
1915 node = None
1909 node = None
1916
1910
1917 for src, abs, rel, exact in walk(repo, pats, opts, node=node,
1911 for src, abs, rel, exact in walk(repo, pats, opts, node=node,
1918 head='(?:.*/|)'):
1912 head='(?:.*/|)'):
1919 if not node and repo.dirstate.state(abs) == '?':
1913 if not node and repo.dirstate.state(abs) == '?':
1920 continue
1914 continue
1921 if opts['fullpath']:
1915 if opts['fullpath']:
1922 ui.write(os.path.join(repo.root, abs), end)
1916 ui.write(os.path.join(repo.root, abs), end)
1923 else:
1917 else:
1924 ui.write(((pats and rel) or abs), end)
1918 ui.write(((pats and rel) or abs), end)
1925
1919
1926 def log(ui, repo, *pats, **opts):
1920 def log(ui, repo, *pats, **opts):
1927 """show revision history of entire repository or files
1921 """show revision history of entire repository or files
1928
1922
1929 Print the revision history of the specified files or the entire project.
1923 Print the revision history of the specified files or the entire project.
1930
1924
1931 By default this command outputs: changeset id and hash, tags,
1925 By default this command outputs: changeset id and hash, tags,
1932 non-trivial parents, user, date and time, and a summary for each
1926 non-trivial parents, user, date and time, and a summary for each
1933 commit. When the -v/--verbose switch is used, the list of changed
1927 commit. When the -v/--verbose switch is used, the list of changed
1934 files and full commit message is shown.
1928 files and full commit message is shown.
1935 """
1929 """
1936 class dui(object):
1930 class dui(object):
1937 # Implement and delegate some ui protocol. Save hunks of
1931 # Implement and delegate some ui protocol. Save hunks of
1938 # output for later display in the desired order.
1932 # output for later display in the desired order.
1939 def __init__(self, ui):
1933 def __init__(self, ui):
1940 self.ui = ui
1934 self.ui = ui
1941 self.hunk = {}
1935 self.hunk = {}
1942 self.header = {}
1936 self.header = {}
1943 def bump(self, rev):
1937 def bump(self, rev):
1944 self.rev = rev
1938 self.rev = rev
1945 self.hunk[rev] = []
1939 self.hunk[rev] = []
1946 self.header[rev] = []
1940 self.header[rev] = []
1947 def note(self, *args):
1941 def note(self, *args):
1948 if self.verbose:
1942 if self.verbose:
1949 self.write(*args)
1943 self.write(*args)
1950 def status(self, *args):
1944 def status(self, *args):
1951 if not self.quiet:
1945 if not self.quiet:
1952 self.write(*args)
1946 self.write(*args)
1953 def write(self, *args):
1947 def write(self, *args):
1954 self.hunk[self.rev].append(args)
1948 self.hunk[self.rev].append(args)
1955 def write_header(self, *args):
1949 def write_header(self, *args):
1956 self.header[self.rev].append(args)
1950 self.header[self.rev].append(args)
1957 def debug(self, *args):
1951 def debug(self, *args):
1958 if self.debugflag:
1952 if self.debugflag:
1959 self.write(*args)
1953 self.write(*args)
1960 def __getattr__(self, key):
1954 def __getattr__(self, key):
1961 return getattr(self.ui, key)
1955 return getattr(self.ui, key)
1962
1956
1963 changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts)
1957 changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts)
1964
1958
1965 if opts['limit']:
1959 if opts['limit']:
1966 try:
1960 try:
1967 limit = int(opts['limit'])
1961 limit = int(opts['limit'])
1968 except ValueError:
1962 except ValueError:
1969 raise util.Abort(_('limit must be a positive integer'))
1963 raise util.Abort(_('limit must be a positive integer'))
1970 if limit <= 0: raise util.Abort(_('limit must be positive'))
1964 if limit <= 0: raise util.Abort(_('limit must be positive'))
1971 else:
1965 else:
1972 limit = sys.maxint
1966 limit = sys.maxint
1973 count = 0
1967 count = 0
1974
1968
1975 displayer = show_changeset(ui, repo, opts)
1969 displayer = show_changeset(ui, repo, opts)
1976 for st, rev, fns in changeiter:
1970 for st, rev, fns in changeiter:
1977 if st == 'window':
1971 if st == 'window':
1978 du = dui(ui)
1972 du = dui(ui)
1979 displayer.ui = du
1973 displayer.ui = du
1980 elif st == 'add':
1974 elif st == 'add':
1981 du.bump(rev)
1975 du.bump(rev)
1982 changenode = repo.changelog.node(rev)
1976 changenode = repo.changelog.node(rev)
1983 parents = [p for p in repo.changelog.parents(changenode)
1977 parents = [p for p in repo.changelog.parents(changenode)
1984 if p != nullid]
1978 if p != nullid]
1985 if opts['no_merges'] and len(parents) == 2:
1979 if opts['no_merges'] and len(parents) == 2:
1986 continue
1980 continue
1987 if opts['only_merges'] and len(parents) != 2:
1981 if opts['only_merges'] and len(parents) != 2:
1988 continue
1982 continue
1989
1983
1990 if opts['keyword']:
1984 if opts['keyword']:
1991 changes = getchange(rev)
1985 changes = getchange(rev)
1992 miss = 0
1986 miss = 0
1993 for k in [kw.lower() for kw in opts['keyword']]:
1987 for k in [kw.lower() for kw in opts['keyword']]:
1994 if not (k in changes[1].lower() or
1988 if not (k in changes[1].lower() or
1995 k in changes[4].lower() or
1989 k in changes[4].lower() or
1996 k in " ".join(changes[3][:20]).lower()):
1990 k in " ".join(changes[3][:20]).lower()):
1997 miss = 1
1991 miss = 1
1998 break
1992 break
1999 if miss:
1993 if miss:
2000 continue
1994 continue
2001
1995
2002 br = None
1996 br = None
2003 if opts['branches']:
1997 if opts['branches']:
2004 br = repo.branchlookup([repo.changelog.node(rev)])
1998 br = repo.branchlookup([repo.changelog.node(rev)])
2005
1999
2006 displayer.show(rev, brinfo=br)
2000 displayer.show(rev, brinfo=br)
2007 if opts['patch']:
2001 if opts['patch']:
2008 prev = (parents and parents[0]) or nullid
2002 prev = (parents and parents[0]) or nullid
2009 dodiff(du, du, repo, prev, changenode, match=matchfn)
2003 dodiff(du, du, repo, prev, changenode, match=matchfn)
2010 du.write("\n\n")
2004 du.write("\n\n")
2011 elif st == 'iter':
2005 elif st == 'iter':
2012 if count == limit: break
2006 if count == limit: break
2013 if du.header[rev]:
2007 if du.header[rev]:
2014 for args in du.header[rev]:
2008 for args in du.header[rev]:
2015 ui.write_header(*args)
2009 ui.write_header(*args)
2016 if du.hunk[rev]:
2010 if du.hunk[rev]:
2017 count += 1
2011 count += 1
2018 for args in du.hunk[rev]:
2012 for args in du.hunk[rev]:
2019 ui.write(*args)
2013 ui.write(*args)
2020
2014
2021 def manifest(ui, repo, rev=None):
2015 def manifest(ui, repo, rev=None):
2022 """output the latest or given revision of the project manifest
2016 """output the latest or given revision of the project manifest
2023
2017
2024 Print a list of version controlled files for the given revision.
2018 Print a list of version controlled files for the given revision.
2025
2019
2026 The manifest is the list of files being version controlled. If no revision
2020 The manifest is the list of files being version controlled. If no revision
2027 is given then the tip is used.
2021 is given then the tip is used.
2028 """
2022 """
2029 if rev:
2023 if rev:
2030 try:
2024 try:
2031 # assume all revision numbers are for changesets
2025 # assume all revision numbers are for changesets
2032 n = repo.lookup(rev)
2026 n = repo.lookup(rev)
2033 change = repo.changelog.read(n)
2027 change = repo.changelog.read(n)
2034 n = change[0]
2028 n = change[0]
2035 except hg.RepoError:
2029 except hg.RepoError:
2036 n = repo.manifest.lookup(rev)
2030 n = repo.manifest.lookup(rev)
2037 else:
2031 else:
2038 n = repo.manifest.tip()
2032 n = repo.manifest.tip()
2039 m = repo.manifest.read(n)
2033 m = repo.manifest.read(n)
2040 mf = repo.manifest.readflags(n)
2034 mf = repo.manifest.readflags(n)
2041 files = m.keys()
2035 files = m.keys()
2042 files.sort()
2036 files.sort()
2043
2037
2044 for f in files:
2038 for f in files:
2045 ui.write("%40s %3s %s\n" % (hex(m[f]), mf[f] and "755" or "644", f))
2039 ui.write("%40s %3s %s\n" % (hex(m[f]), mf[f] and "755" or "644", f))
2046
2040
2047 def merge(ui, repo, node=None, **opts):
2041 def merge(ui, repo, node=None, **opts):
2048 """Merge working directory with another revision
2042 """Merge working directory with another revision
2049
2043
2050 Merge the contents of the current working directory and the
2044 Merge the contents of the current working directory and the
2051 requested revision. Files that changed between either parent are
2045 requested revision. Files that changed between either parent are
2052 marked as changed for the next commit and a commit must be
2046 marked as changed for the next commit and a commit must be
2053 performed before any further updates are allowed.
2047 performed before any further updates are allowed.
2054 """
2048 """
2055 return doupdate(ui, repo, node=node, merge=True, **opts)
2049 return doupdate(ui, repo, node=node, merge=True, **opts)
2056
2050
2057 def outgoing(ui, repo, dest=None, **opts):
2051 def outgoing(ui, repo, dest=None, **opts):
2058 """show changesets not found in destination
2052 """show changesets not found in destination
2059
2053
2060 Show changesets not found in the specified destination repository or
2054 Show changesets not found in the specified destination repository or
2061 the default push location. These are the changesets that would be pushed
2055 the default push location. These are the changesets that would be pushed
2062 if a push was requested.
2056 if a push was requested.
2063
2057
2064 See pull for valid destination format details.
2058 See pull for valid destination format details.
2065 """
2059 """
2066 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2060 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2067 ui.setconfig_remoteopts(**opts)
2061 ui.setconfig_remoteopts(**opts)
2068 revs = None
2062 revs = None
2069 if opts['rev']:
2063 if opts['rev']:
2070 revs = [repo.lookup(rev) for rev in opts['rev']]
2064 revs = [repo.lookup(rev) for rev in opts['rev']]
2071
2065
2072 other = hg.repository(ui, dest)
2066 other = hg.repository(ui, dest)
2073 o = repo.findoutgoing(other, force=opts['force'])
2067 o = repo.findoutgoing(other, force=opts['force'])
2074 if not o:
2068 if not o:
2075 ui.status(_("no changes found\n"))
2069 ui.status(_("no changes found\n"))
2076 return
2070 return
2077 o = repo.changelog.nodesbetween(o, revs)[0]
2071 o = repo.changelog.nodesbetween(o, revs)[0]
2078 if opts['newest_first']:
2072 if opts['newest_first']:
2079 o.reverse()
2073 o.reverse()
2080 displayer = show_changeset(ui, repo, opts)
2074 displayer = show_changeset(ui, repo, opts)
2081 for n in o:
2075 for n in o:
2082 parents = [p for p in repo.changelog.parents(n) if p != nullid]
2076 parents = [p for p in repo.changelog.parents(n) if p != nullid]
2083 if opts['no_merges'] and len(parents) == 2:
2077 if opts['no_merges'] and len(parents) == 2:
2084 continue
2078 continue
2085 displayer.show(changenode=n)
2079 displayer.show(changenode=n)
2086 if opts['patch']:
2080 if opts['patch']:
2087 prev = (parents and parents[0]) or nullid
2081 prev = (parents and parents[0]) or nullid
2088 dodiff(ui, ui, repo, prev, n)
2082 dodiff(ui, ui, repo, prev, n)
2089 ui.write("\n")
2083 ui.write("\n")
2090
2084
2091 def parents(ui, repo, rev=None, branches=None, **opts):
2085 def parents(ui, repo, rev=None, branches=None, **opts):
2092 """show the parents of the working dir or revision
2086 """show the parents of the working dir or revision
2093
2087
2094 Print the working directory's parent revisions.
2088 Print the working directory's parent revisions.
2095 """
2089 """
2096 if rev:
2090 if rev:
2097 p = repo.changelog.parents(repo.lookup(rev))
2091 p = repo.changelog.parents(repo.lookup(rev))
2098 else:
2092 else:
2099 p = repo.dirstate.parents()
2093 p = repo.dirstate.parents()
2100
2094
2101 br = None
2095 br = None
2102 if branches is not None:
2096 if branches is not None:
2103 br = repo.branchlookup(p)
2097 br = repo.branchlookup(p)
2104 displayer = show_changeset(ui, repo, opts)
2098 displayer = show_changeset(ui, repo, opts)
2105 for n in p:
2099 for n in p:
2106 if n != nullid:
2100 if n != nullid:
2107 displayer.show(changenode=n, brinfo=br)
2101 displayer.show(changenode=n, brinfo=br)
2108
2102
2109 def paths(ui, repo, search=None):
2103 def paths(ui, repo, search=None):
2110 """show definition of symbolic path names
2104 """show definition of symbolic path names
2111
2105
2112 Show definition of symbolic path name NAME. If no name is given, show
2106 Show definition of symbolic path name NAME. If no name is given, show
2113 definition of available names.
2107 definition of available names.
2114
2108
2115 Path names are defined in the [paths] section of /etc/mercurial/hgrc
2109 Path names are defined in the [paths] section of /etc/mercurial/hgrc
2116 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
2110 and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too.
2117 """
2111 """
2118 if search:
2112 if search:
2119 for name, path in ui.configitems("paths"):
2113 for name, path in ui.configitems("paths"):
2120 if name == search:
2114 if name == search:
2121 ui.write("%s\n" % path)
2115 ui.write("%s\n" % path)
2122 return
2116 return
2123 ui.warn(_("not found!\n"))
2117 ui.warn(_("not found!\n"))
2124 return 1
2118 return 1
2125 else:
2119 else:
2126 for name, path in ui.configitems("paths"):
2120 for name, path in ui.configitems("paths"):
2127 ui.write("%s = %s\n" % (name, path))
2121 ui.write("%s = %s\n" % (name, path))
2128
2122
2129 def postincoming(ui, repo, modheads, optupdate):
2123 def postincoming(ui, repo, modheads, optupdate):
2130 if modheads == 0:
2124 if modheads == 0:
2131 return
2125 return
2132 if optupdate:
2126 if optupdate:
2133 if modheads == 1:
2127 if modheads == 1:
2134 return doupdate(ui, repo)
2128 return doupdate(ui, repo)
2135 else:
2129 else:
2136 ui.status(_("not updating, since new heads added\n"))
2130 ui.status(_("not updating, since new heads added\n"))
2137 if modheads > 1:
2131 if modheads > 1:
2138 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2132 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2139 else:
2133 else:
2140 ui.status(_("(run 'hg update' to get a working copy)\n"))
2134 ui.status(_("(run 'hg update' to get a working copy)\n"))
2141
2135
2142 def pull(ui, repo, source="default", **opts):
2136 def pull(ui, repo, source="default", **opts):
2143 """pull changes from the specified source
2137 """pull changes from the specified source
2144
2138
2145 Pull changes from a remote repository to a local one.
2139 Pull changes from a remote repository to a local one.
2146
2140
2147 This finds all changes from the repository at the specified path
2141 This finds all changes from the repository at the specified path
2148 or URL and adds them to the local repository. By default, this
2142 or URL and adds them to the local repository. By default, this
2149 does not update the copy of the project in the working directory.
2143 does not update the copy of the project in the working directory.
2150
2144
2151 Valid URLs are of the form:
2145 Valid URLs are of the form:
2152
2146
2153 local/filesystem/path
2147 local/filesystem/path
2154 http://[user@]host[:port]/[path]
2148 http://[user@]host[:port]/[path]
2155 https://[user@]host[:port]/[path]
2149 https://[user@]host[:port]/[path]
2156 ssh://[user@]host[:port]/[path]
2150 ssh://[user@]host[:port]/[path]
2157
2151
2158 Some notes about using SSH with Mercurial:
2152 Some notes about using SSH with Mercurial:
2159 - SSH requires an accessible shell account on the destination machine
2153 - SSH requires an accessible shell account on the destination machine
2160 and a copy of hg in the remote path or specified with as remotecmd.
2154 and a copy of hg in the remote path or specified with as remotecmd.
2161 - path is relative to the remote user's home directory by default.
2155 - path is relative to the remote user's home directory by default.
2162 Use an extra slash at the start of a path to specify an absolute path:
2156 Use an extra slash at the start of a path to specify an absolute path:
2163 ssh://example.com//tmp/repository
2157 ssh://example.com//tmp/repository
2164 - Mercurial doesn't use its own compression via SSH; the right thing
2158 - Mercurial doesn't use its own compression via SSH; the right thing
2165 to do is to configure it in your ~/.ssh/ssh_config, e.g.:
2159 to do is to configure it in your ~/.ssh/ssh_config, e.g.:
2166 Host *.mylocalnetwork.example.com
2160 Host *.mylocalnetwork.example.com
2167 Compression off
2161 Compression off
2168 Host *
2162 Host *
2169 Compression on
2163 Compression on
2170 Alternatively specify "ssh -C" as your ssh command in your hgrc or
2164 Alternatively specify "ssh -C" as your ssh command in your hgrc or
2171 with the --ssh command line option.
2165 with the --ssh command line option.
2172 """
2166 """
2173 source = ui.expandpath(source)
2167 source = ui.expandpath(source)
2174 ui.setconfig_remoteopts(**opts)
2168 ui.setconfig_remoteopts(**opts)
2175
2169
2176 other = hg.repository(ui, source)
2170 other = hg.repository(ui, source)
2177 ui.status(_('pulling from %s\n') % (source))
2171 ui.status(_('pulling from %s\n') % (source))
2178 revs = None
2172 revs = None
2179 if opts['rev'] and not other.local():
2173 if opts['rev'] and not other.local():
2180 raise util.Abort(_("pull -r doesn't work for remote repositories yet"))
2174 raise util.Abort(_("pull -r doesn't work for remote repositories yet"))
2181 elif opts['rev']:
2175 elif opts['rev']:
2182 revs = [other.lookup(rev) for rev in opts['rev']]
2176 revs = [other.lookup(rev) for rev in opts['rev']]
2183 modheads = repo.pull(other, heads=revs, force=opts['force'])
2177 modheads = repo.pull(other, heads=revs, force=opts['force'])
2184 return postincoming(ui, repo, modheads, opts['update'])
2178 return postincoming(ui, repo, modheads, opts['update'])
2185
2179
2186 def push(ui, repo, dest=None, **opts):
2180 def push(ui, repo, dest=None, **opts):
2187 """push changes to the specified destination
2181 """push changes to the specified destination
2188
2182
2189 Push changes from the local repository to the given destination.
2183 Push changes from the local repository to the given destination.
2190
2184
2191 This is the symmetrical operation for pull. It helps to move
2185 This is the symmetrical operation for pull. It helps to move
2192 changes from the current repository to a different one. If the
2186 changes from the current repository to a different one. If the
2193 destination is local this is identical to a pull in that directory
2187 destination is local this is identical to a pull in that directory
2194 from the current one.
2188 from the current one.
2195
2189
2196 By default, push will refuse to run if it detects the result would
2190 By default, push will refuse to run if it detects the result would
2197 increase the number of remote heads. This generally indicates the
2191 increase the number of remote heads. This generally indicates the
2198 the client has forgotten to sync and merge before pushing.
2192 the client has forgotten to sync and merge before pushing.
2199
2193
2200 Valid URLs are of the form:
2194 Valid URLs are of the form:
2201
2195
2202 local/filesystem/path
2196 local/filesystem/path
2203 ssh://[user@]host[:port]/[path]
2197 ssh://[user@]host[:port]/[path]
2204
2198
2205 Look at the help text for the pull command for important details
2199 Look at the help text for the pull command for important details
2206 about ssh:// URLs.
2200 about ssh:// URLs.
2207
2201
2208 Pushing to http:// and https:// URLs is possible, too, if this
2202 Pushing to http:// and https:// URLs is possible, too, if this
2209 feature is enabled on the remote Mercurial server.
2203 feature is enabled on the remote Mercurial server.
2210 """
2204 """
2211 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2205 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2212 ui.setconfig_remoteopts(**opts)
2206 ui.setconfig_remoteopts(**opts)
2213
2207
2214 other = hg.repository(ui, dest)
2208 other = hg.repository(ui, dest)
2215 ui.status('pushing to %s\n' % (dest))
2209 ui.status('pushing to %s\n' % (dest))
2216 revs = None
2210 revs = None
2217 if opts['rev']:
2211 if opts['rev']:
2218 revs = [repo.lookup(rev) for rev in opts['rev']]
2212 revs = [repo.lookup(rev) for rev in opts['rev']]
2219 r = repo.push(other, opts['force'], revs=revs)
2213 r = repo.push(other, opts['force'], revs=revs)
2220 return r == 0
2214 return r == 0
2221
2215
2222 def rawcommit(ui, repo, *flist, **rc):
2216 def rawcommit(ui, repo, *flist, **rc):
2223 """raw commit interface (DEPRECATED)
2217 """raw commit interface (DEPRECATED)
2224
2218
2225 (DEPRECATED)
2219 (DEPRECATED)
2226 Lowlevel commit, for use in helper scripts.
2220 Lowlevel commit, for use in helper scripts.
2227
2221
2228 This command is not intended to be used by normal users, as it is
2222 This command is not intended to be used by normal users, as it is
2229 primarily useful for importing from other SCMs.
2223 primarily useful for importing from other SCMs.
2230
2224
2231 This command is now deprecated and will be removed in a future
2225 This command is now deprecated and will be removed in a future
2232 release, please use debugsetparents and commit instead.
2226 release, please use debugsetparents and commit instead.
2233 """
2227 """
2234
2228
2235 ui.warn(_("(the rawcommit command is deprecated)\n"))
2229 ui.warn(_("(the rawcommit command is deprecated)\n"))
2236
2230
2237 message = rc['message']
2231 message = rc['message']
2238 if not message and rc['logfile']:
2232 if not message and rc['logfile']:
2239 try:
2233 try:
2240 message = open(rc['logfile']).read()
2234 message = open(rc['logfile']).read()
2241 except IOError:
2235 except IOError:
2242 pass
2236 pass
2243 if not message and not rc['logfile']:
2237 if not message and not rc['logfile']:
2244 raise util.Abort(_("missing commit message"))
2238 raise util.Abort(_("missing commit message"))
2245
2239
2246 files = relpath(repo, list(flist))
2240 files = relpath(repo, list(flist))
2247 if rc['files']:
2241 if rc['files']:
2248 files += open(rc['files']).read().splitlines()
2242 files += open(rc['files']).read().splitlines()
2249
2243
2250 rc['parent'] = map(repo.lookup, rc['parent'])
2244 rc['parent'] = map(repo.lookup, rc['parent'])
2251
2245
2252 try:
2246 try:
2253 repo.rawcommit(files, message, rc['user'], rc['date'], *rc['parent'])
2247 repo.rawcommit(files, message, rc['user'], rc['date'], *rc['parent'])
2254 except ValueError, inst:
2248 except ValueError, inst:
2255 raise util.Abort(str(inst))
2249 raise util.Abort(str(inst))
2256
2250
2257 def recover(ui, repo):
2251 def recover(ui, repo):
2258 """roll back an interrupted transaction
2252 """roll back an interrupted transaction
2259
2253
2260 Recover from an interrupted commit or pull.
2254 Recover from an interrupted commit or pull.
2261
2255
2262 This command tries to fix the repository status after an interrupted
2256 This command tries to fix the repository status after an interrupted
2263 operation. It should only be necessary when Mercurial suggests it.
2257 operation. It should only be necessary when Mercurial suggests it.
2264 """
2258 """
2265 if repo.recover():
2259 if repo.recover():
2266 return repo.verify()
2260 return repo.verify()
2267 return 1
2261 return 1
2268
2262
2269 def remove(ui, repo, *pats, **opts):
2263 def remove(ui, repo, *pats, **opts):
2270 """remove the specified files on the next commit
2264 """remove the specified files on the next commit
2271
2265
2272 Schedule the indicated files for removal from the repository.
2266 Schedule the indicated files for removal from the repository.
2273
2267
2274 This command schedules the files to be removed at the next commit.
2268 This command schedules the files to be removed at the next commit.
2275 This only removes files from the current branch, not from the
2269 This only removes files from the current branch, not from the
2276 entire project history. If the files still exist in the working
2270 entire project history. If the files still exist in the working
2277 directory, they will be deleted from it. If invoked with --after,
2271 directory, they will be deleted from it. If invoked with --after,
2278 files that have been manually deleted are marked as removed.
2272 files that have been manually deleted are marked as removed.
2279
2273
2280 Modified files and added files are not removed by default. To
2274 Modified files and added files are not removed by default. To
2281 remove them, use the -f/--force option.
2275 remove them, use the -f/--force option.
2282 """
2276 """
2283 names = []
2277 names = []
2284 if not opts['after'] and not pats:
2278 if not opts['after'] and not pats:
2285 raise util.Abort(_('no files specified'))
2279 raise util.Abort(_('no files specified'))
2286 files, matchfn, anypats = matchpats(repo, pats, opts)
2280 files, matchfn, anypats = matchpats(repo, pats, opts)
2287 exact = dict.fromkeys(files)
2281 exact = dict.fromkeys(files)
2288 mardu = map(dict.fromkeys, repo.changes(files=files, match=matchfn))
2282 mardu = map(dict.fromkeys, repo.changes(files=files, match=matchfn))
2289 modified, added, removed, deleted, unknown = mardu
2283 modified, added, removed, deleted, unknown = mardu
2290 remove, forget = [], []
2284 remove, forget = [], []
2291 for src, abs, rel, exact in walk(repo, pats, opts):
2285 for src, abs, rel, exact in walk(repo, pats, opts):
2292 reason = None
2286 reason = None
2293 if abs not in deleted and opts['after']:
2287 if abs not in deleted and opts['after']:
2294 reason = _('is still present')
2288 reason = _('is still present')
2295 elif abs in modified and not opts['force']:
2289 elif abs in modified and not opts['force']:
2296 reason = _('is modified (use -f to force removal)')
2290 reason = _('is modified (use -f to force removal)')
2297 elif abs in added:
2291 elif abs in added:
2298 if opts['force']:
2292 if opts['force']:
2299 forget.append(abs)
2293 forget.append(abs)
2300 continue
2294 continue
2301 reason = _('has been marked for add (use -f to force removal)')
2295 reason = _('has been marked for add (use -f to force removal)')
2302 elif abs in unknown:
2296 elif abs in unknown:
2303 reason = _('is not managed')
2297 reason = _('is not managed')
2304 elif abs in removed:
2298 elif abs in removed:
2305 continue
2299 continue
2306 if reason:
2300 if reason:
2307 if exact:
2301 if exact:
2308 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
2302 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
2309 else:
2303 else:
2310 if ui.verbose or not exact:
2304 if ui.verbose or not exact:
2311 ui.status(_('removing %s\n') % rel)
2305 ui.status(_('removing %s\n') % rel)
2312 remove.append(abs)
2306 remove.append(abs)
2313 repo.forget(forget)
2307 repo.forget(forget)
2314 repo.remove(remove, unlink=not opts['after'])
2308 repo.remove(remove, unlink=not opts['after'])
2315
2309
2316 def rename(ui, repo, *pats, **opts):
2310 def rename(ui, repo, *pats, **opts):
2317 """rename files; equivalent of copy + remove
2311 """rename files; equivalent of copy + remove
2318
2312
2319 Mark dest as copies of sources; mark sources for deletion. If
2313 Mark dest as copies of sources; mark sources for deletion. If
2320 dest is a directory, copies are put in that directory. If dest is
2314 dest is a directory, copies are put in that directory. If dest is
2321 a file, there can only be one source.
2315 a file, there can only be one source.
2322
2316
2323 By default, this command copies the contents of files as they
2317 By default, this command copies the contents of files as they
2324 stand in the working directory. If invoked with --after, the
2318 stand in the working directory. If invoked with --after, the
2325 operation is recorded, but no copying is performed.
2319 operation is recorded, but no copying is performed.
2326
2320
2327 This command takes effect in the next commit.
2321 This command takes effect in the next commit.
2328
2322
2329 NOTE: This command should be treated as experimental. While it
2323 NOTE: This command should be treated as experimental. While it
2330 should properly record rename files, this information is not yet
2324 should properly record rename files, this information is not yet
2331 fully used by merge, nor fully reported by log.
2325 fully used by merge, nor fully reported by log.
2332 """
2326 """
2333 wlock = repo.wlock(0)
2327 wlock = repo.wlock(0)
2334 errs, copied = docopy(ui, repo, pats, opts, wlock)
2328 errs, copied = docopy(ui, repo, pats, opts, wlock)
2335 names = []
2329 names = []
2336 for abs, rel, exact in copied:
2330 for abs, rel, exact in copied:
2337 if ui.verbose or not exact:
2331 if ui.verbose or not exact:
2338 ui.status(_('removing %s\n') % rel)
2332 ui.status(_('removing %s\n') % rel)
2339 names.append(abs)
2333 names.append(abs)
2340 if not opts.get('dry_run'):
2334 if not opts.get('dry_run'):
2341 repo.remove(names, True, wlock)
2335 repo.remove(names, True, wlock)
2342 return errs
2336 return errs
2343
2337
2344 def revert(ui, repo, *pats, **opts):
2338 def revert(ui, repo, *pats, **opts):
2345 """revert files or dirs to their states as of some revision
2339 """revert files or dirs to their states as of some revision
2346
2340
2347 With no revision specified, revert the named files or directories
2341 With no revision specified, revert the named files or directories
2348 to the contents they had in the parent of the working directory.
2342 to the contents they had in the parent of the working directory.
2349 This restores the contents of the affected files to an unmodified
2343 This restores the contents of the affected files to an unmodified
2350 state. If the working directory has two parents, you must
2344 state. If the working directory has two parents, you must
2351 explicitly specify the revision to revert to.
2345 explicitly specify the revision to revert to.
2352
2346
2353 Modified files are saved with a .orig suffix before reverting.
2347 Modified files are saved with a .orig suffix before reverting.
2354 To disable these backups, use --no-backup.
2348 To disable these backups, use --no-backup.
2355
2349
2356 Using the -r option, revert the given files or directories to
2350 Using the -r option, revert the given files or directories to
2357 their contents as of a specific revision. This can be helpful to"roll
2351 their contents as of a specific revision. This can be helpful to"roll
2358 back" some or all of a change that should not have been committed.
2352 back" some or all of a change that should not have been committed.
2359
2353
2360 Revert modifies the working directory. It does not commit any
2354 Revert modifies the working directory. It does not commit any
2361 changes, or change the parent of the working directory. If you
2355 changes, or change the parent of the working directory. If you
2362 revert to a revision other than the parent of the working
2356 revert to a revision other than the parent of the working
2363 directory, the reverted files will thus appear modified
2357 directory, the reverted files will thus appear modified
2364 afterwards.
2358 afterwards.
2365
2359
2366 If a file has been deleted, it is recreated. If the executable
2360 If a file has been deleted, it is recreated. If the executable
2367 mode of a file was changed, it is reset.
2361 mode of a file was changed, it is reset.
2368
2362
2369 If names are given, all files matching the names are reverted.
2363 If names are given, all files matching the names are reverted.
2370
2364
2371 If no arguments are given, all files in the repository are reverted.
2365 If no arguments are given, all files in the repository are reverted.
2372 """
2366 """
2373 parent, p2 = repo.dirstate.parents()
2367 parent, p2 = repo.dirstate.parents()
2374 if opts['rev']:
2368 if opts['rev']:
2375 node = repo.lookup(opts['rev'])
2369 node = repo.lookup(opts['rev'])
2376 elif p2 != nullid:
2370 elif p2 != nullid:
2377 raise util.Abort(_('working dir has two parents; '
2371 raise util.Abort(_('working dir has two parents; '
2378 'you must specify the revision to revert to'))
2372 'you must specify the revision to revert to'))
2379 else:
2373 else:
2380 node = parent
2374 node = parent
2381 mf = repo.manifest.read(repo.changelog.read(node)[0])
2375 mf = repo.manifest.read(repo.changelog.read(node)[0])
2382 if node == parent:
2376 if node == parent:
2383 pmf = mf
2377 pmf = mf
2384 else:
2378 else:
2385 pmf = None
2379 pmf = None
2386
2380
2387 wlock = repo.wlock()
2381 wlock = repo.wlock()
2388
2382
2389 # need all matching names in dirstate and manifest of target rev,
2383 # need all matching names in dirstate and manifest of target rev,
2390 # so have to walk both. do not print errors if files exist in one
2384 # so have to walk both. do not print errors if files exist in one
2391 # but not other.
2385 # but not other.
2392
2386
2393 names = {}
2387 names = {}
2394 target_only = {}
2388 target_only = {}
2395
2389
2396 # walk dirstate.
2390 # walk dirstate.
2397
2391
2398 for src, abs, rel, exact in walk(repo, pats, opts, badmatch=mf.has_key):
2392 for src, abs, rel, exact in walk(repo, pats, opts, badmatch=mf.has_key):
2399 names[abs] = (rel, exact)
2393 names[abs] = (rel, exact)
2400 if src == 'b':
2394 if src == 'b':
2401 target_only[abs] = True
2395 target_only[abs] = True
2402
2396
2403 # walk target manifest.
2397 # walk target manifest.
2404
2398
2405 for src, abs, rel, exact in walk(repo, pats, opts, node=node,
2399 for src, abs, rel, exact in walk(repo, pats, opts, node=node,
2406 badmatch=names.has_key):
2400 badmatch=names.has_key):
2407 if abs in names: continue
2401 if abs in names: continue
2408 names[abs] = (rel, exact)
2402 names[abs] = (rel, exact)
2409 target_only[abs] = True
2403 target_only[abs] = True
2410
2404
2411 changes = repo.changes(match=names.has_key, wlock=wlock)
2405 changes = repo.changes(match=names.has_key, wlock=wlock)
2412 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
2406 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
2413
2407
2414 revert = ([], _('reverting %s\n'))
2408 revert = ([], _('reverting %s\n'))
2415 add = ([], _('adding %s\n'))
2409 add = ([], _('adding %s\n'))
2416 remove = ([], _('removing %s\n'))
2410 remove = ([], _('removing %s\n'))
2417 forget = ([], _('forgetting %s\n'))
2411 forget = ([], _('forgetting %s\n'))
2418 undelete = ([], _('undeleting %s\n'))
2412 undelete = ([], _('undeleting %s\n'))
2419 update = {}
2413 update = {}
2420
2414
2421 disptable = (
2415 disptable = (
2422 # dispatch table:
2416 # dispatch table:
2423 # file state
2417 # file state
2424 # action if in target manifest
2418 # action if in target manifest
2425 # action if not in target manifest
2419 # action if not in target manifest
2426 # make backup if in target manifest
2420 # make backup if in target manifest
2427 # make backup if not in target manifest
2421 # make backup if not in target manifest
2428 (modified, revert, remove, True, True),
2422 (modified, revert, remove, True, True),
2429 (added, revert, forget, True, False),
2423 (added, revert, forget, True, False),
2430 (removed, undelete, None, False, False),
2424 (removed, undelete, None, False, False),
2431 (deleted, revert, remove, False, False),
2425 (deleted, revert, remove, False, False),
2432 (unknown, add, None, True, False),
2426 (unknown, add, None, True, False),
2433 (target_only, add, None, False, False),
2427 (target_only, add, None, False, False),
2434 )
2428 )
2435
2429
2436 entries = names.items()
2430 entries = names.items()
2437 entries.sort()
2431 entries.sort()
2438
2432
2439 for abs, (rel, exact) in entries:
2433 for abs, (rel, exact) in entries:
2440 mfentry = mf.get(abs)
2434 mfentry = mf.get(abs)
2441 def handle(xlist, dobackup):
2435 def handle(xlist, dobackup):
2442 xlist[0].append(abs)
2436 xlist[0].append(abs)
2443 update[abs] = 1
2437 update[abs] = 1
2444 if dobackup and not opts['no_backup'] and os.path.exists(rel):
2438 if dobackup and not opts['no_backup'] and os.path.exists(rel):
2445 bakname = "%s.orig" % rel
2439 bakname = "%s.orig" % rel
2446 ui.note(_('saving current version of %s as %s\n') %
2440 ui.note(_('saving current version of %s as %s\n') %
2447 (rel, bakname))
2441 (rel, bakname))
2448 if not opts.get('dry_run'):
2442 if not opts.get('dry_run'):
2449 shutil.copyfile(rel, bakname)
2443 shutil.copyfile(rel, bakname)
2450 shutil.copymode(rel, bakname)
2444 shutil.copymode(rel, bakname)
2451 if ui.verbose or not exact:
2445 if ui.verbose or not exact:
2452 ui.status(xlist[1] % rel)
2446 ui.status(xlist[1] % rel)
2453 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2447 for table, hitlist, misslist, backuphit, backupmiss in disptable:
2454 if abs not in table: continue
2448 if abs not in table: continue
2455 # file has changed in dirstate
2449 # file has changed in dirstate
2456 if mfentry:
2450 if mfentry:
2457 handle(hitlist, backuphit)
2451 handle(hitlist, backuphit)
2458 elif misslist is not None:
2452 elif misslist is not None:
2459 handle(misslist, backupmiss)
2453 handle(misslist, backupmiss)
2460 else:
2454 else:
2461 if exact: ui.warn(_('file not managed: %s\n' % rel))
2455 if exact: ui.warn(_('file not managed: %s\n' % rel))
2462 break
2456 break
2463 else:
2457 else:
2464 # file has not changed in dirstate
2458 # file has not changed in dirstate
2465 if node == parent:
2459 if node == parent:
2466 if exact: ui.warn(_('no changes needed to %s\n' % rel))
2460 if exact: ui.warn(_('no changes needed to %s\n' % rel))
2467 continue
2461 continue
2468 if pmf is None:
2462 if pmf is None:
2469 # only need parent manifest in this unlikely case,
2463 # only need parent manifest in this unlikely case,
2470 # so do not read by default
2464 # so do not read by default
2471 pmf = repo.manifest.read(repo.changelog.read(parent)[0])
2465 pmf = repo.manifest.read(repo.changelog.read(parent)[0])
2472 if abs in pmf:
2466 if abs in pmf:
2473 if mfentry:
2467 if mfentry:
2474 # if version of file is same in parent and target
2468 # if version of file is same in parent and target
2475 # manifests, do nothing
2469 # manifests, do nothing
2476 if pmf[abs] != mfentry:
2470 if pmf[abs] != mfentry:
2477 handle(revert, False)
2471 handle(revert, False)
2478 else:
2472 else:
2479 handle(remove, False)
2473 handle(remove, False)
2480
2474
2481 if not opts.get('dry_run'):
2475 if not opts.get('dry_run'):
2482 repo.dirstate.forget(forget[0])
2476 repo.dirstate.forget(forget[0])
2483 r = repo.update(node, False, True, update.has_key, False, wlock=wlock,
2477 r = repo.update(node, False, True, update.has_key, False, wlock=wlock,
2484 show_stats=False)
2478 show_stats=False)
2485 repo.dirstate.update(add[0], 'a')
2479 repo.dirstate.update(add[0], 'a')
2486 repo.dirstate.update(undelete[0], 'n')
2480 repo.dirstate.update(undelete[0], 'n')
2487 repo.dirstate.update(remove[0], 'r')
2481 repo.dirstate.update(remove[0], 'r')
2488 return r
2482 return r
2489
2483
2490 def rollback(ui, repo):
2484 def rollback(ui, repo):
2491 """roll back the last transaction in this repository
2485 """roll back the last transaction in this repository
2492
2486
2493 Roll back the last transaction in this repository, restoring the
2487 Roll back the last transaction in this repository, restoring the
2494 project to its state prior to the transaction.
2488 project to its state prior to the transaction.
2495
2489
2496 Transactions are used to encapsulate the effects of all commands
2490 Transactions are used to encapsulate the effects of all commands
2497 that create new changesets or propagate existing changesets into a
2491 that create new changesets or propagate existing changesets into a
2498 repository. For example, the following commands are transactional,
2492 repository. For example, the following commands are transactional,
2499 and their effects can be rolled back:
2493 and their effects can be rolled back:
2500
2494
2501 commit
2495 commit
2502 import
2496 import
2503 pull
2497 pull
2504 push (with this repository as destination)
2498 push (with this repository as destination)
2505 unbundle
2499 unbundle
2506
2500
2507 This command should be used with care. There is only one level of
2501 This command should be used with care. There is only one level of
2508 rollback, and there is no way to undo a rollback.
2502 rollback, and there is no way to undo a rollback.
2509
2503
2510 This command is not intended for use on public repositories. Once
2504 This command is not intended for use on public repositories. Once
2511 changes are visible for pull by other users, rolling a transaction
2505 changes are visible for pull by other users, rolling a transaction
2512 back locally is ineffective (someone else may already have pulled
2506 back locally is ineffective (someone else may already have pulled
2513 the changes). Furthermore, a race is possible with readers of the
2507 the changes). Furthermore, a race is possible with readers of the
2514 repository; for example an in-progress pull from the repository
2508 repository; for example an in-progress pull from the repository
2515 may fail if a rollback is performed.
2509 may fail if a rollback is performed.
2516 """
2510 """
2517 repo.rollback()
2511 repo.rollback()
2518
2512
2519 def root(ui, repo):
2513 def root(ui, repo):
2520 """print the root (top) of the current working dir
2514 """print the root (top) of the current working dir
2521
2515
2522 Print the root directory of the current repository.
2516 Print the root directory of the current repository.
2523 """
2517 """
2524 ui.write(repo.root + "\n")
2518 ui.write(repo.root + "\n")
2525
2519
2526 def serve(ui, repo, **opts):
2520 def serve(ui, repo, **opts):
2527 """export the repository via HTTP
2521 """export the repository via HTTP
2528
2522
2529 Start a local HTTP repository browser and pull server.
2523 Start a local HTTP repository browser and pull server.
2530
2524
2531 By default, the server logs accesses to stdout and errors to
2525 By default, the server logs accesses to stdout and errors to
2532 stderr. Use the "-A" and "-E" options to log to files.
2526 stderr. Use the "-A" and "-E" options to log to files.
2533 """
2527 """
2534
2528
2535 if opts["stdio"]:
2529 if opts["stdio"]:
2536 if repo is None:
2530 if repo is None:
2537 raise hg.RepoError(_('no repo found'))
2531 raise hg.RepoError(_('no repo found'))
2538 s = sshserver.sshserver(ui, repo)
2532 s = sshserver.sshserver(ui, repo)
2539 s.serve_forever()
2533 s.serve_forever()
2540
2534
2541 optlist = ("name templates style address port ipv6"
2535 optlist = ("name templates style address port ipv6"
2542 " accesslog errorlog webdir_conf")
2536 " accesslog errorlog webdir_conf")
2543 for o in optlist.split():
2537 for o in optlist.split():
2544 if opts[o]:
2538 if opts[o]:
2545 ui.setconfig("web", o, opts[o])
2539 ui.setconfig("web", o, opts[o])
2546
2540
2547 if repo is None and not ui.config("web", "webdir_conf"):
2541 if repo is None and not ui.config("web", "webdir_conf"):
2548 raise hg.RepoError(_('no repo found'))
2542 raise hg.RepoError(_('no repo found'))
2549
2543
2550 if opts['daemon'] and not opts['daemon_pipefds']:
2544 if opts['daemon'] and not opts['daemon_pipefds']:
2551 rfd, wfd = os.pipe()
2545 rfd, wfd = os.pipe()
2552 args = sys.argv[:]
2546 args = sys.argv[:]
2553 args.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
2547 args.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
2554 pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
2548 pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
2555 args[0], args)
2549 args[0], args)
2556 os.close(wfd)
2550 os.close(wfd)
2557 os.read(rfd, 1)
2551 os.read(rfd, 1)
2558 os._exit(0)
2552 os._exit(0)
2559
2553
2560 try:
2554 try:
2561 httpd = hgweb.server.create_server(ui, repo)
2555 httpd = hgweb.server.create_server(ui, repo)
2562 except socket.error, inst:
2556 except socket.error, inst:
2563 raise util.Abort(_('cannot start server: ') + inst.args[1])
2557 raise util.Abort(_('cannot start server: ') + inst.args[1])
2564
2558
2565 if ui.verbose:
2559 if ui.verbose:
2566 addr, port = httpd.socket.getsockname()
2560 addr, port = httpd.socket.getsockname()
2567 if addr == '0.0.0.0':
2561 if addr == '0.0.0.0':
2568 addr = socket.gethostname()
2562 addr = socket.gethostname()
2569 else:
2563 else:
2570 try:
2564 try:
2571 addr = socket.gethostbyaddr(addr)[0]
2565 addr = socket.gethostbyaddr(addr)[0]
2572 except socket.error:
2566 except socket.error:
2573 pass
2567 pass
2574 if port != 80:
2568 if port != 80:
2575 ui.status(_('listening at http://%s:%d/\n') % (addr, port))
2569 ui.status(_('listening at http://%s:%d/\n') % (addr, port))
2576 else:
2570 else:
2577 ui.status(_('listening at http://%s/\n') % addr)
2571 ui.status(_('listening at http://%s/\n') % addr)
2578
2572
2579 if opts['pid_file']:
2573 if opts['pid_file']:
2580 fp = open(opts['pid_file'], 'w')
2574 fp = open(opts['pid_file'], 'w')
2581 fp.write(str(os.getpid()) + '\n')
2575 fp.write(str(os.getpid()) + '\n')
2582 fp.close()
2576 fp.close()
2583
2577
2584 if opts['daemon_pipefds']:
2578 if opts['daemon_pipefds']:
2585 rfd, wfd = [int(x) for x in opts['daemon_pipefds'].split(',')]
2579 rfd, wfd = [int(x) for x in opts['daemon_pipefds'].split(',')]
2586 os.close(rfd)
2580 os.close(rfd)
2587 os.write(wfd, 'y')
2581 os.write(wfd, 'y')
2588 os.close(wfd)
2582 os.close(wfd)
2589 sys.stdout.flush()
2583 sys.stdout.flush()
2590 sys.stderr.flush()
2584 sys.stderr.flush()
2591 fd = os.open(util.nulldev, os.O_RDWR)
2585 fd = os.open(util.nulldev, os.O_RDWR)
2592 if fd != 0: os.dup2(fd, 0)
2586 if fd != 0: os.dup2(fd, 0)
2593 if fd != 1: os.dup2(fd, 1)
2587 if fd != 1: os.dup2(fd, 1)
2594 if fd != 2: os.dup2(fd, 2)
2588 if fd != 2: os.dup2(fd, 2)
2595 if fd not in (0, 1, 2): os.close(fd)
2589 if fd not in (0, 1, 2): os.close(fd)
2596
2590
2597 httpd.serve_forever()
2591 httpd.serve_forever()
2598
2592
2599 def status(ui, repo, *pats, **opts):
2593 def status(ui, repo, *pats, **opts):
2600 """show changed files in the working directory
2594 """show changed files in the working directory
2601
2595
2602 Show changed files in the repository. If names are
2596 Show changed files in the repository. If names are
2603 given, only files that match are shown.
2597 given, only files that match are shown.
2604
2598
2605 The codes used to show the status of files are:
2599 The codes used to show the status of files are:
2606 M = modified
2600 M = modified
2607 A = added
2601 A = added
2608 R = removed
2602 R = removed
2609 ! = deleted, but still tracked
2603 ! = deleted, but still tracked
2610 ? = not tracked
2604 ? = not tracked
2611 I = ignored (not shown by default)
2605 I = ignored (not shown by default)
2612 = the previous added file was copied from here
2606 = the previous added file was copied from here
2613 """
2607 """
2614
2608
2615 show_ignored = opts['ignored'] and True or False
2609 show_ignored = opts['ignored'] and True or False
2616 files, matchfn, anypats = matchpats(repo, pats, opts)
2610 files, matchfn, anypats = matchpats(repo, pats, opts)
2617 cwd = (pats and repo.getcwd()) or ''
2611 cwd = (pats and repo.getcwd()) or ''
2618 modified, added, removed, deleted, unknown, ignored = [
2612 modified, added, removed, deleted, unknown, ignored = [
2619 [util.pathto(cwd, x) for x in n]
2613 [util.pathto(cwd, x) for x in n]
2620 for n in repo.changes(files=files, match=matchfn,
2614 for n in repo.changes(files=files, match=matchfn,
2621 show_ignored=show_ignored)]
2615 show_ignored=show_ignored)]
2622
2616
2623 changetypes = [('modified', 'M', modified),
2617 changetypes = [('modified', 'M', modified),
2624 ('added', 'A', added),
2618 ('added', 'A', added),
2625 ('removed', 'R', removed),
2619 ('removed', 'R', removed),
2626 ('deleted', '!', deleted),
2620 ('deleted', '!', deleted),
2627 ('unknown', '?', unknown),
2621 ('unknown', '?', unknown),
2628 ('ignored', 'I', ignored)]
2622 ('ignored', 'I', ignored)]
2629
2623
2630 end = opts['print0'] and '\0' or '\n'
2624 end = opts['print0'] and '\0' or '\n'
2631
2625
2632 for opt, char, changes in ([ct for ct in changetypes if opts[ct[0]]]
2626 for opt, char, changes in ([ct for ct in changetypes if opts[ct[0]]]
2633 or changetypes):
2627 or changetypes):
2634 if opts['no_status']:
2628 if opts['no_status']:
2635 format = "%%s%s" % end
2629 format = "%%s%s" % end
2636 else:
2630 else:
2637 format = "%s %%s%s" % (char, end)
2631 format = "%s %%s%s" % (char, end)
2638
2632
2639 for f in changes:
2633 for f in changes:
2640 ui.write(format % f)
2634 ui.write(format % f)
2641 if (opts.get('copies') and not opts.get('no_status')
2635 if (opts.get('copies') and not opts.get('no_status')
2642 and opt == 'added' and repo.dirstate.copies.has_key(f)):
2636 and opt == 'added' and repo.dirstate.copies.has_key(f)):
2643 ui.write(' %s%s' % (repo.dirstate.copies[f], end))
2637 ui.write(' %s%s' % (repo.dirstate.copies[f], end))
2644
2638
2645 def tag(ui, repo, name, rev_=None, **opts):
2639 def tag(ui, repo, name, rev_=None, **opts):
2646 """add a tag for the current tip or a given revision
2640 """add a tag for the current tip or a given revision
2647
2641
2648 Name a particular revision using <name>.
2642 Name a particular revision using <name>.
2649
2643
2650 Tags are used to name particular revisions of the repository and are
2644 Tags are used to name particular revisions of the repository and are
2651 very useful to compare different revision, to go back to significant
2645 very useful to compare different revision, to go back to significant
2652 earlier versions or to mark branch points as releases, etc.
2646 earlier versions or to mark branch points as releases, etc.
2653
2647
2654 If no revision is given, the tip is used.
2648 If no revision is given, the tip is used.
2655
2649
2656 To facilitate version control, distribution, and merging of tags,
2650 To facilitate version control, distribution, and merging of tags,
2657 they are stored as a file named ".hgtags" which is managed
2651 they are stored as a file named ".hgtags" which is managed
2658 similarly to other project files and can be hand-edited if
2652 similarly to other project files and can be hand-edited if
2659 necessary. The file '.hg/localtags' is used for local tags (not
2653 necessary. The file '.hg/localtags' is used for local tags (not
2660 shared among repositories).
2654 shared among repositories).
2661 """
2655 """
2662 if name == "tip":
2656 if name == "tip":
2663 raise util.Abort(_("the name 'tip' is reserved"))
2657 raise util.Abort(_("the name 'tip' is reserved"))
2664 if rev_ is not None:
2658 if rev_ is not None:
2665 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2659 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, "
2666 "please use 'hg tag [-r REV] NAME' instead\n"))
2660 "please use 'hg tag [-r REV] NAME' instead\n"))
2667 if opts['rev']:
2661 if opts['rev']:
2668 raise util.Abort(_("use only one form to specify the revision"))
2662 raise util.Abort(_("use only one form to specify the revision"))
2669 if opts['rev']:
2663 if opts['rev']:
2670 rev_ = opts['rev']
2664 rev_ = opts['rev']
2671 if rev_:
2665 if rev_:
2672 r = hex(repo.lookup(rev_))
2666 r = hex(repo.lookup(rev_))
2673 else:
2667 else:
2674 r = hex(repo.changelog.tip())
2668 r = hex(repo.changelog.tip())
2675
2669
2676 repo.tag(name, r, opts['local'], opts['message'], opts['user'],
2670 repo.tag(name, r, opts['local'], opts['message'], opts['user'],
2677 opts['date'])
2671 opts['date'])
2678
2672
2679 def tags(ui, repo):
2673 def tags(ui, repo):
2680 """list repository tags
2674 """list repository tags
2681
2675
2682 List the repository tags.
2676 List the repository tags.
2683
2677
2684 This lists both regular and local tags.
2678 This lists both regular and local tags.
2685 """
2679 """
2686
2680
2687 l = repo.tagslist()
2681 l = repo.tagslist()
2688 l.reverse()
2682 l.reverse()
2689 for t, n in l:
2683 for t, n in l:
2690 try:
2684 try:
2691 r = "%5d:%s" % (repo.changelog.rev(n), hex(n))
2685 r = "%5d:%s" % (repo.changelog.rev(n), hex(n))
2692 except KeyError:
2686 except KeyError:
2693 r = " ?:?"
2687 r = " ?:?"
2694 if ui.quiet:
2688 if ui.quiet:
2695 ui.write("%s\n" % t)
2689 ui.write("%s\n" % t)
2696 else:
2690 else:
2697 ui.write("%-30s %s\n" % (t, r))
2691 ui.write("%-30s %s\n" % (t, r))
2698
2692
2699 def tip(ui, repo, **opts):
2693 def tip(ui, repo, **opts):
2700 """show the tip revision
2694 """show the tip revision
2701
2695
2702 Show the tip revision.
2696 Show the tip revision.
2703 """
2697 """
2704 n = repo.changelog.tip()
2698 n = repo.changelog.tip()
2705 br = None
2699 br = None
2706 if opts['branches']:
2700 if opts['branches']:
2707 br = repo.branchlookup([n])
2701 br = repo.branchlookup([n])
2708 show_changeset(ui, repo, opts).show(changenode=n, brinfo=br)
2702 show_changeset(ui, repo, opts).show(changenode=n, brinfo=br)
2709 if opts['patch']:
2703 if opts['patch']:
2710 dodiff(ui, ui, repo, repo.changelog.parents(n)[0], n)
2704 dodiff(ui, ui, repo, repo.changelog.parents(n)[0], n)
2711
2705
2712 def unbundle(ui, repo, fname, **opts):
2706 def unbundle(ui, repo, fname, **opts):
2713 """apply a changegroup file
2707 """apply a changegroup file
2714
2708
2715 Apply a compressed changegroup file generated by the bundle
2709 Apply a compressed changegroup file generated by the bundle
2716 command.
2710 command.
2717 """
2711 """
2718 f = urllib.urlopen(fname)
2712 f = urllib.urlopen(fname)
2719
2713
2720 header = f.read(6)
2714 header = f.read(6)
2721 if not header.startswith("HG"):
2715 if not header.startswith("HG"):
2722 raise util.Abort(_("%s: not a Mercurial bundle file") % fname)
2716 raise util.Abort(_("%s: not a Mercurial bundle file") % fname)
2723 elif not header.startswith("HG10"):
2717 elif not header.startswith("HG10"):
2724 raise util.Abort(_("%s: unknown bundle version") % fname)
2718 raise util.Abort(_("%s: unknown bundle version") % fname)
2725 elif header == "HG10BZ":
2719 elif header == "HG10BZ":
2726 def generator(f):
2720 def generator(f):
2727 zd = bz2.BZ2Decompressor()
2721 zd = bz2.BZ2Decompressor()
2728 zd.decompress("BZ")
2722 zd.decompress("BZ")
2729 for chunk in f:
2723 for chunk in f:
2730 yield zd.decompress(chunk)
2724 yield zd.decompress(chunk)
2731 elif header == "HG10UN":
2725 elif header == "HG10UN":
2732 def generator(f):
2726 def generator(f):
2733 for chunk in f:
2727 for chunk in f:
2734 yield chunk
2728 yield chunk
2735 else:
2729 else:
2736 raise util.Abort(_("%s: unknown bundle compression type")
2730 raise util.Abort(_("%s: unknown bundle compression type")
2737 % fname)
2731 % fname)
2738 gen = generator(util.filechunkiter(f, 4096))
2732 gen = generator(util.filechunkiter(f, 4096))
2739 modheads = repo.addchangegroup(util.chunkbuffer(gen), 'unbundle')
2733 modheads = repo.addchangegroup(util.chunkbuffer(gen), 'unbundle')
2740 return postincoming(ui, repo, modheads, opts['update'])
2734 return postincoming(ui, repo, modheads, opts['update'])
2741
2735
2742 def undo(ui, repo):
2736 def undo(ui, repo):
2743 """undo the last commit or pull (DEPRECATED)
2737 """undo the last commit or pull (DEPRECATED)
2744
2738
2745 (DEPRECATED)
2739 (DEPRECATED)
2746 This command is now deprecated and will be removed in a future
2740 This command is now deprecated and will be removed in a future
2747 release. Please use the rollback command instead. For usage
2741 release. Please use the rollback command instead. For usage
2748 instructions, see the rollback command.
2742 instructions, see the rollback command.
2749 """
2743 """
2750 ui.warn(_('(the undo command is deprecated; use rollback instead)\n'))
2744 ui.warn(_('(the undo command is deprecated; use rollback instead)\n'))
2751 repo.rollback()
2745 repo.rollback()
2752
2746
2753 def update(ui, repo, node=None, merge=False, clean=False, force=None,
2747 def update(ui, repo, node=None, merge=False, clean=False, force=None,
2754 branch=None, **opts):
2748 branch=None, **opts):
2755 """update or merge working directory
2749 """update or merge working directory
2756
2750
2757 Update the working directory to the specified revision.
2751 Update the working directory to the specified revision.
2758
2752
2759 If there are no outstanding changes in the working directory and
2753 If there are no outstanding changes in the working directory and
2760 there is a linear relationship between the current version and the
2754 there is a linear relationship between the current version and the
2761 requested version, the result is the requested version.
2755 requested version, the result is the requested version.
2762
2756
2763 To merge the working directory with another revision, use the
2757 To merge the working directory with another revision, use the
2764 merge command.
2758 merge command.
2765
2759
2766 By default, update will refuse to run if doing so would require
2760 By default, update will refuse to run if doing so would require
2767 merging or discarding local changes.
2761 merging or discarding local changes.
2768 """
2762 """
2769 if merge:
2763 if merge:
2770 ui.warn(_('(the -m/--merge option is deprecated; '
2764 ui.warn(_('(the -m/--merge option is deprecated; '
2771 'use the merge command instead)\n'))
2765 'use the merge command instead)\n'))
2772 return doupdate(ui, repo, node, merge, clean, force, branch, **opts)
2766 return doupdate(ui, repo, node, merge, clean, force, branch, **opts)
2773
2767
2774 def doupdate(ui, repo, node=None, merge=False, clean=False, force=None,
2768 def doupdate(ui, repo, node=None, merge=False, clean=False, force=None,
2775 branch=None, **opts):
2769 branch=None, **opts):
2776 if branch:
2770 if branch:
2777 br = repo.branchlookup(branch=branch)
2771 br = repo.branchlookup(branch=branch)
2778 found = []
2772 found = []
2779 for x in br:
2773 for x in br:
2780 if branch in br[x]:
2774 if branch in br[x]:
2781 found.append(x)
2775 found.append(x)
2782 if len(found) > 1:
2776 if len(found) > 1:
2783 ui.warn(_("Found multiple heads for %s\n") % branch)
2777 ui.warn(_("Found multiple heads for %s\n") % branch)
2784 for x in found:
2778 for x in found:
2785 show_changeset(ui, repo, opts).show(changenode=x, brinfo=br)
2779 show_changeset(ui, repo, opts).show(changenode=x, brinfo=br)
2786 return 1
2780 return 1
2787 if len(found) == 1:
2781 if len(found) == 1:
2788 node = found[0]
2782 node = found[0]
2789 ui.warn(_("Using head %s for branch %s\n") % (short(node), branch))
2783 ui.warn(_("Using head %s for branch %s\n") % (short(node), branch))
2790 else:
2784 else:
2791 ui.warn(_("branch %s not found\n") % (branch))
2785 ui.warn(_("branch %s not found\n") % (branch))
2792 return 1
2786 return 1
2793 else:
2787 else:
2794 node = node and repo.lookup(node) or repo.changelog.tip()
2788 node = node and repo.lookup(node) or repo.changelog.tip()
2795 return repo.update(node, allow=merge, force=clean, forcemerge=force)
2789 return repo.update(node, allow=merge, force=clean, forcemerge=force)
2796
2790
2797 def verify(ui, repo):
2791 def verify(ui, repo):
2798 """verify the integrity of the repository
2792 """verify the integrity of the repository
2799
2793
2800 Verify the integrity of the current repository.
2794 Verify the integrity of the current repository.
2801
2795
2802 This will perform an extensive check of the repository's
2796 This will perform an extensive check of the repository's
2803 integrity, validating the hashes and checksums of each entry in
2797 integrity, validating the hashes and checksums of each entry in
2804 the changelog, manifest, and tracked files, as well as the
2798 the changelog, manifest, and tracked files, as well as the
2805 integrity of their crosslinks and indices.
2799 integrity of their crosslinks and indices.
2806 """
2800 """
2807 return repo.verify()
2801 return repo.verify()
2808
2802
2809 # Command options and aliases are listed here, alphabetically
2803 # Command options and aliases are listed here, alphabetically
2810
2804
2811 table = {
2805 table = {
2812 "^add":
2806 "^add":
2813 (add,
2807 (add,
2814 [('I', 'include', [], _('include names matching the given patterns')),
2808 [('I', 'include', [], _('include names matching the given patterns')),
2815 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2809 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2816 ('n', 'dry-run', None, _('do not perform actions, just print output'))],
2810 ('n', 'dry-run', None, _('do not perform actions, just print output'))],
2817 _('hg add [OPTION]... [FILE]...')),
2811 _('hg add [OPTION]... [FILE]...')),
2818 "debugaddremove|addremove":
2812 "addremove":
2819 (addremove,
2813 (addremove,
2820 [('I', 'include', [], _('include names matching the given patterns')),
2814 [('I', 'include', [], _('include names matching the given patterns')),
2821 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2815 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2822 ('n', 'dry-run', None, _('do not perform actions, just print output'))],
2816 ('n', 'dry-run', None, _('do not perform actions, just print output'))],
2823 _('hg addremove [OPTION]... [FILE]...')),
2817 _('hg addremove [OPTION]... [FILE]...')),
2824 "^annotate":
2818 "^annotate":
2825 (annotate,
2819 (annotate,
2826 [('r', 'rev', '', _('annotate the specified revision')),
2820 [('r', 'rev', '', _('annotate the specified revision')),
2827 ('a', 'text', None, _('treat all files as text')),
2821 ('a', 'text', None, _('treat all files as text')),
2828 ('u', 'user', None, _('list the author')),
2822 ('u', 'user', None, _('list the author')),
2829 ('d', 'date', None, _('list the date')),
2823 ('d', 'date', None, _('list the date')),
2830 ('n', 'number', None, _('list the revision number (default)')),
2824 ('n', 'number', None, _('list the revision number (default)')),
2831 ('c', 'changeset', None, _('list the changeset')),
2825 ('c', 'changeset', None, _('list the changeset')),
2832 ('I', 'include', [], _('include names matching the given patterns')),
2826 ('I', 'include', [], _('include names matching the given patterns')),
2833 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2827 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2834 _('hg annotate [-r REV] [-a] [-u] [-d] [-n] [-c] FILE...')),
2828 _('hg annotate [-r REV] [-a] [-u] [-d] [-n] [-c] FILE...')),
2835 "archive":
2829 "archive":
2836 (archive,
2830 (archive,
2837 [('', 'no-decode', None, _('do not pass files through decoders')),
2831 [('', 'no-decode', None, _('do not pass files through decoders')),
2838 ('p', 'prefix', '', _('directory prefix for files in archive')),
2832 ('p', 'prefix', '', _('directory prefix for files in archive')),
2839 ('r', 'rev', '', _('revision to distribute')),
2833 ('r', 'rev', '', _('revision to distribute')),
2840 ('t', 'type', '', _('type of distribution to create')),
2834 ('t', 'type', '', _('type of distribution to create')),
2841 ('I', 'include', [], _('include names matching the given patterns')),
2835 ('I', 'include', [], _('include names matching the given patterns')),
2842 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2836 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2843 _('hg archive [OPTION]... DEST')),
2837 _('hg archive [OPTION]... DEST')),
2844 "backout":
2838 "backout":
2845 (backout,
2839 (backout,
2846 [('', 'merge', None,
2840 [('', 'merge', None,
2847 _('merge with old dirstate parent after backout')),
2841 _('merge with old dirstate parent after backout')),
2848 ('m', 'message', '', _('use <text> as commit message')),
2842 ('m', 'message', '', _('use <text> as commit message')),
2849 ('l', 'logfile', '', _('read commit message from <file>')),
2843 ('l', 'logfile', '', _('read commit message from <file>')),
2850 ('d', 'date', '', _('record datecode as commit date')),
2844 ('d', 'date', '', _('record datecode as commit date')),
2851 ('', 'parent', '', _('parent to choose when backing out merge')),
2845 ('', 'parent', '', _('parent to choose when backing out merge')),
2852 ('u', 'user', '', _('record user as committer')),
2846 ('u', 'user', '', _('record user as committer')),
2853 ('I', 'include', [], _('include names matching the given patterns')),
2847 ('I', 'include', [], _('include names matching the given patterns')),
2854 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2848 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2855 _('hg backout [OPTION]... REV')),
2849 _('hg backout [OPTION]... REV')),
2856 "bundle":
2850 "bundle":
2857 (bundle,
2851 (bundle,
2858 [('f', 'force', None,
2852 [('f', 'force', None,
2859 _('run even when remote repository is unrelated'))],
2853 _('run even when remote repository is unrelated'))],
2860 _('hg bundle FILE DEST')),
2854 _('hg bundle FILE DEST')),
2861 "cat":
2855 "cat":
2862 (cat,
2856 (cat,
2863 [('o', 'output', '', _('print output to file with formatted name')),
2857 [('o', 'output', '', _('print output to file with formatted name')),
2864 ('r', 'rev', '', _('print the given revision')),
2858 ('r', 'rev', '', _('print the given revision')),
2865 ('I', 'include', [], _('include names matching the given patterns')),
2859 ('I', 'include', [], _('include names matching the given patterns')),
2866 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2860 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2867 _('hg cat [OPTION]... FILE...')),
2861 _('hg cat [OPTION]... FILE...')),
2868 "^clone":
2862 "^clone":
2869 (clone,
2863 (clone,
2870 [('U', 'noupdate', None, _('do not update the new working directory')),
2864 [('U', 'noupdate', None, _('do not update the new working directory')),
2871 ('r', 'rev', [],
2865 ('r', 'rev', [],
2872 _('a changeset you would like to have after cloning')),
2866 _('a changeset you would like to have after cloning')),
2873 ('', 'pull', None, _('use pull protocol to copy metadata')),
2867 ('', 'pull', None, _('use pull protocol to copy metadata')),
2874 ('', 'uncompressed', None,
2868 ('', 'uncompressed', None,
2875 _('use uncompressed transfer (fast over LAN)')),
2869 _('use uncompressed transfer (fast over LAN)')),
2876 ('e', 'ssh', '', _('specify ssh command to use')),
2870 ('e', 'ssh', '', _('specify ssh command to use')),
2877 ('', 'remotecmd', '',
2871 ('', 'remotecmd', '',
2878 _('specify hg command to run on the remote side'))],
2872 _('specify hg command to run on the remote side'))],
2879 _('hg clone [OPTION]... SOURCE [DEST]')),
2873 _('hg clone [OPTION]... SOURCE [DEST]')),
2880 "^commit|ci":
2874 "^commit|ci":
2881 (commit,
2875 (commit,
2882 [('A', 'addremove', None,
2876 [('A', 'addremove', None,
2883 _('mark new/missing files as added/removed before committing')),
2877 _('mark new/missing files as added/removed before committing')),
2884 ('m', 'message', '', _('use <text> as commit message')),
2878 ('m', 'message', '', _('use <text> as commit message')),
2885 ('l', 'logfile', '', _('read the commit message from <file>')),
2879 ('l', 'logfile', '', _('read the commit message from <file>')),
2886 ('d', 'date', '', _('record datecode as commit date')),
2880 ('d', 'date', '', _('record datecode as commit date')),
2887 ('u', 'user', '', _('record user as commiter')),
2881 ('u', 'user', '', _('record user as commiter')),
2888 ('I', 'include', [], _('include names matching the given patterns')),
2882 ('I', 'include', [], _('include names matching the given patterns')),
2889 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2883 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2890 _('hg commit [OPTION]... [FILE]...')),
2884 _('hg commit [OPTION]... [FILE]...')),
2891 "copy|cp":
2885 "copy|cp":
2892 (copy,
2886 (copy,
2893 [('A', 'after', None, _('record a copy that has already occurred')),
2887 [('A', 'after', None, _('record a copy that has already occurred')),
2894 ('f', 'force', None,
2888 ('f', 'force', None,
2895 _('forcibly copy over an existing managed file')),
2889 _('forcibly copy over an existing managed file')),
2896 ('I', 'include', [], _('include names matching the given patterns')),
2890 ('I', 'include', [], _('include names matching the given patterns')),
2897 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2891 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2898 ('n', 'dry-run', None, _('do not perform actions, just print output'))],
2892 ('n', 'dry-run', None, _('do not perform actions, just print output'))],
2899 _('hg copy [OPTION]... [SOURCE]... DEST')),
2893 _('hg copy [OPTION]... [SOURCE]... DEST')),
2900 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
2894 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
2901 "debugcomplete":
2895 "debugcomplete":
2902 (debugcomplete,
2896 (debugcomplete,
2903 [('o', 'options', None, _('show the command options'))],
2897 [('o', 'options', None, _('show the command options'))],
2904 _('debugcomplete [-o] CMD')),
2898 _('debugcomplete [-o] CMD')),
2905 "debugrebuildstate":
2899 "debugrebuildstate":
2906 (debugrebuildstate,
2900 (debugrebuildstate,
2907 [('r', 'rev', '', _('revision to rebuild to'))],
2901 [('r', 'rev', '', _('revision to rebuild to'))],
2908 _('debugrebuildstate [-r REV] [REV]')),
2902 _('debugrebuildstate [-r REV] [REV]')),
2909 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
2903 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
2910 "debugconfig": (debugconfig, [], _('debugconfig [NAME]...')),
2904 "debugconfig": (debugconfig, [], _('debugconfig [NAME]...')),
2911 "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
2905 "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
2912 "debugstate": (debugstate, [], _('debugstate')),
2906 "debugstate": (debugstate, [], _('debugstate')),
2913 "debugdata": (debugdata, [], _('debugdata FILE REV')),
2907 "debugdata": (debugdata, [], _('debugdata FILE REV')),
2914 "debugindex": (debugindex, [], _('debugindex FILE')),
2908 "debugindex": (debugindex, [], _('debugindex FILE')),
2915 "debugindexdot": (debugindexdot, [], _('debugindexdot FILE')),
2909 "debugindexdot": (debugindexdot, [], _('debugindexdot FILE')),
2916 "debugrename": (debugrename, [], _('debugrename FILE [REV]')),
2910 "debugrename": (debugrename, [], _('debugrename FILE [REV]')),
2917 "debugwalk":
2911 "debugwalk":
2918 (debugwalk,
2912 (debugwalk,
2919 [('I', 'include', [], _('include names matching the given patterns')),
2913 [('I', 'include', [], _('include names matching the given patterns')),
2920 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2914 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2921 _('debugwalk [OPTION]... [FILE]...')),
2915 _('debugwalk [OPTION]... [FILE]...')),
2922 "^diff":
2916 "^diff":
2923 (diff,
2917 (diff,
2924 [('r', 'rev', [], _('revision')),
2918 [('r', 'rev', [], _('revision')),
2925 ('a', 'text', None, _('treat all files as text')),
2919 ('a', 'text', None, _('treat all files as text')),
2926 ('p', 'show-function', None,
2920 ('p', 'show-function', None,
2927 _('show which function each change is in')),
2921 _('show which function each change is in')),
2928 ('w', 'ignore-all-space', None,
2922 ('w', 'ignore-all-space', None,
2929 _('ignore white space when comparing lines')),
2923 _('ignore white space when comparing lines')),
2930 ('b', 'ignore-space-change', None,
2924 ('b', 'ignore-space-change', None,
2931 _('ignore changes in the amount of white space')),
2925 _('ignore changes in the amount of white space')),
2932 ('B', 'ignore-blank-lines', None,
2926 ('B', 'ignore-blank-lines', None,
2933 _('ignore changes whose lines are all blank')),
2927 _('ignore changes whose lines are all blank')),
2934 ('I', 'include', [], _('include names matching the given patterns')),
2928 ('I', 'include', [], _('include names matching the given patterns')),
2935 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2929 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2936 _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')),
2930 _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')),
2937 "^export":
2931 "^export":
2938 (export,
2932 (export,
2939 [('o', 'output', '', _('print output to file with formatted name')),
2933 [('o', 'output', '', _('print output to file with formatted name')),
2940 ('a', 'text', None, _('treat all files as text')),
2934 ('a', 'text', None, _('treat all files as text')),
2941 ('', 'switch-parent', None, _('diff against the second parent'))],
2935 ('', 'switch-parent', None, _('diff against the second parent'))],
2942 _('hg export [-a] [-o OUTFILESPEC] REV...')),
2936 _('hg export [-a] [-o OUTFILESPEC] REV...')),
2943 "debugforget|forget":
2937 "debugforget|forget":
2944 (forget,
2938 (forget,
2945 [('I', 'include', [], _('include names matching the given patterns')),
2939 [('I', 'include', [], _('include names matching the given patterns')),
2946 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2940 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2947 _('hg forget [OPTION]... FILE...')),
2941 _('hg forget [OPTION]... FILE...')),
2948 "grep":
2942 "grep":
2949 (grep,
2943 (grep,
2950 [('0', 'print0', None, _('end fields with NUL')),
2944 [('0', 'print0', None, _('end fields with NUL')),
2951 ('', 'all', None, _('print all revisions that match')),
2945 ('', 'all', None, _('print all revisions that match')),
2952 ('i', 'ignore-case', None, _('ignore case when matching')),
2946 ('i', 'ignore-case', None, _('ignore case when matching')),
2953 ('l', 'files-with-matches', None,
2947 ('l', 'files-with-matches', None,
2954 _('print only filenames and revs that match')),
2948 _('print only filenames and revs that match')),
2955 ('n', 'line-number', None, _('print matching line numbers')),
2949 ('n', 'line-number', None, _('print matching line numbers')),
2956 ('r', 'rev', [], _('search in given revision range')),
2950 ('r', 'rev', [], _('search in given revision range')),
2957 ('u', 'user', None, _('print user who committed change')),
2951 ('u', 'user', None, _('print user who committed change')),
2958 ('I', 'include', [], _('include names matching the given patterns')),
2952 ('I', 'include', [], _('include names matching the given patterns')),
2959 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2953 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
2960 _('hg grep [OPTION]... PATTERN [FILE]...')),
2954 _('hg grep [OPTION]... PATTERN [FILE]...')),
2961 "heads":
2955 "heads":
2962 (heads,
2956 (heads,
2963 [('b', 'branches', None, _('show branches')),
2957 [('b', 'branches', None, _('show branches')),
2964 ('', 'style', '', _('display using template map file')),
2958 ('', 'style', '', _('display using template map file')),
2965 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2959 ('r', 'rev', '', _('show only heads which are descendants of rev')),
2966 ('', 'template', '', _('display with template'))],
2960 ('', 'template', '', _('display with template'))],
2967 _('hg heads [-b] [-r <rev>]')),
2961 _('hg heads [-b] [-r <rev>]')),
2968 "help": (help_, [], _('hg help [COMMAND]')),
2962 "help": (help_, [], _('hg help [COMMAND]')),
2969 "identify|id": (identify, [], _('hg identify')),
2963 "identify|id": (identify, [], _('hg identify')),
2970 "import|patch":
2964 "import|patch":
2971 (import_,
2965 (import_,
2972 [('p', 'strip', 1,
2966 [('p', 'strip', 1,
2973 _('directory strip option for patch. This has the same\n'
2967 _('directory strip option for patch. This has the same\n'
2974 'meaning as the corresponding patch option')),
2968 'meaning as the corresponding patch option')),
2975 ('m', 'message', '', _('use <text> as commit message')),
2969 ('m', 'message', '', _('use <text> as commit message')),
2976 ('b', 'base', '', _('base path')),
2970 ('b', 'base', '', _('base path')),
2977 ('f', 'force', None,
2971 ('f', 'force', None,
2978 _('skip check for outstanding uncommitted changes'))],
2972 _('skip check for outstanding uncommitted changes'))],
2979 _('hg import [-p NUM] [-b BASE] [-m MESSAGE] [-f] PATCH...')),
2973 _('hg import [-p NUM] [-b BASE] [-m MESSAGE] [-f] PATCH...')),
2980 "incoming|in": (incoming,
2974 "incoming|in": (incoming,
2981 [('M', 'no-merges', None, _('do not show merges')),
2975 [('M', 'no-merges', None, _('do not show merges')),
2982 ('f', 'force', None,
2976 ('f', 'force', None,
2983 _('run even when remote repository is unrelated')),
2977 _('run even when remote repository is unrelated')),
2984 ('', 'style', '', _('display using template map file')),
2978 ('', 'style', '', _('display using template map file')),
2985 ('n', 'newest-first', None, _('show newest record first')),
2979 ('n', 'newest-first', None, _('show newest record first')),
2986 ('', 'bundle', '', _('file to store the bundles into')),
2980 ('', 'bundle', '', _('file to store the bundles into')),
2987 ('p', 'patch', None, _('show patch')),
2981 ('p', 'patch', None, _('show patch')),
2988 ('r', 'rev', [], _('a specific revision you would like to pull')),
2982 ('r', 'rev', [], _('a specific revision you would like to pull')),
2989 ('', 'template', '', _('display with template')),
2983 ('', 'template', '', _('display with template')),
2990 ('e', 'ssh', '', _('specify ssh command to use')),
2984 ('e', 'ssh', '', _('specify ssh command to use')),
2991 ('', 'remotecmd', '',
2985 ('', 'remotecmd', '',
2992 _('specify hg command to run on the remote side'))],
2986 _('specify hg command to run on the remote side'))],
2993 _('hg incoming [-p] [-n] [-M] [-r REV]...'
2987 _('hg incoming [-p] [-n] [-M] [-r REV]...'
2994 ' [--bundle FILENAME] [SOURCE]')),
2988 ' [--bundle FILENAME] [SOURCE]')),
2995 "^init":
2989 "^init":
2996 (init,
2990 (init,
2997 [('e', 'ssh', '', _('specify ssh command to use')),
2991 [('e', 'ssh', '', _('specify ssh command to use')),
2998 ('', 'remotecmd', '',
2992 ('', 'remotecmd', '',
2999 _('specify hg command to run on the remote side'))],
2993 _('specify hg command to run on the remote side'))],
3000 _('hg init [-e FILE] [--remotecmd FILE] [DEST]')),
2994 _('hg init [-e FILE] [--remotecmd FILE] [DEST]')),
3001 "locate":
2995 "locate":
3002 (locate,
2996 (locate,
3003 [('r', 'rev', '', _('search the repository as it stood at rev')),
2997 [('r', 'rev', '', _('search the repository as it stood at rev')),
3004 ('0', 'print0', None,
2998 ('0', 'print0', None,
3005 _('end filenames with NUL, for use with xargs')),
2999 _('end filenames with NUL, for use with xargs')),
3006 ('f', 'fullpath', None,
3000 ('f', 'fullpath', None,
3007 _('print complete paths from the filesystem root')),
3001 _('print complete paths from the filesystem root')),
3008 ('I', 'include', [], _('include names matching the given patterns')),
3002 ('I', 'include', [], _('include names matching the given patterns')),
3009 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
3003 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
3010 _('hg locate [OPTION]... [PATTERN]...')),
3004 _('hg locate [OPTION]... [PATTERN]...')),
3011 "^log|history":
3005 "^log|history":
3012 (log,
3006 (log,
3013 [('b', 'branches', None, _('show branches')),
3007 [('b', 'branches', None, _('show branches')),
3014 ('k', 'keyword', [], _('search for a keyword')),
3008 ('k', 'keyword', [], _('search for a keyword')),
3015 ('l', 'limit', '', _('limit number of changes displayed')),
3009 ('l', 'limit', '', _('limit number of changes displayed')),
3016 ('r', 'rev', [], _('show the specified revision or range')),
3010 ('r', 'rev', [], _('show the specified revision or range')),
3017 ('M', 'no-merges', None, _('do not show merges')),
3011 ('M', 'no-merges', None, _('do not show merges')),
3018 ('', 'style', '', _('display using template map file')),
3012 ('', 'style', '', _('display using template map file')),
3019 ('m', 'only-merges', None, _('show only merges')),
3013 ('m', 'only-merges', None, _('show only merges')),
3020 ('p', 'patch', None, _('show patch')),
3014 ('p', 'patch', None, _('show patch')),
3021 ('', 'template', '', _('display with template')),
3015 ('', 'template', '', _('display with template')),
3022 ('I', 'include', [], _('include names matching the given patterns')),
3016 ('I', 'include', [], _('include names matching the given patterns')),
3023 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
3017 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
3024 _('hg log [OPTION]... [FILE]')),
3018 _('hg log [OPTION]... [FILE]')),
3025 "manifest": (manifest, [], _('hg manifest [REV]')),
3019 "manifest": (manifest, [], _('hg manifest [REV]')),
3026 "merge":
3020 "merge":
3027 (merge,
3021 (merge,
3028 [('b', 'branch', '', _('merge with head of a specific branch')),
3022 [('b', 'branch', '', _('merge with head of a specific branch')),
3029 ('f', 'force', None, _('force a merge with outstanding changes'))],
3023 ('f', 'force', None, _('force a merge with outstanding changes'))],
3030 _('hg merge [-b TAG] [-f] [REV]')),
3024 _('hg merge [-b TAG] [-f] [REV]')),
3031 "outgoing|out": (outgoing,
3025 "outgoing|out": (outgoing,
3032 [('M', 'no-merges', None, _('do not show merges')),
3026 [('M', 'no-merges', None, _('do not show merges')),
3033 ('f', 'force', None,
3027 ('f', 'force', None,
3034 _('run even when remote repository is unrelated')),
3028 _('run even when remote repository is unrelated')),
3035 ('p', 'patch', None, _('show patch')),
3029 ('p', 'patch', None, _('show patch')),
3036 ('', 'style', '', _('display using template map file')),
3030 ('', 'style', '', _('display using template map file')),
3037 ('r', 'rev', [], _('a specific revision you would like to push')),
3031 ('r', 'rev', [], _('a specific revision you would like to push')),
3038 ('n', 'newest-first', None, _('show newest record first')),
3032 ('n', 'newest-first', None, _('show newest record first')),
3039 ('', 'template', '', _('display with template')),
3033 ('', 'template', '', _('display with template')),
3040 ('e', 'ssh', '', _('specify ssh command to use')),
3034 ('e', 'ssh', '', _('specify ssh command to use')),
3041 ('', 'remotecmd', '',
3035 ('', 'remotecmd', '',
3042 _('specify hg command to run on the remote side'))],
3036 _('specify hg command to run on the remote side'))],
3043 _('hg outgoing [-M] [-p] [-n] [-r REV]... [DEST]')),
3037 _('hg outgoing [-M] [-p] [-n] [-r REV]... [DEST]')),
3044 "^parents":
3038 "^parents":
3045 (parents,
3039 (parents,
3046 [('b', 'branches', None, _('show branches')),
3040 [('b', 'branches', None, _('show branches')),
3047 ('', 'style', '', _('display using template map file')),
3041 ('', 'style', '', _('display using template map file')),
3048 ('', 'template', '', _('display with template'))],
3042 ('', 'template', '', _('display with template'))],
3049 _('hg parents [-b] [REV]')),
3043 _('hg parents [-b] [REV]')),
3050 "paths": (paths, [], _('hg paths [NAME]')),
3044 "paths": (paths, [], _('hg paths [NAME]')),
3051 "^pull":
3045 "^pull":
3052 (pull,
3046 (pull,
3053 [('u', 'update', None,
3047 [('u', 'update', None,
3054 _('update the working directory to tip after pull')),
3048 _('update the working directory to tip after pull')),
3055 ('e', 'ssh', '', _('specify ssh command to use')),
3049 ('e', 'ssh', '', _('specify ssh command to use')),
3056 ('f', 'force', None,
3050 ('f', 'force', None,
3057 _('run even when remote repository is unrelated')),
3051 _('run even when remote repository is unrelated')),
3058 ('r', 'rev', [], _('a specific revision you would like to pull')),
3052 ('r', 'rev', [], _('a specific revision you would like to pull')),
3059 ('', 'remotecmd', '',
3053 ('', 'remotecmd', '',
3060 _('specify hg command to run on the remote side'))],
3054 _('specify hg command to run on the remote side'))],
3061 _('hg pull [-u] [-r REV]... [-e FILE] [--remotecmd FILE] [SOURCE]')),
3055 _('hg pull [-u] [-r REV]... [-e FILE] [--remotecmd FILE] [SOURCE]')),
3062 "^push":
3056 "^push":
3063 (push,
3057 (push,
3064 [('f', 'force', None, _('force push')),
3058 [('f', 'force', None, _('force push')),
3065 ('e', 'ssh', '', _('specify ssh command to use')),
3059 ('e', 'ssh', '', _('specify ssh command to use')),
3066 ('r', 'rev', [], _('a specific revision you would like to push')),
3060 ('r', 'rev', [], _('a specific revision you would like to push')),
3067 ('', 'remotecmd', '',
3061 ('', 'remotecmd', '',
3068 _('specify hg command to run on the remote side'))],
3062 _('specify hg command to run on the remote side'))],
3069 _('hg push [-f] [-r REV]... [-e FILE] [--remotecmd FILE] [DEST]')),
3063 _('hg push [-f] [-r REV]... [-e FILE] [--remotecmd FILE] [DEST]')),
3070 "debugrawcommit|rawcommit":
3064 "debugrawcommit|rawcommit":
3071 (rawcommit,
3065 (rawcommit,
3072 [('p', 'parent', [], _('parent')),
3066 [('p', 'parent', [], _('parent')),
3073 ('d', 'date', '', _('date code')),
3067 ('d', 'date', '', _('date code')),
3074 ('u', 'user', '', _('user')),
3068 ('u', 'user', '', _('user')),
3075 ('F', 'files', '', _('file list')),
3069 ('F', 'files', '', _('file list')),
3076 ('m', 'message', '', _('commit message')),
3070 ('m', 'message', '', _('commit message')),
3077 ('l', 'logfile', '', _('commit message file'))],
3071 ('l', 'logfile', '', _('commit message file'))],
3078 _('hg debugrawcommit [OPTION]... [FILE]...')),
3072 _('hg debugrawcommit [OPTION]... [FILE]...')),
3079 "recover": (recover, [], _('hg recover')),
3073 "recover": (recover, [], _('hg recover')),
3080 "^remove|rm":
3074 "^remove|rm":
3081 (remove,
3075 (remove,
3082 [('A', 'after', None, _('record remove that has already occurred')),
3076 [('A', 'after', None, _('record remove that has already occurred')),
3083 ('f', 'force', None, _('remove file even if modified')),
3077 ('f', 'force', None, _('remove file even if modified')),
3084 ('I', 'include', [], _('include names matching the given patterns')),
3078 ('I', 'include', [], _('include names matching the given patterns')),
3085 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
3079 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
3086 _('hg remove [OPTION]... FILE...')),
3080 _('hg remove [OPTION]... FILE...')),
3087 "rename|mv":
3081 "rename|mv":
3088 (rename,
3082 (rename,
3089 [('A', 'after', None, _('record a rename that has already occurred')),
3083 [('A', 'after', None, _('record a rename that has already occurred')),
3090 ('f', 'force', None,
3084 ('f', 'force', None,
3091 _('forcibly copy over an existing managed file')),
3085 _('forcibly copy over an existing managed file')),
3092 ('I', 'include', [], _('include names matching the given patterns')),
3086 ('I', 'include', [], _('include names matching the given patterns')),
3093 ('X', 'exclude', [], _('exclude names matching the given patterns')),
3087 ('X', 'exclude', [], _('exclude names matching the given patterns')),
3094 ('n', 'dry-run', None, _('do not perform actions, just print output'))],
3088 ('n', 'dry-run', None, _('do not perform actions, just print output'))],
3095 _('hg rename [OPTION]... SOURCE... DEST')),
3089 _('hg rename [OPTION]... SOURCE... DEST')),
3096 "^revert":
3090 "^revert":
3097 (revert,
3091 (revert,
3098 [('r', 'rev', '', _('revision to revert to')),
3092 [('r', 'rev', '', _('revision to revert to')),
3099 ('', 'no-backup', None, _('do not save backup copies of files')),
3093 ('', 'no-backup', None, _('do not save backup copies of files')),
3100 ('I', 'include', [], _('include names matching given patterns')),
3094 ('I', 'include', [], _('include names matching given patterns')),
3101 ('X', 'exclude', [], _('exclude names matching given patterns')),
3095 ('X', 'exclude', [], _('exclude names matching given patterns')),
3102 ('n', 'dry-run', None, _('do not perform actions, just print output'))],
3096 ('n', 'dry-run', None, _('do not perform actions, just print output'))],
3103 _('hg revert [-r REV] [NAME]...')),
3097 _('hg revert [-r REV] [NAME]...')),
3104 "rollback": (rollback, [], _('hg rollback')),
3098 "rollback": (rollback, [], _('hg rollback')),
3105 "root": (root, [], _('hg root')),
3099 "root": (root, [], _('hg root')),
3106 "^serve":
3100 "^serve":
3107 (serve,
3101 (serve,
3108 [('A', 'accesslog', '', _('name of access log file to write to')),
3102 [('A', 'accesslog', '', _('name of access log file to write to')),
3109 ('d', 'daemon', None, _('run server in background')),
3103 ('d', 'daemon', None, _('run server in background')),
3110 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3104 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
3111 ('E', 'errorlog', '', _('name of error log file to write to')),
3105 ('E', 'errorlog', '', _('name of error log file to write to')),
3112 ('p', 'port', 0, _('port to use (default: 8000)')),
3106 ('p', 'port', 0, _('port to use (default: 8000)')),
3113 ('a', 'address', '', _('address to use')),
3107 ('a', 'address', '', _('address to use')),
3114 ('n', 'name', '',
3108 ('n', 'name', '',
3115 _('name to show in web pages (default: working dir)')),
3109 _('name to show in web pages (default: working dir)')),
3116 ('', 'webdir-conf', '', _('name of the webdir config file'
3110 ('', 'webdir-conf', '', _('name of the webdir config file'
3117 ' (serve more than one repo)')),
3111 ' (serve more than one repo)')),
3118 ('', 'pid-file', '', _('name of file to write process ID to')),
3112 ('', 'pid-file', '', _('name of file to write process ID to')),
3119 ('', 'stdio', None, _('for remote clients')),
3113 ('', 'stdio', None, _('for remote clients')),
3120 ('t', 'templates', '', _('web templates to use')),
3114 ('t', 'templates', '', _('web templates to use')),
3121 ('', 'style', '', _('template style to use')),
3115 ('', 'style', '', _('template style to use')),
3122 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))],
3116 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))],
3123 _('hg serve [OPTION]...')),
3117 _('hg serve [OPTION]...')),
3124 "^status|st":
3118 "^status|st":
3125 (status,
3119 (status,
3126 [('m', 'modified', None, _('show only modified files')),
3120 [('m', 'modified', None, _('show only modified files')),
3127 ('a', 'added', None, _('show only added files')),
3121 ('a', 'added', None, _('show only added files')),
3128 ('r', 'removed', None, _('show only removed files')),
3122 ('r', 'removed', None, _('show only removed files')),
3129 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3123 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
3130 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3124 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
3131 ('i', 'ignored', None, _('show ignored files')),
3125 ('i', 'ignored', None, _('show ignored files')),
3132 ('n', 'no-status', None, _('hide status prefix')),
3126 ('n', 'no-status', None, _('hide status prefix')),
3133 ('C', 'copies', None, _('show source of copied files')),
3127 ('C', 'copies', None, _('show source of copied files')),
3134 ('0', 'print0', None,
3128 ('0', 'print0', None,
3135 _('end filenames with NUL, for use with xargs')),
3129 _('end filenames with NUL, for use with xargs')),
3136 ('I', 'include', [], _('include names matching the given patterns')),
3130 ('I', 'include', [], _('include names matching the given patterns')),
3137 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
3131 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
3138 _('hg status [OPTION]... [FILE]...')),
3132 _('hg status [OPTION]... [FILE]...')),
3139 "tag":
3133 "tag":
3140 (tag,
3134 (tag,
3141 [('l', 'local', None, _('make the tag local')),
3135 [('l', 'local', None, _('make the tag local')),
3142 ('m', 'message', '', _('message for tag commit log entry')),
3136 ('m', 'message', '', _('message for tag commit log entry')),
3143 ('d', 'date', '', _('record datecode as commit date')),
3137 ('d', 'date', '', _('record datecode as commit date')),
3144 ('u', 'user', '', _('record user as commiter')),
3138 ('u', 'user', '', _('record user as commiter')),
3145 ('r', 'rev', '', _('revision to tag'))],
3139 ('r', 'rev', '', _('revision to tag'))],
3146 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
3140 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
3147 "tags": (tags, [], _('hg tags')),
3141 "tags": (tags, [], _('hg tags')),
3148 "tip":
3142 "tip":
3149 (tip,
3143 (tip,
3150 [('b', 'branches', None, _('show branches')),
3144 [('b', 'branches', None, _('show branches')),
3151 ('', 'style', '', _('display using template map file')),
3145 ('', 'style', '', _('display using template map file')),
3152 ('p', 'patch', None, _('show patch')),
3146 ('p', 'patch', None, _('show patch')),
3153 ('', 'template', '', _('display with template'))],
3147 ('', 'template', '', _('display with template'))],
3154 _('hg tip [-b] [-p]')),
3148 _('hg tip [-b] [-p]')),
3155 "unbundle":
3149 "unbundle":
3156 (unbundle,
3150 (unbundle,
3157 [('u', 'update', None,
3151 [('u', 'update', None,
3158 _('update the working directory to tip after unbundle'))],
3152 _('update the working directory to tip after unbundle'))],
3159 _('hg unbundle [-u] FILE')),
3153 _('hg unbundle [-u] FILE')),
3160 "debugundo|undo": (undo, [], _('hg undo')),
3154 "debugundo|undo": (undo, [], _('hg undo')),
3161 "^update|up|checkout|co":
3155 "^update|up|checkout|co":
3162 (update,
3156 (update,
3163 [('b', 'branch', '', _('checkout the head of a specific branch')),
3157 [('b', 'branch', '', _('checkout the head of a specific branch')),
3164 ('m', 'merge', None, _('allow merging of branches (DEPRECATED)')),
3158 ('m', 'merge', None, _('allow merging of branches (DEPRECATED)')),
3165 ('C', 'clean', None, _('overwrite locally modified files')),
3159 ('C', 'clean', None, _('overwrite locally modified files')),
3166 ('f', 'force', None, _('force a merge with outstanding changes'))],
3160 ('f', 'force', None, _('force a merge with outstanding changes'))],
3167 _('hg update [-b TAG] [-m] [-C] [-f] [REV]')),
3161 _('hg update [-b TAG] [-m] [-C] [-f] [REV]')),
3168 "verify": (verify, [], _('hg verify')),
3162 "verify": (verify, [], _('hg verify')),
3169 "version": (show_version, [], _('hg version')),
3163 "version": (show_version, [], _('hg version')),
3170 }
3164 }
3171
3165
3172 globalopts = [
3166 globalopts = [
3173 ('R', 'repository', '',
3167 ('R', 'repository', '',
3174 _('repository root directory or symbolic path name')),
3168 _('repository root directory or symbolic path name')),
3175 ('', 'cwd', '', _('change working directory')),
3169 ('', 'cwd', '', _('change working directory')),
3176 ('y', 'noninteractive', None,
3170 ('y', 'noninteractive', None,
3177 _('do not prompt, assume \'yes\' for any required answers')),
3171 _('do not prompt, assume \'yes\' for any required answers')),
3178 ('q', 'quiet', None, _('suppress output')),
3172 ('q', 'quiet', None, _('suppress output')),
3179 ('v', 'verbose', None, _('enable additional output')),
3173 ('v', 'verbose', None, _('enable additional output')),
3180 ('', 'config', [], _('set/override config option')),
3174 ('', 'config', [], _('set/override config option')),
3181 ('', 'debug', None, _('enable debugging output')),
3175 ('', 'debug', None, _('enable debugging output')),
3182 ('', 'debugger', None, _('start debugger')),
3176 ('', 'debugger', None, _('start debugger')),
3183 ('', 'lsprof', None, _('print improved command execution profile')),
3177 ('', 'lsprof', None, _('print improved command execution profile')),
3184 ('', 'traceback', None, _('print traceback on exception')),
3178 ('', 'traceback', None, _('print traceback on exception')),
3185 ('', 'time', None, _('time how long the command takes')),
3179 ('', 'time', None, _('time how long the command takes')),
3186 ('', 'profile', None, _('print command execution profile')),
3180 ('', 'profile', None, _('print command execution profile')),
3187 ('', 'version', None, _('output version information and exit')),
3181 ('', 'version', None, _('output version information and exit')),
3188 ('h', 'help', None, _('display help and exit')),
3182 ('h', 'help', None, _('display help and exit')),
3189 ]
3183 ]
3190
3184
3191 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3185 norepo = ("clone init version help debugancestor debugcomplete debugdata"
3192 " debugindex debugindexdot")
3186 " debugindex debugindexdot")
3193 optionalrepo = ("paths serve debugconfig")
3187 optionalrepo = ("paths serve debugconfig")
3194
3188
3195 def findpossible(cmd):
3189 def findpossible(cmd):
3196 """
3190 """
3197 Return cmd -> (aliases, command table entry)
3191 Return cmd -> (aliases, command table entry)
3198 for each matching command.
3192 for each matching command.
3199 Return debug commands (or their aliases) only if no normal command matches.
3193 Return debug commands (or their aliases) only if no normal command matches.
3200 """
3194 """
3201 choice = {}
3195 choice = {}
3202 debugchoice = {}
3196 debugchoice = {}
3203 for e in table.keys():
3197 for e in table.keys():
3204 aliases = e.lstrip("^").split("|")
3198 aliases = e.lstrip("^").split("|")
3205 found = None
3199 found = None
3206 if cmd in aliases:
3200 if cmd in aliases:
3207 found = cmd
3201 found = cmd
3208 else:
3202 else:
3209 for a in aliases:
3203 for a in aliases:
3210 if a.startswith(cmd):
3204 if a.startswith(cmd):
3211 found = a
3205 found = a
3212 break
3206 break
3213 if found is not None:
3207 if found is not None:
3214 if aliases[0].startswith("debug"):
3208 if aliases[0].startswith("debug"):
3215 debugchoice[found] = (aliases, table[e])
3209 debugchoice[found] = (aliases, table[e])
3216 else:
3210 else:
3217 choice[found] = (aliases, table[e])
3211 choice[found] = (aliases, table[e])
3218
3212
3219 if not choice and debugchoice:
3213 if not choice and debugchoice:
3220 choice = debugchoice
3214 choice = debugchoice
3221
3215
3222 return choice
3216 return choice
3223
3217
3224 def findcmd(cmd):
3218 def findcmd(cmd):
3225 """Return (aliases, command table entry) for command string."""
3219 """Return (aliases, command table entry) for command string."""
3226 choice = findpossible(cmd)
3220 choice = findpossible(cmd)
3227
3221
3228 if choice.has_key(cmd):
3222 if choice.has_key(cmd):
3229 return choice[cmd]
3223 return choice[cmd]
3230
3224
3231 if len(choice) > 1:
3225 if len(choice) > 1:
3232 clist = choice.keys()
3226 clist = choice.keys()
3233 clist.sort()
3227 clist.sort()
3234 raise AmbiguousCommand(cmd, clist)
3228 raise AmbiguousCommand(cmd, clist)
3235
3229
3236 if choice:
3230 if choice:
3237 return choice.values()[0]
3231 return choice.values()[0]
3238
3232
3239 raise UnknownCommand(cmd)
3233 raise UnknownCommand(cmd)
3240
3234
3241 def catchterm(*args):
3235 def catchterm(*args):
3242 raise util.SignalInterrupt
3236 raise util.SignalInterrupt
3243
3237
3244 def run():
3238 def run():
3245 sys.exit(dispatch(sys.argv[1:]))
3239 sys.exit(dispatch(sys.argv[1:]))
3246
3240
3247 class ParseError(Exception):
3241 class ParseError(Exception):
3248 """Exception raised on errors in parsing the command line."""
3242 """Exception raised on errors in parsing the command line."""
3249
3243
3250 def parse(ui, args):
3244 def parse(ui, args):
3251 options = {}
3245 options = {}
3252 cmdoptions = {}
3246 cmdoptions = {}
3253
3247
3254 try:
3248 try:
3255 args = fancyopts.fancyopts(args, globalopts, options)
3249 args = fancyopts.fancyopts(args, globalopts, options)
3256 except fancyopts.getopt.GetoptError, inst:
3250 except fancyopts.getopt.GetoptError, inst:
3257 raise ParseError(None, inst)
3251 raise ParseError(None, inst)
3258
3252
3259 if args:
3253 if args:
3260 cmd, args = args[0], args[1:]
3254 cmd, args = args[0], args[1:]
3261 aliases, i = findcmd(cmd)
3255 aliases, i = findcmd(cmd)
3262 cmd = aliases[0]
3256 cmd = aliases[0]
3263 defaults = ui.config("defaults", cmd)
3257 defaults = ui.config("defaults", cmd)
3264 if defaults:
3258 if defaults:
3265 args = defaults.split() + args
3259 args = defaults.split() + args
3266 c = list(i[1])
3260 c = list(i[1])
3267 else:
3261 else:
3268 cmd = None
3262 cmd = None
3269 c = []
3263 c = []
3270
3264
3271 # combine global options into local
3265 # combine global options into local
3272 for o in globalopts:
3266 for o in globalopts:
3273 c.append((o[0], o[1], options[o[1]], o[3]))
3267 c.append((o[0], o[1], options[o[1]], o[3]))
3274
3268
3275 try:
3269 try:
3276 args = fancyopts.fancyopts(args, c, cmdoptions)
3270 args = fancyopts.fancyopts(args, c, cmdoptions)
3277 except fancyopts.getopt.GetoptError, inst:
3271 except fancyopts.getopt.GetoptError, inst:
3278 raise ParseError(cmd, inst)
3272 raise ParseError(cmd, inst)
3279
3273
3280 # separate global options back out
3274 # separate global options back out
3281 for o in globalopts:
3275 for o in globalopts:
3282 n = o[1]
3276 n = o[1]
3283 options[n] = cmdoptions[n]
3277 options[n] = cmdoptions[n]
3284 del cmdoptions[n]
3278 del cmdoptions[n]
3285
3279
3286 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
3280 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
3287
3281
3288 external = {}
3282 external = {}
3289
3283
3290 def findext(name):
3284 def findext(name):
3291 '''return module with given extension name'''
3285 '''return module with given extension name'''
3292 try:
3286 try:
3293 return sys.modules[external[name]]
3287 return sys.modules[external[name]]
3294 except KeyError:
3288 except KeyError:
3295 dotname = '.' + name
3289 dotname = '.' + name
3296 for k, v in external.iteritems():
3290 for k, v in external.iteritems():
3297 if k.endswith('.' + name) or v == name:
3291 if k.endswith('.' + name) or v == name:
3298 return sys.modules[v]
3292 return sys.modules[v]
3299 raise KeyError(name)
3293 raise KeyError(name)
3300
3294
3301 def dispatch(args):
3295 def dispatch(args):
3302 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
3296 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
3303 num = getattr(signal, name, None)
3297 num = getattr(signal, name, None)
3304 if num: signal.signal(num, catchterm)
3298 if num: signal.signal(num, catchterm)
3305
3299
3306 try:
3300 try:
3307 u = ui.ui(traceback='--traceback' in sys.argv[1:])
3301 u = ui.ui(traceback='--traceback' in sys.argv[1:])
3308 except util.Abort, inst:
3302 except util.Abort, inst:
3309 sys.stderr.write(_("abort: %s\n") % inst)
3303 sys.stderr.write(_("abort: %s\n") % inst)
3310 return -1
3304 return -1
3311
3305
3312 for ext_name, load_from_name in u.extensions():
3306 for ext_name, load_from_name in u.extensions():
3313 try:
3307 try:
3314 if load_from_name:
3308 if load_from_name:
3315 # the module will be loaded in sys.modules
3309 # the module will be loaded in sys.modules
3316 # choose an unique name so that it doesn't
3310 # choose an unique name so that it doesn't
3317 # conflicts with other modules
3311 # conflicts with other modules
3318 module_name = "hgext_%s" % ext_name.replace('.', '_')
3312 module_name = "hgext_%s" % ext_name.replace('.', '_')
3319 mod = imp.load_source(module_name, load_from_name)
3313 mod = imp.load_source(module_name, load_from_name)
3320 else:
3314 else:
3321 def importh(name):
3315 def importh(name):
3322 mod = __import__(name)
3316 mod = __import__(name)
3323 components = name.split('.')
3317 components = name.split('.')
3324 for comp in components[1:]:
3318 for comp in components[1:]:
3325 mod = getattr(mod, comp)
3319 mod = getattr(mod, comp)
3326 return mod
3320 return mod
3327 try:
3321 try:
3328 mod = importh("hgext.%s" % ext_name)
3322 mod = importh("hgext.%s" % ext_name)
3329 except ImportError:
3323 except ImportError:
3330 mod = importh(ext_name)
3324 mod = importh(ext_name)
3331 external[ext_name] = mod.__name__
3325 external[ext_name] = mod.__name__
3332 except (util.SignalInterrupt, KeyboardInterrupt):
3326 except (util.SignalInterrupt, KeyboardInterrupt):
3333 raise
3327 raise
3334 except Exception, inst:
3328 except Exception, inst:
3335 u.warn(_("*** failed to import extension %s: %s\n") % (ext_name, inst))
3329 u.warn(_("*** failed to import extension %s: %s\n") % (ext_name, inst))
3336 if u.print_exc():
3330 if u.print_exc():
3337 return 1
3331 return 1
3338
3332
3339 for name in external.itervalues():
3333 for name in external.itervalues():
3340 mod = sys.modules[name]
3334 mod = sys.modules[name]
3341 uisetup = getattr(mod, 'uisetup', None)
3335 uisetup = getattr(mod, 'uisetup', None)
3342 if uisetup:
3336 if uisetup:
3343 uisetup(u)
3337 uisetup(u)
3344 cmdtable = getattr(mod, 'cmdtable', {})
3338 cmdtable = getattr(mod, 'cmdtable', {})
3345 for t in cmdtable:
3339 for t in cmdtable:
3346 if t in table:
3340 if t in table:
3347 u.warn(_("module %s overrides %s\n") % (name, t))
3341 u.warn(_("module %s overrides %s\n") % (name, t))
3348 table.update(cmdtable)
3342 table.update(cmdtable)
3349
3343
3350 try:
3344 try:
3351 cmd, func, args, options, cmdoptions = parse(u, args)
3345 cmd, func, args, options, cmdoptions = parse(u, args)
3352 if options["time"]:
3346 if options["time"]:
3353 def get_times():
3347 def get_times():
3354 t = os.times()
3348 t = os.times()
3355 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
3349 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
3356 t = (t[0], t[1], t[2], t[3], time.clock())
3350 t = (t[0], t[1], t[2], t[3], time.clock())
3357 return t
3351 return t
3358 s = get_times()
3352 s = get_times()
3359 def print_time():
3353 def print_time():
3360 t = get_times()
3354 t = get_times()
3361 u.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
3355 u.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
3362 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
3356 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
3363 atexit.register(print_time)
3357 atexit.register(print_time)
3364
3358
3365 u.updateopts(options["verbose"], options["debug"], options["quiet"],
3359 u.updateopts(options["verbose"], options["debug"], options["quiet"],
3366 not options["noninteractive"], options["traceback"],
3360 not options["noninteractive"], options["traceback"],
3367 options["config"])
3361 options["config"])
3368
3362
3369 # enter the debugger before command execution
3363 # enter the debugger before command execution
3370 if options['debugger']:
3364 if options['debugger']:
3371 pdb.set_trace()
3365 pdb.set_trace()
3372
3366
3373 try:
3367 try:
3374 if options['cwd']:
3368 if options['cwd']:
3375 try:
3369 try:
3376 os.chdir(options['cwd'])
3370 os.chdir(options['cwd'])
3377 except OSError, inst:
3371 except OSError, inst:
3378 raise util.Abort('%s: %s' %
3372 raise util.Abort('%s: %s' %
3379 (options['cwd'], inst.strerror))
3373 (options['cwd'], inst.strerror))
3380
3374
3381 path = u.expandpath(options["repository"]) or ""
3375 path = u.expandpath(options["repository"]) or ""
3382 repo = path and hg.repository(u, path=path) or None
3376 repo = path and hg.repository(u, path=path) or None
3383
3377
3384 if options['help']:
3378 if options['help']:
3385 return help_(u, cmd, options['version'])
3379 return help_(u, cmd, options['version'])
3386 elif options['version']:
3380 elif options['version']:
3387 return show_version(u)
3381 return show_version(u)
3388 elif not cmd:
3382 elif not cmd:
3389 return help_(u, 'shortlist')
3383 return help_(u, 'shortlist')
3390
3384
3391 if cmd not in norepo.split():
3385 if cmd not in norepo.split():
3392 try:
3386 try:
3393 if not repo:
3387 if not repo:
3394 repo = hg.repository(u, path=path)
3388 repo = hg.repository(u, path=path)
3395 u = repo.ui
3389 u = repo.ui
3396 for name in external.itervalues():
3390 for name in external.itervalues():
3397 mod = sys.modules[name]
3391 mod = sys.modules[name]
3398 if hasattr(mod, 'reposetup'):
3392 if hasattr(mod, 'reposetup'):
3399 mod.reposetup(u, repo)
3393 mod.reposetup(u, repo)
3400 except hg.RepoError:
3394 except hg.RepoError:
3401 if cmd not in optionalrepo.split():
3395 if cmd not in optionalrepo.split():
3402 raise
3396 raise
3403 d = lambda: func(u, repo, *args, **cmdoptions)
3397 d = lambda: func(u, repo, *args, **cmdoptions)
3404 else:
3398 else:
3405 d = lambda: func(u, *args, **cmdoptions)
3399 d = lambda: func(u, *args, **cmdoptions)
3406
3400
3407 try:
3401 try:
3408 if options['profile']:
3402 if options['profile']:
3409 import hotshot, hotshot.stats
3403 import hotshot, hotshot.stats
3410 prof = hotshot.Profile("hg.prof")
3404 prof = hotshot.Profile("hg.prof")
3411 try:
3405 try:
3412 try:
3406 try:
3413 return prof.runcall(d)
3407 return prof.runcall(d)
3414 except:
3408 except:
3415 try:
3409 try:
3416 u.warn(_('exception raised - generating '
3410 u.warn(_('exception raised - generating '
3417 'profile anyway\n'))
3411 'profile anyway\n'))
3418 except:
3412 except:
3419 pass
3413 pass
3420 raise
3414 raise
3421 finally:
3415 finally:
3422 prof.close()
3416 prof.close()
3423 stats = hotshot.stats.load("hg.prof")
3417 stats = hotshot.stats.load("hg.prof")
3424 stats.strip_dirs()
3418 stats.strip_dirs()
3425 stats.sort_stats('time', 'calls')
3419 stats.sort_stats('time', 'calls')
3426 stats.print_stats(40)
3420 stats.print_stats(40)
3427 elif options['lsprof']:
3421 elif options['lsprof']:
3428 try:
3422 try:
3429 from mercurial import lsprof
3423 from mercurial import lsprof
3430 except ImportError:
3424 except ImportError:
3431 raise util.Abort(_(
3425 raise util.Abort(_(
3432 'lsprof not available - install from '
3426 'lsprof not available - install from '
3433 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
3427 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
3434 p = lsprof.Profiler()
3428 p = lsprof.Profiler()
3435 p.enable(subcalls=True)
3429 p.enable(subcalls=True)
3436 try:
3430 try:
3437 return d()
3431 return d()
3438 finally:
3432 finally:
3439 p.disable()
3433 p.disable()
3440 stats = lsprof.Stats(p.getstats())
3434 stats = lsprof.Stats(p.getstats())
3441 stats.sort()
3435 stats.sort()
3442 stats.pprint(top=10, file=sys.stderr, climit=5)
3436 stats.pprint(top=10, file=sys.stderr, climit=5)
3443 else:
3437 else:
3444 return d()
3438 return d()
3445 finally:
3439 finally:
3446 u.flush()
3440 u.flush()
3447 except:
3441 except:
3448 # enter the debugger when we hit an exception
3442 # enter the debugger when we hit an exception
3449 if options['debugger']:
3443 if options['debugger']:
3450 pdb.post_mortem(sys.exc_info()[2])
3444 pdb.post_mortem(sys.exc_info()[2])
3451 u.print_exc()
3445 u.print_exc()
3452 raise
3446 raise
3453 except ParseError, inst:
3447 except ParseError, inst:
3454 if inst.args[0]:
3448 if inst.args[0]:
3455 u.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
3449 u.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
3456 help_(u, inst.args[0])
3450 help_(u, inst.args[0])
3457 else:
3451 else:
3458 u.warn(_("hg: %s\n") % inst.args[1])
3452 u.warn(_("hg: %s\n") % inst.args[1])
3459 help_(u, 'shortlist')
3453 help_(u, 'shortlist')
3460 except AmbiguousCommand, inst:
3454 except AmbiguousCommand, inst:
3461 u.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
3455 u.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
3462 (inst.args[0], " ".join(inst.args[1])))
3456 (inst.args[0], " ".join(inst.args[1])))
3463 except UnknownCommand, inst:
3457 except UnknownCommand, inst:
3464 u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
3458 u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
3465 help_(u, 'shortlist')
3459 help_(u, 'shortlist')
3466 except hg.RepoError, inst:
3460 except hg.RepoError, inst:
3467 u.warn(_("abort: %s!\n") % inst)
3461 u.warn(_("abort: %s!\n") % inst)
3468 except lock.LockHeld, inst:
3462 except lock.LockHeld, inst:
3469 if inst.errno == errno.ETIMEDOUT:
3463 if inst.errno == errno.ETIMEDOUT:
3470 reason = _('timed out waiting for lock held by %s') % inst.locker
3464 reason = _('timed out waiting for lock held by %s') % inst.locker
3471 else:
3465 else:
3472 reason = _('lock held by %s') % inst.locker
3466 reason = _('lock held by %s') % inst.locker
3473 u.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
3467 u.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
3474 except lock.LockUnavailable, inst:
3468 except lock.LockUnavailable, inst:
3475 u.warn(_("abort: could not lock %s: %s\n") %
3469 u.warn(_("abort: could not lock %s: %s\n") %
3476 (inst.desc or inst.filename, inst.strerror))
3470 (inst.desc or inst.filename, inst.strerror))
3477 except revlog.RevlogError, inst:
3471 except revlog.RevlogError, inst:
3478 u.warn(_("abort: "), inst, "!\n")
3472 u.warn(_("abort: "), inst, "!\n")
3479 except util.SignalInterrupt:
3473 except util.SignalInterrupt:
3480 u.warn(_("killed!\n"))
3474 u.warn(_("killed!\n"))
3481 except KeyboardInterrupt:
3475 except KeyboardInterrupt:
3482 try:
3476 try:
3483 u.warn(_("interrupted!\n"))
3477 u.warn(_("interrupted!\n"))
3484 except IOError, inst:
3478 except IOError, inst:
3485 if inst.errno == errno.EPIPE:
3479 if inst.errno == errno.EPIPE:
3486 if u.debugflag:
3480 if u.debugflag:
3487 u.warn(_("\nbroken pipe\n"))
3481 u.warn(_("\nbroken pipe\n"))
3488 else:
3482 else:
3489 raise
3483 raise
3490 except IOError, inst:
3484 except IOError, inst:
3491 if hasattr(inst, "code"):
3485 if hasattr(inst, "code"):
3492 u.warn(_("abort: %s\n") % inst)
3486 u.warn(_("abort: %s\n") % inst)
3493 elif hasattr(inst, "reason"):
3487 elif hasattr(inst, "reason"):
3494 u.warn(_("abort: error: %s\n") % inst.reason[1])
3488 u.warn(_("abort: error: %s\n") % inst.reason[1])
3495 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
3489 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
3496 if u.debugflag:
3490 if u.debugflag:
3497 u.warn(_("broken pipe\n"))
3491 u.warn(_("broken pipe\n"))
3498 elif getattr(inst, "strerror", None):
3492 elif getattr(inst, "strerror", None):
3499 if getattr(inst, "filename", None):
3493 if getattr(inst, "filename", None):
3500 u.warn(_("abort: %s - %s\n") % (inst.strerror, inst.filename))
3494 u.warn(_("abort: %s - %s\n") % (inst.strerror, inst.filename))
3501 else:
3495 else:
3502 u.warn(_("abort: %s\n") % inst.strerror)
3496 u.warn(_("abort: %s\n") % inst.strerror)
3503 else:
3497 else:
3504 raise
3498 raise
3505 except OSError, inst:
3499 except OSError, inst:
3506 if hasattr(inst, "filename"):
3500 if hasattr(inst, "filename"):
3507 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
3501 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
3508 else:
3502 else:
3509 u.warn(_("abort: %s\n") % inst.strerror)
3503 u.warn(_("abort: %s\n") % inst.strerror)
3510 except util.Abort, inst:
3504 except util.Abort, inst:
3511 u.warn(_('abort: '), inst.args[0] % inst.args[1:], '\n')
3505 u.warn(_('abort: '), inst.args[0] % inst.args[1:], '\n')
3512 except TypeError, inst:
3506 except TypeError, inst:
3513 # was this an argument error?
3507 # was this an argument error?
3514 tb = traceback.extract_tb(sys.exc_info()[2])
3508 tb = traceback.extract_tb(sys.exc_info()[2])
3515 if len(tb) > 2: # no
3509 if len(tb) > 2: # no
3516 raise
3510 raise
3517 u.debug(inst, "\n")
3511 u.debug(inst, "\n")
3518 u.warn(_("%s: invalid arguments\n") % cmd)
3512 u.warn(_("%s: invalid arguments\n") % cmd)
3519 help_(u, cmd)
3513 help_(u, cmd)
3520 except SystemExit, inst:
3514 except SystemExit, inst:
3521 # Commands shouldn't sys.exit directly, but give a return code.
3515 # Commands shouldn't sys.exit directly, but give a return code.
3522 # Just in case catch this and and pass exit code to caller.
3516 # Just in case catch this and and pass exit code to caller.
3523 return inst.code
3517 return inst.code
3524 except:
3518 except:
3525 u.warn(_("** unknown exception encountered, details follow\n"))
3519 u.warn(_("** unknown exception encountered, details follow\n"))
3526 u.warn(_("** report bug details to "
3520 u.warn(_("** report bug details to "
3527 "http://www.selenic.com/mercurial/bts\n"))
3521 "http://www.selenic.com/mercurial/bts\n"))
3528 u.warn(_("** or mercurial@selenic.com\n"))
3522 u.warn(_("** or mercurial@selenic.com\n"))
3529 u.warn(_("** Mercurial Distributed SCM (version %s)\n")
3523 u.warn(_("** Mercurial Distributed SCM (version %s)\n")
3530 % version.get_version())
3524 % version.get_version())
3531 raise
3525 raise
3532
3526
3533 return -1
3527 return -1
@@ -1,10 +1,8 b''
1 (the addremove command is deprecated; use add and remove --after instead)
2 adding dir/bar
1 adding dir/bar
3 adding foo
2 adding foo
4 dir/bar
3 dir/bar
5 foo
4 foo
6 (the addremove command is deprecated; use add and remove --after instead)
7 adding dir/bar_2
5 adding dir/bar_2
8 adding foo_2
6 adding foo_2
9 dir/bar_2
7 dir/bar_2
10 foo_2
8 foo_2
@@ -1,42 +1,39 b''
1 (the addremove command is deprecated; use add and remove --after instead)
2 adding foo
1 adding foo
3 (the addremove command is deprecated; use add and remove --after instead)
4 adding bar
2 adding bar
5 (the addremove command is deprecated; use add and remove --after instead)
6 adding baz/bletch
3 adding baz/bletch
7 test-archive-TIP/.hg_archival.txt
4 test-archive-TIP/.hg_archival.txt
8 test-archive-TIP/bar
5 test-archive-TIP/bar
9 test-archive-TIP/baz/bletch
6 test-archive-TIP/baz/bletch
10 test-archive-TIP/foo
7 test-archive-TIP/foo
11 test-archive-TIP/.hg_archival.txt
8 test-archive-TIP/.hg_archival.txt
12 test-archive-TIP/bar
9 test-archive-TIP/bar
13 test-archive-TIP/baz/bletch
10 test-archive-TIP/baz/bletch
14 test-archive-TIP/foo
11 test-archive-TIP/foo
15 Archive: archive.zip
12 Archive: archive.zip
16 testing: test-archive-TIP/.hg_archival.txt OK
13 testing: test-archive-TIP/.hg_archival.txt OK
17 testing: test-archive-TIP/bar OK
14 testing: test-archive-TIP/bar OK
18 testing: test-archive-TIP/baz/bletch OK
15 testing: test-archive-TIP/baz/bletch OK
19 testing: test-archive-TIP/foo OK
16 testing: test-archive-TIP/foo OK
20 No errors detected in compressed data of archive.zip.
17 No errors detected in compressed data of archive.zip.
21 test/.hg_archival.txt
18 test/.hg_archival.txt
22 test/bar
19 test/bar
23 test/baz/bletch
20 test/baz/bletch
24 test/foo
21 test/foo
25 test/.hg_archival.txt
22 test/.hg_archival.txt
26 test/bar
23 test/bar
27 test/foo
24 test/foo
28 test-TIP/.hg_archival.txt
25 test-TIP/.hg_archival.txt
29 test-TIP/bar
26 test-TIP/bar
30 test-TIP/baz/bletch
27 test-TIP/baz/bletch
31 test-TIP/foo
28 test-TIP/foo
32 abort: archive prefix contains illegal components
29 abort: archive prefix contains illegal components
33 Archive: test.zip
30 Archive: test.zip
34 testing: test/.hg_archival.txt OK
31 testing: test/.hg_archival.txt OK
35 testing: test/bar OK
32 testing: test/bar OK
36 testing: test/baz/bletch OK
33 testing: test/baz/bletch OK
37 testing: test/foo OK
34 testing: test/foo OK
38 No errors detected in compressed data of test.zip.
35 No errors detected in compressed data of test.zip.
39 test-TIP/.hg_archival.txt
36 test-TIP/.hg_archival.txt
40 test-TIP/bar
37 test-TIP/bar
41 test-TIP/baz/bletch
38 test-TIP/baz/bletch
42 test-TIP/foo
39 test-TIP/foo
@@ -1,205 +1,207 b''
1 adding a
1 adding a
2 adding b
2 adding b
3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 pulling from ../b
4 pulling from ../b
5 searching for changes
5 searching for changes
6 warning: repository is unrelated
6 warning: repository is unrelated
7 adding changesets
7 adding changesets
8 adding manifests
8 adding manifests
9 adding file changes
9 adding file changes
10 added 1 changesets with 1 changes to 1 files (+1 heads)
10 added 1 changesets with 1 changes to 1 files (+1 heads)
11 (run 'hg heads' to see heads, 'hg merge' to merge)
11 (run 'hg heads' to see heads, 'hg merge' to merge)
12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
13 (branch merge, don't forget to commit)
13 (branch merge, don't forget to commit)
14 %% -R/--repository
14 %% -R/--repository
15 changeset: 0:8580ff50825a
15 changeset: 0:8580ff50825a
16 tag: tip
16 tag: tip
17 user: test
17 user: test
18 date: Thu Jan 01 00:00:01 1970 +0000
18 date: Thu Jan 01 00:00:01 1970 +0000
19 summary: a
19 summary: a
20
20
21 changeset: 0:b6c483daf290
21 changeset: 0:b6c483daf290
22 tag: tip
22 tag: tip
23 user: test
23 user: test
24 date: Thu Jan 01 00:00:01 1970 +0000
24 date: Thu Jan 01 00:00:01 1970 +0000
25 summary: b
25 summary: b
26
26
27 %% abbrev of long option
27 %% abbrev of long option
28 changeset: 1:b6c483daf290
28 changeset: 1:b6c483daf290
29 tag: tip
29 tag: tip
30 user: test
30 user: test
31 date: Thu Jan 01 00:00:01 1970 +0000
31 date: Thu Jan 01 00:00:01 1970 +0000
32 summary: b
32 summary: b
33
33
34 %% --cwd
34 %% --cwd
35 changeset: 0:8580ff50825a
35 changeset: 0:8580ff50825a
36 tag: tip
36 tag: tip
37 user: test
37 user: test
38 date: Thu Jan 01 00:00:01 1970 +0000
38 date: Thu Jan 01 00:00:01 1970 +0000
39 summary: a
39 summary: a
40
40
41 %% -y/--noninteractive - just be sure it is parsed
41 %% -y/--noninteractive - just be sure it is parsed
42 0:8580ff50825a
42 0:8580ff50825a
43 0:8580ff50825a
43 0:8580ff50825a
44 %% -q/--quiet
44 %% -q/--quiet
45 0:8580ff50825a
45 0:8580ff50825a
46 0:b6c483daf290
46 0:b6c483daf290
47 0:8580ff50825a
47 0:8580ff50825a
48 1:b6c483daf290
48 1:b6c483daf290
49 %% -v/--verbose
49 %% -v/--verbose
50 changeset: 1:b6c483daf2907ce5825c0bb50f5716226281cc1a
50 changeset: 1:b6c483daf2907ce5825c0bb50f5716226281cc1a
51 tag: tip
51 tag: tip
52 user: test
52 user: test
53 date: Thu Jan 01 00:00:01 1970 +0000
53 date: Thu Jan 01 00:00:01 1970 +0000
54 files: b
54 files: b
55 description:
55 description:
56 b
56 b
57
57
58
58
59 changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab
59 changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab
60 user: test
60 user: test
61 date: Thu Jan 01 00:00:01 1970 +0000
61 date: Thu Jan 01 00:00:01 1970 +0000
62 files: a
62 files: a
63 description:
63 description:
64 a
64 a
65
65
66
66
67 changeset: 0:b6c483daf2907ce5825c0bb50f5716226281cc1a
67 changeset: 0:b6c483daf2907ce5825c0bb50f5716226281cc1a
68 tag: tip
68 tag: tip
69 user: test
69 user: test
70 date: Thu Jan 01 00:00:01 1970 +0000
70 date: Thu Jan 01 00:00:01 1970 +0000
71 files: b
71 files: b
72 description:
72 description:
73 b
73 b
74
74
75
75
76 %% --config
76 %% --config
77 quuxfoo
77 quuxfoo
78 abort: malformed --config option:
78 abort: malformed --config option:
79 abort: malformed --config option: a.b
79 abort: malformed --config option: a.b
80 abort: malformed --config option: a
80 abort: malformed --config option: a
81 abort: malformed --config option: a.=
81 abort: malformed --config option: a.=
82 abort: malformed --config option: .b=
82 abort: malformed --config option: .b=
83 %% --debug
83 %% --debug
84 changeset: 1:b6c483daf2907ce5825c0bb50f5716226281cc1a
84 changeset: 1:b6c483daf2907ce5825c0bb50f5716226281cc1a
85 tag: tip
85 tag: tip
86 parent: -1:0000000000000000000000000000000000000000
86 parent: -1:0000000000000000000000000000000000000000
87 parent: -1:0000000000000000000000000000000000000000
87 parent: -1:0000000000000000000000000000000000000000
88 manifest: 1:23226e7a252cacdc2d99e4fbdc3653441056de49
88 manifest: 1:23226e7a252cacdc2d99e4fbdc3653441056de49
89 user: test
89 user: test
90 date: Thu Jan 01 00:00:01 1970 +0000
90 date: Thu Jan 01 00:00:01 1970 +0000
91 files+: b
91 files+: b
92 description:
92 description:
93 b
93 b
94
94
95
95
96 changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab
96 changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab
97 parent: -1:0000000000000000000000000000000000000000
97 parent: -1:0000000000000000000000000000000000000000
98 parent: -1:0000000000000000000000000000000000000000
98 parent: -1:0000000000000000000000000000000000000000
99 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
99 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
100 user: test
100 user: test
101 date: Thu Jan 01 00:00:01 1970 +0000
101 date: Thu Jan 01 00:00:01 1970 +0000
102 files+: a
102 files+: a
103 description:
103 description:
104 a
104 a
105
105
106
106
107 %% --traceback
107 %% --traceback
108 %% --time
108 %% --time
109 Time: real x.x secs (user x.x+x.x sys x.x+x.x)
109 Time: real x.x secs (user x.x+x.x sys x.x+x.x)
110 %% --version
110 %% --version
111 Mercurial Distributed SCM (version xxx)
111 Mercurial Distributed SCM (version xxx)
112 %% -h/--help
112 %% -h/--help
113 Mercurial Distributed SCM
113 Mercurial Distributed SCM
114
114
115 list of commands (use "hg help -v" to show aliases and global options):
115 list of commands (use "hg help -v" to show aliases and global options):
116
116
117 add add the specified files on the next commit
117 add add the specified files on the next commit
118 annotate show changeset information per file line
118 addremove add all new files, delete all missing files (DEPRECATED)
119 archive create unversioned archive of a repository revision
119 annotate show changeset information per file line
120 backout reverse effect of earlier changeset
120 archive create unversioned archive of a repository revision
121 bundle create a changegroup file
121 backout reverse effect of earlier changeset
122 cat output the latest or given revisions of files
122 bundle create a changegroup file
123 clone make a copy of an existing repository
123 cat output the latest or given revisions of files
124 commit commit the specified files or all outstanding changes
124 clone make a copy of an existing repository
125 copy mark files as copied for the next commit
125 commit commit the specified files or all outstanding changes
126 diff diff repository (or selected files)
126 copy mark files as copied for the next commit
127 export dump the header and diffs for one or more changesets
127 diff diff repository (or selected files)
128 grep search for a pattern in specified files and revisions
128 export dump the header and diffs for one or more changesets
129 heads show current repository heads
129 grep search for a pattern in specified files and revisions
130 help show help for a command, extension, or list of commands
130 heads show current repository heads
131 identify print information about the working copy
131 help show help for a command, extension, or list of commands
132 import import an ordered set of patches
132 identify print information about the working copy
133 incoming show new changesets found in source
133 import import an ordered set of patches
134 init create a new repository in the given directory
134 incoming show new changesets found in source
135 locate locate files matching specific patterns
135 init create a new repository in the given directory
136 log show revision history of entire repository or files
136 locate locate files matching specific patterns
137 manifest output the latest or given revision of the project manifest
137 log show revision history of entire repository or files
138 merge Merge working directory with another revision
138 manifest output the latest or given revision of the project manifest
139 outgoing show changesets not found in destination
139 merge Merge working directory with another revision
140 parents show the parents of the working dir or revision
140 outgoing show changesets not found in destination
141 paths show definition of symbolic path names
141 parents show the parents of the working dir or revision
142 pull pull changes from the specified source
142 paths show definition of symbolic path names
143 push push changes to the specified destination
143 pull pull changes from the specified source
144 recover roll back an interrupted transaction
144 push push changes to the specified destination
145 remove remove the specified files on the next commit
145 recover roll back an interrupted transaction
146 rename rename files; equivalent of copy + remove
146 remove remove the specified files on the next commit
147 revert revert files or dirs to their states as of some revision
147 rename rename files; equivalent of copy + remove
148 rollback roll back the last transaction in this repository
148 revert revert files or dirs to their states as of some revision
149 root print the root (top) of the current working dir
149 rollback roll back the last transaction in this repository
150 serve export the repository via HTTP
150 root print the root (top) of the current working dir
151 status show changed files in the working directory
151 serve export the repository via HTTP
152 tag add a tag for the current tip or a given revision
152 status show changed files in the working directory
153 tags list repository tags
153 tag add a tag for the current tip or a given revision
154 tip show the tip revision
154 tags list repository tags
155 unbundle apply a changegroup file
155 tip show the tip revision
156 update update or merge working directory
156 unbundle apply a changegroup file
157 verify verify the integrity of the repository
157 update update or merge working directory
158 version output version and copyright information
158 verify verify the integrity of the repository
159 version output version and copyright information
159 Mercurial Distributed SCM
160 Mercurial Distributed SCM
160
161
161 list of commands (use "hg help -v" to show aliases and global options):
162 list of commands (use "hg help -v" to show aliases and global options):
162
163
163 add add the specified files on the next commit
164 add add the specified files on the next commit
164 annotate show changeset information per file line
165 addremove add all new files, delete all missing files (DEPRECATED)
165 archive create unversioned archive of a repository revision
166 annotate show changeset information per file line
166 backout reverse effect of earlier changeset
167 archive create unversioned archive of a repository revision
167 bundle create a changegroup file
168 backout reverse effect of earlier changeset
168 cat output the latest or given revisions of files
169 bundle create a changegroup file
169 clone make a copy of an existing repository
170 cat output the latest or given revisions of files
170 commit commit the specified files or all outstanding changes
171 clone make a copy of an existing repository
171 copy mark files as copied for the next commit
172 commit commit the specified files or all outstanding changes
172 diff diff repository (or selected files)
173 copy mark files as copied for the next commit
173 export dump the header and diffs for one or more changesets
174 diff diff repository (or selected files)
174 grep search for a pattern in specified files and revisions
175 export dump the header and diffs for one or more changesets
175 heads show current repository heads
176 grep search for a pattern in specified files and revisions
176 help show help for a command, extension, or list of commands
177 heads show current repository heads
177 identify print information about the working copy
178 help show help for a command, extension, or list of commands
178 import import an ordered set of patches
179 identify print information about the working copy
179 incoming show new changesets found in source
180 import import an ordered set of patches
180 init create a new repository in the given directory
181 incoming show new changesets found in source
181 locate locate files matching specific patterns
182 init create a new repository in the given directory
182 log show revision history of entire repository or files
183 locate locate files matching specific patterns
183 manifest output the latest or given revision of the project manifest
184 log show revision history of entire repository or files
184 merge Merge working directory with another revision
185 manifest output the latest or given revision of the project manifest
185 outgoing show changesets not found in destination
186 merge Merge working directory with another revision
186 parents show the parents of the working dir or revision
187 outgoing show changesets not found in destination
187 paths show definition of symbolic path names
188 parents show the parents of the working dir or revision
188 pull pull changes from the specified source
189 paths show definition of symbolic path names
189 push push changes to the specified destination
190 pull pull changes from the specified source
190 recover roll back an interrupted transaction
191 push push changes to the specified destination
191 remove remove the specified files on the next commit
192 recover roll back an interrupted transaction
192 rename rename files; equivalent of copy + remove
193 remove remove the specified files on the next commit
193 revert revert files or dirs to their states as of some revision
194 rename rename files; equivalent of copy + remove
194 rollback roll back the last transaction in this repository
195 revert revert files or dirs to their states as of some revision
195 root print the root (top) of the current working dir
196 rollback roll back the last transaction in this repository
196 serve export the repository via HTTP
197 root print the root (top) of the current working dir
197 status show changed files in the working directory
198 serve export the repository via HTTP
198 tag add a tag for the current tip or a given revision
199 status show changed files in the working directory
199 tags list repository tags
200 tag add a tag for the current tip or a given revision
200 tip show the tip revision
201 tags list repository tags
201 unbundle apply a changegroup file
202 tip show the tip revision
202 update update or merge working directory
203 unbundle apply a changegroup file
203 verify verify the integrity of the repository
204 update update or merge working directory
204 version output version and copyright information
205 verify verify the integrity of the repository
206 version output version and copyright information
205 %% not tested: --debugger
207 %% not tested: --debugger
@@ -1,259 +1,261 b''
1 Mercurial Distributed SCM
1 Mercurial Distributed SCM
2
2
3 basic commands (use "hg help" for the full list or option "-v" for details):
3 basic commands (use "hg help" for the full list or option "-v" for details):
4
4
5 add add the specified files on the next commit
5 add add the specified files on the next commit
6 annotate show changeset information per file line
6 annotate show changeset information per file line
7 clone make a copy of an existing repository
7 clone make a copy of an existing repository
8 commit commit the specified files or all outstanding changes
8 commit commit the specified files or all outstanding changes
9 diff diff repository (or selected files)
9 diff diff repository (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 parents show the parents of the working dir or revision
13 parents show the parents of the working dir or revision
14 pull pull changes from the specified source
14 pull pull changes from the specified source
15 push push changes to the specified destination
15 push push changes to the specified destination
16 remove remove the specified files on the next commit
16 remove remove the specified files on the next commit
17 revert revert files or dirs to their states as of some revision
17 revert revert files or dirs to their states as of some revision
18 serve export the repository via HTTP
18 serve export the repository via HTTP
19 status show changed files in the working directory
19 status show changed files in the working directory
20 update update or merge working directory
20 update update or merge working directory
21 add add the specified files on the next commit
21 add add the specified files on the next commit
22 annotate show changeset information per file line
22 annotate show changeset information per file line
23 clone make a copy of an existing repository
23 clone make a copy of an existing repository
24 commit commit the specified files or all outstanding changes
24 commit commit the specified files or all outstanding changes
25 diff diff repository (or selected files)
25 diff diff repository (or selected files)
26 export dump the header and diffs for one or more changesets
26 export dump the header and diffs for one or more changesets
27 init create a new repository in the given directory
27 init create a new repository in the given directory
28 log show revision history of entire repository or files
28 log show revision history of entire repository or files
29 parents show the parents of the working dir or revision
29 parents show the parents of the working dir or revision
30 pull pull changes from the specified source
30 pull pull changes from the specified source
31 push push changes to the specified destination
31 push push changes to the specified destination
32 remove remove the specified files on the next commit
32 remove remove the specified files on the next commit
33 revert revert files or dirs to their states as of some revision
33 revert revert files or dirs to their states as of some revision
34 serve export the repository via HTTP
34 serve export the repository via HTTP
35 status show changed files in the working directory
35 status show changed files in the working directory
36 update update or merge working directory
36 update update or merge working directory
37 Mercurial Distributed SCM
37 Mercurial Distributed SCM
38
38
39 list of commands (use "hg help -v" to show aliases and global options):
39 list of commands (use "hg help -v" to show aliases and global options):
40
40
41 add add the specified files on the next commit
41 add add the specified files on the next commit
42 annotate show changeset information per file line
42 addremove add all new files, delete all missing files (DEPRECATED)
43 archive create unversioned archive of a repository revision
43 annotate show changeset information per file line
44 backout reverse effect of earlier changeset
44 archive create unversioned archive of a repository revision
45 bundle create a changegroup file
45 backout reverse effect of earlier changeset
46 cat output the latest or given revisions of files
46 bundle create a changegroup file
47 clone make a copy of an existing repository
47 cat output the latest or given revisions of files
48 commit commit the specified files or all outstanding changes
48 clone make a copy of an existing repository
49 copy mark files as copied for the next commit
49 commit commit the specified files or all outstanding changes
50 diff diff repository (or selected files)
50 copy mark files as copied for the next commit
51 export dump the header and diffs for one or more changesets
51 diff diff repository (or selected files)
52 grep search for a pattern in specified files and revisions
52 export dump the header and diffs for one or more changesets
53 heads show current repository heads
53 grep search for a pattern in specified files and revisions
54 help show help for a command, extension, or list of commands
54 heads show current repository heads
55 identify print information about the working copy
55 help show help for a command, extension, or list of commands
56 import import an ordered set of patches
56 identify print information about the working copy
57 incoming show new changesets found in source
57 import import an ordered set of patches
58 init create a new repository in the given directory
58 incoming show new changesets found in source
59 locate locate files matching specific patterns
59 init create a new repository in the given directory
60 log show revision history of entire repository or files
60 locate locate files matching specific patterns
61 manifest output the latest or given revision of the project manifest
61 log show revision history of entire repository or files
62 merge Merge working directory with another revision
62 manifest output the latest or given revision of the project manifest
63 outgoing show changesets not found in destination
63 merge Merge working directory with another revision
64 parents show the parents of the working dir or revision
64 outgoing show changesets not found in destination
65 paths show definition of symbolic path names
65 parents show the parents of the working dir or revision
66 pull pull changes from the specified source
66 paths show definition of symbolic path names
67 push push changes to the specified destination
67 pull pull changes from the specified source
68 recover roll back an interrupted transaction
68 push push changes to the specified destination
69 remove remove the specified files on the next commit
69 recover roll back an interrupted transaction
70 rename rename files; equivalent of copy + remove
70 remove remove the specified files on the next commit
71 revert revert files or dirs to their states as of some revision
71 rename rename files; equivalent of copy + remove
72 rollback roll back the last transaction in this repository
72 revert revert files or dirs to their states as of some revision
73 root print the root (top) of the current working dir
73 rollback roll back the last transaction in this repository
74 serve export the repository via HTTP
74 root print the root (top) of the current working dir
75 status show changed files in the working directory
75 serve export the repository via HTTP
76 tag add a tag for the current tip or a given revision
76 status show changed files in the working directory
77 tags list repository tags
77 tag add a tag for the current tip or a given revision
78 tip show the tip revision
78 tags list repository tags
79 unbundle apply a changegroup file
79 tip show the tip revision
80 update update or merge working directory
80 unbundle apply a changegroup file
81 verify verify the integrity of the repository
81 update update or merge working directory
82 version output version and copyright information
82 verify verify the integrity of the repository
83 add add the specified files on the next commit
83 version output version and copyright information
84 annotate show changeset information per file line
84 add add the specified files on the next commit
85 archive create unversioned archive of a repository revision
85 addremove add all new files, delete all missing files (DEPRECATED)
86 backout reverse effect of earlier changeset
86 annotate show changeset information per file line
87 bundle create a changegroup file
87 archive create unversioned archive of a repository revision
88 cat output the latest or given revisions of files
88 backout reverse effect of earlier changeset
89 clone make a copy of an existing repository
89 bundle create a changegroup file
90 commit commit the specified files or all outstanding changes
90 cat output the latest or given revisions of files
91 copy mark files as copied for the next commit
91 clone make a copy of an existing repository
92 diff diff repository (or selected files)
92 commit commit the specified files or all outstanding changes
93 export dump the header and diffs for one or more changesets
93 copy mark files as copied for the next commit
94 grep search for a pattern in specified files and revisions
94 diff diff repository (or selected files)
95 heads show current repository heads
95 export dump the header and diffs for one or more changesets
96 help show help for a command, extension, or list of commands
96 grep search for a pattern in specified files and revisions
97 identify print information about the working copy
97 heads show current repository heads
98 import import an ordered set of patches
98 help show help for a command, extension, or list of commands
99 incoming show new changesets found in source
99 identify print information about the working copy
100 init create a new repository in the given directory
100 import import an ordered set of patches
101 locate locate files matching specific patterns
101 incoming show new changesets found in source
102 log show revision history of entire repository or files
102 init create a new repository in the given directory
103 manifest output the latest or given revision of the project manifest
103 locate locate files matching specific patterns
104 merge Merge working directory with another revision
104 log show revision history of entire repository or files
105 outgoing show changesets not found in destination
105 manifest output the latest or given revision of the project manifest
106 parents show the parents of the working dir or revision
106 merge Merge working directory with another revision
107 paths show definition of symbolic path names
107 outgoing show changesets not found in destination
108 pull pull changes from the specified source
108 parents show the parents of the working dir or revision
109 push push changes to the specified destination
109 paths show definition of symbolic path names
110 recover roll back an interrupted transaction
110 pull pull changes from the specified source
111 remove remove the specified files on the next commit
111 push push changes to the specified destination
112 rename rename files; equivalent of copy + remove
112 recover roll back an interrupted transaction
113 revert revert files or dirs to their states as of some revision
113 remove remove the specified files on the next commit
114 rollback roll back the last transaction in this repository
114 rename rename files; equivalent of copy + remove
115 root print the root (top) of the current working dir
115 revert revert files or dirs to their states as of some revision
116 serve export the repository via HTTP
116 rollback roll back the last transaction in this repository
117 status show changed files in the working directory
117 root print the root (top) of the current working dir
118 tag add a tag for the current tip or a given revision
118 serve export the repository via HTTP
119 tags list repository tags
119 status show changed files in the working directory
120 tip show the tip revision
120 tag add a tag for the current tip or a given revision
121 unbundle apply a changegroup file
121 tags list repository tags
122 update update or merge working directory
122 tip show the tip revision
123 verify verify the integrity of the repository
123 unbundle apply a changegroup file
124 version output version and copyright information
124 update update or merge working directory
125 verify verify the integrity of the repository
126 version output version and copyright information
125 hg add [OPTION]... [FILE]...
127 hg add [OPTION]... [FILE]...
126
128
127 add the specified files on the next commit
129 add the specified files on the next commit
128
130
129 Schedule files to be version controlled and added to the repository.
131 Schedule files to be version controlled and added to the repository.
130
132
131 The files will be added to the repository at the next commit.
133 The files will be added to the repository at the next commit.
132
134
133 If no names are given, add all files in the repository.
135 If no names are given, add all files in the repository.
134
136
135 options:
137 options:
136
138
137 -I --include include names matching the given patterns
139 -I --include include names matching the given patterns
138 -X --exclude exclude names matching the given patterns
140 -X --exclude exclude names matching the given patterns
139 -n --dry-run do not perform actions, just print output
141 -n --dry-run do not perform actions, just print output
140 hg add: option --skjdfks not recognized
142 hg add: option --skjdfks not recognized
141 hg add [OPTION]... [FILE]...
143 hg add [OPTION]... [FILE]...
142
144
143 add the specified files on the next commit
145 add the specified files on the next commit
144
146
145 Schedule files to be version controlled and added to the repository.
147 Schedule files to be version controlled and added to the repository.
146
148
147 The files will be added to the repository at the next commit.
149 The files will be added to the repository at the next commit.
148
150
149 If no names are given, add all files in the repository.
151 If no names are given, add all files in the repository.
150
152
151 options:
153 options:
152
154
153 -I --include include names matching the given patterns
155 -I --include include names matching the given patterns
154 -X --exclude exclude names matching the given patterns
156 -X --exclude exclude names matching the given patterns
155 -n --dry-run do not perform actions, just print output
157 -n --dry-run do not perform actions, just print output
156 hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...
158 hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...
157
159
158 diff repository (or selected files)
160 diff repository (or selected files)
159
161
160 Show differences between revisions for the specified files.
162 Show differences between revisions for the specified files.
161
163
162 Differences between files are shown using the unified diff format.
164 Differences between files are shown using the unified diff format.
163
165
164 When two revision arguments are given, then changes are shown
166 When two revision arguments are given, then changes are shown
165 between those revisions. If only one revision is specified then
167 between those revisions. If only one revision is specified then
166 that revision is compared to the working directory, and, when no
168 that revision is compared to the working directory, and, when no
167 revisions are specified, the working directory files are compared
169 revisions are specified, the working directory files are compared
168 to its parent.
170 to its parent.
169
171
170 Without the -a option, diff will avoid generating diffs of files
172 Without the -a option, diff will avoid generating diffs of files
171 it detects as binary. With -a, diff will generate a diff anyway,
173 it detects as binary. With -a, diff will generate a diff anyway,
172 probably with undesirable results.
174 probably with undesirable results.
173
175
174 options:
176 options:
175
177
176 -r --rev revision
178 -r --rev revision
177 -a --text treat all files as text
179 -a --text treat all files as text
178 -p --show-function show which function each change is in
180 -p --show-function show which function each change is in
179 -w --ignore-all-space ignore white space when comparing lines
181 -w --ignore-all-space ignore white space when comparing lines
180 -b --ignore-space-change ignore changes in the amount of white space
182 -b --ignore-space-change ignore changes in the amount of white space
181 -B --ignore-blank-lines ignore changes whose lines are all blank
183 -B --ignore-blank-lines ignore changes whose lines are all blank
182 -I --include include names matching the given patterns
184 -I --include include names matching the given patterns
183 -X --exclude exclude names matching the given patterns
185 -X --exclude exclude names matching the given patterns
184 hg status [OPTION]... [FILE]...
186 hg status [OPTION]... [FILE]...
185
187
186 show changed files in the working directory
188 show changed files in the working directory
187
189
188 Show changed files in the repository. If names are
190 Show changed files in the repository. If names are
189 given, only files that match are shown.
191 given, only files that match are shown.
190
192
191 The codes used to show the status of files are:
193 The codes used to show the status of files are:
192 M = modified
194 M = modified
193 A = added
195 A = added
194 R = removed
196 R = removed
195 ! = deleted, but still tracked
197 ! = deleted, but still tracked
196 ? = not tracked
198 ? = not tracked
197 I = ignored (not shown by default)
199 I = ignored (not shown by default)
198 = the previous added file was copied from here
200 = the previous added file was copied from here
199
201
200 aliases: st
202 aliases: st
201
203
202 options:
204 options:
203
205
204 -m --modified show only modified files
206 -m --modified show only modified files
205 -a --added show only added files
207 -a --added show only added files
206 -r --removed show only removed files
208 -r --removed show only removed files
207 -d --deleted show only deleted (but tracked) files
209 -d --deleted show only deleted (but tracked) files
208 -u --unknown show only unknown (not tracked) files
210 -u --unknown show only unknown (not tracked) files
209 -i --ignored show ignored files
211 -i --ignored show ignored files
210 -n --no-status hide status prefix
212 -n --no-status hide status prefix
211 -C --copies show source of copied files
213 -C --copies show source of copied files
212 -0 --print0 end filenames with NUL, for use with xargs
214 -0 --print0 end filenames with NUL, for use with xargs
213 -I --include include names matching the given patterns
215 -I --include include names matching the given patterns
214 -X --exclude exclude names matching the given patterns
216 -X --exclude exclude names matching the given patterns
215 hg status [OPTION]... [FILE]...
217 hg status [OPTION]... [FILE]...
216
218
217 show changed files in the working directory
219 show changed files in the working directory
218 hg: unknown command 'foo'
220 hg: unknown command 'foo'
219 Mercurial Distributed SCM
221 Mercurial Distributed SCM
220
222
221 basic commands (use "hg help" for the full list or option "-v" for details):
223 basic commands (use "hg help" for the full list or option "-v" for details):
222
224
223 add add the specified files on the next commit
225 add add the specified files on the next commit
224 annotate show changeset information per file line
226 annotate show changeset information per file line
225 clone make a copy of an existing repository
227 clone make a copy of an existing repository
226 commit commit the specified files or all outstanding changes
228 commit commit the specified files or all outstanding changes
227 diff diff repository (or selected files)
229 diff diff repository (or selected files)
228 export dump the header and diffs for one or more changesets
230 export dump the header and diffs for one or more changesets
229 init create a new repository in the given directory
231 init create a new repository in the given directory
230 log show revision history of entire repository or files
232 log show revision history of entire repository or files
231 parents show the parents of the working dir or revision
233 parents show the parents of the working dir or revision
232 pull pull changes from the specified source
234 pull pull changes from the specified source
233 push push changes to the specified destination
235 push push changes to the specified destination
234 remove remove the specified files on the next commit
236 remove remove the specified files on the next commit
235 revert revert files or dirs to their states as of some revision
237 revert revert files or dirs to their states as of some revision
236 serve export the repository via HTTP
238 serve export the repository via HTTP
237 status show changed files in the working directory
239 status show changed files in the working directory
238 update update or merge working directory
240 update update or merge working directory
239 hg: unknown command 'skjdfks'
241 hg: unknown command 'skjdfks'
240 Mercurial Distributed SCM
242 Mercurial Distributed SCM
241
243
242 basic commands (use "hg help" for the full list or option "-v" for details):
244 basic commands (use "hg help" for the full list or option "-v" for details):
243
245
244 add add the specified files on the next commit
246 add add the specified files on the next commit
245 annotate show changeset information per file line
247 annotate show changeset information per file line
246 clone make a copy of an existing repository
248 clone make a copy of an existing repository
247 commit commit the specified files or all outstanding changes
249 commit commit the specified files or all outstanding changes
248 diff diff repository (or selected files)
250 diff diff repository (or selected files)
249 export dump the header and diffs for one or more changesets
251 export dump the header and diffs for one or more changesets
250 init create a new repository in the given directory
252 init create a new repository in the given directory
251 log show revision history of entire repository or files
253 log show revision history of entire repository or files
252 parents show the parents of the working dir or revision
254 parents show the parents of the working dir or revision
253 pull pull changes from the specified source
255 pull pull changes from the specified source
254 push push changes to the specified destination
256 push push changes to the specified destination
255 remove remove the specified files on the next commit
257 remove remove the specified files on the next commit
256 revert revert files or dirs to their states as of some revision
258 revert revert files or dirs to their states as of some revision
257 serve export the repository via HTTP
259 serve export the repository via HTTP
258 status show changed files in the working directory
260 status show changed files in the working directory
259 update update or merge working directory
261 update update or merge working directory
@@ -1,24 +1,23 b''
1 (the addremove command is deprecated; use add and remove --after instead)
2 adding foo
1 adding foo
3 checking changesets
2 checking changesets
4 checking manifests
3 checking manifests
5 crosschecking files in changesets and manifests
4 crosschecking files in changesets and manifests
6 checking files
5 checking files
7 1 files, 1 changesets, 1 total revisions
6 1 files, 1 changesets, 1 total revisions
8 requesting all changes
7 requesting all changes
9 adding changesets
8 adding changesets
10 adding manifests
9 adding manifests
11 adding file changes
10 adding file changes
12 added 1 changesets with 1 changes to 1 files
11 added 1 changesets with 1 changes to 1 files
13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 checking changesets
13 checking changesets
15 checking manifests
14 checking manifests
16 crosschecking files in changesets and manifests
15 crosschecking files in changesets and manifests
17 checking files
16 checking files
18 1 files, 1 changesets, 1 total revisions
17 1 files, 1 changesets, 1 total revisions
19 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
18 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 foo
19 foo
21 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 foo
20 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 foo
22 pulling from http://localhost:20059/
21 pulling from http://localhost:20059/
23 searching for changes
22 searching for changes
24 no changes found
23 no changes found
@@ -1,25 +1,24 b''
1 (the addremove command is deprecated; use add and remove --after instead)
2 adding foo
1 adding foo
3 checking changesets
2 checking changesets
4 checking manifests
3 checking manifests
5 crosschecking files in changesets and manifests
4 crosschecking files in changesets and manifests
6 checking files
5 checking files
7 1 files, 1 changesets, 1 total revisions
6 1 files, 1 changesets, 1 total revisions
8 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
7 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
9 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
8 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
10 pulling from ../branch
9 pulling from ../branch
11 searching for changes
10 searching for changes
12 adding changesets
11 adding changesets
13 adding manifests
12 adding manifests
14 adding file changes
13 adding file changes
15 added 1 changesets with 1 changes to 1 files
14 added 1 changesets with 1 changes to 1 files
16 (run 'hg update' to get a working copy)
15 (run 'hg update' to get a working copy)
17 checking changesets
16 checking changesets
18 checking manifests
17 checking manifests
19 crosschecking files in changesets and manifests
18 crosschecking files in changesets and manifests
20 checking files
19 checking files
21 1 files, 2 changesets, 2 total revisions
20 1 files, 2 changesets, 2 total revisions
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 foo
22 foo
24 bar
23 bar
25 6f4310b00b9a147241b071a60c28a650827fb03d 644 foo
24 6f4310b00b9a147241b071a60c28a650827fb03d 644 foo
@@ -1,17 +1,15 b''
1 (the addremove command is deprecated; use add and remove --after instead)
2 adding foo
1 adding foo
3 (the addremove command is deprecated; use add and remove --after instead)
4 adding bomb
2 adding bomb
5 adding a.c
3 adding a.c
6 adding dir/a.o
4 adding dir/a.o
7 adding dir/b.o
5 adding dir/b.o
8 ! a.c
6 ! a.c
9 ! dir/a.o
7 ! dir/a.o
10 ! dir/b.o
8 ! dir/b.o
11 ? .hgignore
9 ? .hgignore
12 a.c: unsupported file type (type is fifo)
10 a.c: unsupported file type (type is fifo)
13 ! a.c
11 ! a.c
14 # test absolute path through symlink outside repo
12 # test absolute path through symlink outside repo
15 A f
13 A f
16 # try symlink outside repo to file inside
14 # try symlink outside repo to file inside
17 abort: ../z not under root
15 abort: ../z not under root
@@ -1,152 +1,149 b''
1 (the addremove command is deprecated; use add and remove --after instead)
2 adding a
1 adding a
3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
5 diff -r 33aaa84a386b a
4 diff -r 33aaa84a386b a
6 --- a/a
5 --- a/a
7 +++ b/a
6 +++ b/a
8 @@ -1,1 +1,1 @@ a
7 @@ -1,1 +1,1 @@ a
9 -a
8 -a
10 +abc
9 +abc
11 (the addremove command is deprecated; use add and remove --after instead)
12 adding b
10 adding b
13 M a
11 M a
14 changeset: 0:33aaa84a386b
12 changeset: 0:33aaa84a386b
15 user: test
13 user: test
16 date: Mon Jan 12 13:46:40 1970 +0000
14 date: Mon Jan 12 13:46:40 1970 +0000
17 summary: 1
15 summary: 1
18
16
19 resolving manifests
17 resolving manifests
20 force None allow None moddirstate True linear True
18 force None allow None moddirstate True linear True
21 ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e
19 ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e
22 a versions differ, resolve
20 a versions differ, resolve
23 remote created b
21 remote created b
24 getting b
22 getting b
25 merging a
23 merging a
26 resolving a
24 resolving a
27 file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
25 file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
28 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
26 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
29 changeset: 1:802f095af299
27 changeset: 1:802f095af299
30 tag: tip
28 tag: tip
31 user: test
29 user: test
32 date: Mon Jan 12 13:46:40 1970 +0000
30 date: Mon Jan 12 13:46:40 1970 +0000
33 summary: 2
31 summary: 2
34
32
35 resolving manifests
33 resolving manifests
36 force None allow None moddirstate True linear True
34 force None allow None moddirstate True linear True
37 ancestor a0c8bcbbb45c local 1165e8bd193e remote a0c8bcbbb45c
35 ancestor a0c8bcbbb45c local 1165e8bd193e remote a0c8bcbbb45c
38 remote deleted b
36 remote deleted b
39 removing b
37 removing b
40 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
38 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
41 changeset: 0:33aaa84a386b
39 changeset: 0:33aaa84a386b
42 user: test
40 user: test
43 date: Mon Jan 12 13:46:40 1970 +0000
41 date: Mon Jan 12 13:46:40 1970 +0000
44 summary: 1
42 summary: 1
45
43
46 abort: there is nothing to merge, just use 'hg update' or look at 'hg heads'
44 abort: there is nothing to merge, just use 'hg update' or look at 'hg heads'
47 failed
45 failed
48 changeset: 0:33aaa84a386b
46 changeset: 0:33aaa84a386b
49 user: test
47 user: test
50 date: Mon Jan 12 13:46:40 1970 +0000
48 date: Mon Jan 12 13:46:40 1970 +0000
51 summary: 1
49 summary: 1
52
50
53 resolving manifests
51 resolving manifests
54 force None allow None moddirstate True linear True
52 force None allow None moddirstate True linear True
55 ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e
53 ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e
56 a versions differ, resolve
54 a versions differ, resolve
57 remote created b
55 remote created b
58 getting b
56 getting b
59 merging a
57 merging a
60 resolving a
58 resolving a
61 file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
59 file a: my b789fdd96dc2 other d730145abbf9 ancestor b789fdd96dc2
62 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
60 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
63 changeset: 1:802f095af299
61 changeset: 1:802f095af299
64 tag: tip
62 tag: tip
65 user: test
63 user: test
66 date: Mon Jan 12 13:46:40 1970 +0000
64 date: Mon Jan 12 13:46:40 1970 +0000
67 summary: 2
65 summary: 2
68
66
69 changeset: 1:802f095af299cde27a85b2f056aef3829870956c
67 changeset: 1:802f095af299cde27a85b2f056aef3829870956c
70 tag: tip
68 tag: tip
71 user: test
69 user: test
72 date: Mon Jan 12 13:46:40 1970 +0000
70 date: Mon Jan 12 13:46:40 1970 +0000
73 files: a b
71 files: a b
74 description:
72 description:
75 2
73 2
76
74
77
75
78 changeset: 0:33aaa84a386bd609094aeb21a97c09436c482ef1
76 changeset: 0:33aaa84a386bd609094aeb21a97c09436c482ef1
79 user: test
77 user: test
80 date: Mon Jan 12 13:46:40 1970 +0000
78 date: Mon Jan 12 13:46:40 1970 +0000
81 files: a
79 files: a
82 description:
80 description:
83 1
81 1
84
82
85
83
86 diff -r 802f095af299 a
84 diff -r 802f095af299 a
87 --- a/a
85 --- a/a
88 +++ b/a
86 +++ b/a
89 @@ -1,1 +1,1 @@ a2
87 @@ -1,1 +1,1 @@ a2
90 -a2
88 -a2
91 +abc
89 +abc
92 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
90 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
93 (the addremove command is deprecated; use add and remove --after instead)
94 adding b
91 adding b
95 M a
92 M a
96 changeset: 1:802f095af299
93 changeset: 1:802f095af299
97 user: test
94 user: test
98 date: Mon Jan 12 13:46:40 1970 +0000
95 date: Mon Jan 12 13:46:40 1970 +0000
99 summary: 2
96 summary: 2
100
97
101 resolving manifests
98 resolving manifests
102 force None allow None moddirstate True linear False
99 force None allow None moddirstate True linear False
103 ancestor a0c8bcbbb45c local 1165e8bd193e remote 4096f2872392
100 ancestor a0c8bcbbb45c local 1165e8bd193e remote 4096f2872392
104 a versions differ, resolve
101 a versions differ, resolve
105 b versions differ, resolve
102 b versions differ, resolve
106 this update spans a branch affecting the following files:
103 this update spans a branch affecting the following files:
107 a (resolve)
104 a (resolve)
108 b (resolve)
105 b (resolve)
109 aborting update spanning branches!
106 aborting update spanning branches!
110 (use 'hg merge' to merge across branches or 'hg update -C' to lose changes)
107 (use 'hg merge' to merge across branches or 'hg update -C' to lose changes)
111 failed
108 failed
112 abort: outstanding uncommitted changes
109 abort: outstanding uncommitted changes
113 failed
110 failed
114 resolving manifests
111 resolving manifests
115 force False allow True moddirstate True linear False
112 force False allow True moddirstate True linear False
116 ancestor a0c8bcbbb45c local 1165e8bd193e remote 4096f2872392
113 ancestor a0c8bcbbb45c local 1165e8bd193e remote 4096f2872392
117 a versions differ, resolve
114 a versions differ, resolve
118 b versions differ, resolve
115 b versions differ, resolve
119 merging a
116 merging a
120 resolving a
117 resolving a
121 file a: my d730145abbf9 other 13e0d5f949fa ancestor b789fdd96dc2
118 file a: my d730145abbf9 other 13e0d5f949fa ancestor b789fdd96dc2
122 merging b
119 merging b
123 resolving b
120 resolving b
124 file b: my 1e88685f5dde other 61de8c7723ca ancestor 000000000000
121 file b: my 1e88685f5dde other 61de8c7723ca ancestor 000000000000
125 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
122 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
126 (branch merge, don't forget to commit)
123 (branch merge, don't forget to commit)
127 changeset: 1:802f095af299
124 changeset: 1:802f095af299
128 user: test
125 user: test
129 date: Mon Jan 12 13:46:40 1970 +0000
126 date: Mon Jan 12 13:46:40 1970 +0000
130 summary: 2
127 summary: 2
131
128
132 changeset: 2:030602aee63d
129 changeset: 2:030602aee63d
133 tag: tip
130 tag: tip
134 parent: 0:33aaa84a386b
131 parent: 0:33aaa84a386b
135 user: test
132 user: test
136 date: Mon Jan 12 13:46:40 1970 +0000
133 date: Mon Jan 12 13:46:40 1970 +0000
137 summary: 3
134 summary: 3
138
135
139 diff -r 802f095af299 a
136 diff -r 802f095af299 a
140 --- a/a
137 --- a/a
141 +++ b/a
138 +++ b/a
142 @@ -1,1 +1,1 @@ a2
139 @@ -1,1 +1,1 @@ a2
143 -a2
140 -a2
144 +abc
141 +abc
145 adding a
142 adding a
146 pulling from ../a
143 pulling from ../a
147 requesting all changes
144 requesting all changes
148 adding changesets
145 adding changesets
149 adding manifests
146 adding manifests
150 adding file changes
147 adding file changes
151 added 1 changesets with 1 changes to 1 files
148 added 1 changesets with 1 changes to 1 files
152 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1,98 +1,97 b''
1 (the addremove command is deprecated; use add and remove --after instead)
2 adding beans/black
1 adding beans/black
3 adding beans/borlotti
2 adding beans/borlotti
4 adding beans/kidney
3 adding beans/kidney
5 adding beans/navy
4 adding beans/navy
6 adding beans/pinto
5 adding beans/pinto
7 adding beans/turtle
6 adding beans/turtle
8 adding fennel
7 adding fennel
9 adding fenugreek
8 adding fenugreek
10 adding fiddlehead
9 adding fiddlehead
11 adding glob:glob
10 adding glob:glob
12 adding mammals/Procyonidae/cacomistle
11 adding mammals/Procyonidae/cacomistle
13 adding mammals/Procyonidae/coatimundi
12 adding mammals/Procyonidae/coatimundi
14 adding mammals/Procyonidae/raccoon
13 adding mammals/Procyonidae/raccoon
15 adding mammals/skunk
14 adding mammals/skunk
16 f beans/black beans/black
15 f beans/black beans/black
17 f beans/borlotti beans/borlotti
16 f beans/borlotti beans/borlotti
18 f beans/kidney beans/kidney
17 f beans/kidney beans/kidney
19 f beans/navy beans/navy
18 f beans/navy beans/navy
20 f beans/pinto beans/pinto
19 f beans/pinto beans/pinto
21 f beans/turtle beans/turtle
20 f beans/turtle beans/turtle
22 f fennel fennel
21 f fennel fennel
23 f fenugreek fenugreek
22 f fenugreek fenugreek
24 f fiddlehead fiddlehead
23 f fiddlehead fiddlehead
25 f glob:glob glob:glob
24 f glob:glob glob:glob
26 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
25 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
27 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
26 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
28 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
27 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
29 f mammals/skunk mammals/skunk
28 f mammals/skunk mammals/skunk
30 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
29 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
31 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
30 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
32 f mammals/Procyonidae/raccoon Procyonidae/raccoon
31 f mammals/Procyonidae/raccoon Procyonidae/raccoon
33 f mammals/skunk skunk
32 f mammals/skunk skunk
34 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
33 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
35 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
34 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
36 f mammals/Procyonidae/raccoon Procyonidae/raccoon
35 f mammals/Procyonidae/raccoon Procyonidae/raccoon
37 f mammals/Procyonidae/cacomistle cacomistle
36 f mammals/Procyonidae/cacomistle cacomistle
38 f mammals/Procyonidae/coatimundi coatimundi
37 f mammals/Procyonidae/coatimundi coatimundi
39 f mammals/Procyonidae/raccoon raccoon
38 f mammals/Procyonidae/raccoon raccoon
40 f mammals/Procyonidae/cacomistle cacomistle
39 f mammals/Procyonidae/cacomistle cacomistle
41 f mammals/Procyonidae/coatimundi coatimundi
40 f mammals/Procyonidae/coatimundi coatimundi
42 f mammals/Procyonidae/raccoon raccoon
41 f mammals/Procyonidae/raccoon raccoon
43 f mammals/skunk ../skunk
42 f mammals/skunk ../skunk
44 f beans/black ../beans/black
43 f beans/black ../beans/black
45 f beans/borlotti ../beans/borlotti
44 f beans/borlotti ../beans/borlotti
46 f beans/kidney ../beans/kidney
45 f beans/kidney ../beans/kidney
47 f beans/navy ../beans/navy
46 f beans/navy ../beans/navy
48 f beans/pinto ../beans/pinto
47 f beans/pinto ../beans/pinto
49 f beans/turtle ../beans/turtle
48 f beans/turtle ../beans/turtle
50 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
49 f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
51 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
50 f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
52 f mammals/Procyonidae/raccoon Procyonidae/raccoon
51 f mammals/Procyonidae/raccoon Procyonidae/raccoon
53 f mammals/skunk skunk
52 f mammals/skunk skunk
54 .hg: No such file or directory
53 .hg: No such file or directory
55 abort: path contains illegal component: .hg
54 abort: path contains illegal component: .hg
56
55
57 f beans/black beans/black
56 f beans/black beans/black
58 f beans/borlotti beans/borlotti
57 f beans/borlotti beans/borlotti
59 f beans/kidney beans/kidney
58 f beans/kidney beans/kidney
60 f beans/navy beans/navy
59 f beans/navy beans/navy
61 f beans/pinto beans/pinto
60 f beans/pinto beans/pinto
62 f beans/turtle beans/turtle
61 f beans/turtle beans/turtle
63 f beans/black beans/black
62 f beans/black beans/black
64 f beans/borlotti beans/borlotti
63 f beans/borlotti beans/borlotti
65 f mammals/skunk mammals/skunk
64 f mammals/skunk mammals/skunk
66 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
65 f mammals/Procyonidae/cacomistle mammals/Procyonidae/cacomistle
67 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
66 f mammals/Procyonidae/coatimundi mammals/Procyonidae/coatimundi
68 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
67 f mammals/Procyonidae/raccoon mammals/Procyonidae/raccoon
69 f mammals/skunk mammals/skunk
68 f mammals/skunk mammals/skunk
70 abort: .. not under root
69 abort: .. not under root
71 abort: beans/../.. not under root
70 abort: beans/../.. not under root
72 abort: path contains illegal component: .hg
71 abort: path contains illegal component: .hg
73
72
74 abort: path contains illegal component: .hg
73 abort: path contains illegal component: .hg
75
74
76 abort: path contains illegal component: .hg/data
75 abort: path contains illegal component: .hg/data
77
76
78 beans/.hg: No such file or directory
77 beans/.hg: No such file or directory
79 f fennel fennel
78 f fennel fennel
80 f fenugreek fenugreek
79 f fenugreek fenugreek
81 f fiddlehead fiddlehead
80 f fiddlehead fiddlehead
82 f glob:glob glob:glob
81 f glob:glob glob:glob
83 f beans/black beans/black
82 f beans/black beans/black
84 f fenugreek fenugreek
83 f fenugreek fenugreek
85 f glob:glob glob:glob
84 f glob:glob glob:glob
86 f mammals/skunk mammals/skunk
85 f mammals/skunk mammals/skunk
87 f beans/black beans/black
86 f beans/black beans/black
88 f beans/black beans/black
87 f beans/black beans/black
89 f beans/borlotti beans/borlotti
88 f beans/borlotti beans/borlotti
90 f beans/kidney beans/kidney
89 f beans/kidney beans/kidney
91 f beans/navy beans/navy
90 f beans/navy beans/navy
92 f beans/pinto beans/pinto
91 f beans/pinto beans/pinto
93 f beans/turtle beans/turtle
92 f beans/turtle beans/turtle
94 NOEXIST: No such file or directory
93 NOEXIST: No such file or directory
95 fifo: unsupported file type (type is fifo)
94 fifo: unsupported file type (type is fifo)
96 m fenugreek fenugreek exact
95 m fenugreek fenugreek exact
97 m fenugreek fenugreek exact
96 m fenugreek fenugreek exact
98 f new new exact
97 f new new exact
General Comments 0
You need to be logged in to leave comments. Login now