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