##// END OF EJS Templates
annotate: add option to annotate working-directory files...
Yuya Nishihara -
r24421:77881cad default
parent child Browse files
Show More
@@ -1,6367 +1,6397 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from node import hex, bin, nullid, nullrev, short
8 from node import hex, bin, nullid, nullrev, short
9 from lock import release
9 from lock import release
10 from i18n import _
10 from i18n import _
11 import os, re, difflib, time, tempfile, errno, shlex
11 import os, re, difflib, time, tempfile, errno, shlex
12 import sys, socket
12 import sys, socket
13 import hg, scmutil, util, revlog, copies, error, bookmarks
13 import hg, scmutil, util, revlog, copies, error, bookmarks
14 import patch, help, encoding, templatekw, discovery
14 import patch, help, encoding, templatekw, discovery
15 import archival, changegroup, cmdutil, hbisect
15 import archival, changegroup, cmdutil, hbisect
16 import sshserver, hgweb, commandserver
16 import sshserver, hgweb, commandserver
17 import extensions
17 import extensions
18 from hgweb import server as hgweb_server
18 from hgweb import server as hgweb_server
19 import merge as mergemod
19 import merge as mergemod
20 import minirst, revset, fileset
20 import minirst, revset, fileset
21 import dagparser, context, simplemerge, graphmod, copies
21 import dagparser, context, simplemerge, graphmod, copies
22 import random
22 import random
23 import setdiscovery, treediscovery, dagutil, pvec, localrepo
23 import setdiscovery, treediscovery, dagutil, pvec, localrepo
24 import phases, obsolete, exchange, bundle2
24 import phases, obsolete, exchange, bundle2
25 import ui as uimod
25 import ui as uimod
26
26
27 table = {}
27 table = {}
28
28
29 command = cmdutil.command(table)
29 command = cmdutil.command(table)
30
30
31 # Space delimited list of commands that don't require local repositories.
31 # Space delimited list of commands that don't require local repositories.
32 # This should be populated by passing norepo=True into the @command decorator.
32 # This should be populated by passing norepo=True into the @command decorator.
33 norepo = ''
33 norepo = ''
34 # Space delimited list of commands that optionally require local repositories.
34 # Space delimited list of commands that optionally require local repositories.
35 # This should be populated by passing optionalrepo=True into the @command
35 # This should be populated by passing optionalrepo=True into the @command
36 # decorator.
36 # decorator.
37 optionalrepo = ''
37 optionalrepo = ''
38 # Space delimited list of commands that will examine arguments looking for
38 # Space delimited list of commands that will examine arguments looking for
39 # a repository. This should be populated by passing inferrepo=True into the
39 # a repository. This should be populated by passing inferrepo=True into the
40 # @command decorator.
40 # @command decorator.
41 inferrepo = ''
41 inferrepo = ''
42
42
43 # common command options
43 # common command options
44
44
45 globalopts = [
45 globalopts = [
46 ('R', 'repository', '',
46 ('R', 'repository', '',
47 _('repository root directory or name of overlay bundle file'),
47 _('repository root directory or name of overlay bundle file'),
48 _('REPO')),
48 _('REPO')),
49 ('', 'cwd', '',
49 ('', 'cwd', '',
50 _('change working directory'), _('DIR')),
50 _('change working directory'), _('DIR')),
51 ('y', 'noninteractive', None,
51 ('y', 'noninteractive', None,
52 _('do not prompt, automatically pick the first choice for all prompts')),
52 _('do not prompt, automatically pick the first choice for all prompts')),
53 ('q', 'quiet', None, _('suppress output')),
53 ('q', 'quiet', None, _('suppress output')),
54 ('v', 'verbose', None, _('enable additional output')),
54 ('v', 'verbose', None, _('enable additional output')),
55 ('', 'config', [],
55 ('', 'config', [],
56 _('set/override config option (use \'section.name=value\')'),
56 _('set/override config option (use \'section.name=value\')'),
57 _('CONFIG')),
57 _('CONFIG')),
58 ('', 'debug', None, _('enable debugging output')),
58 ('', 'debug', None, _('enable debugging output')),
59 ('', 'debugger', None, _('start debugger')),
59 ('', 'debugger', None, _('start debugger')),
60 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
60 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
61 _('ENCODE')),
61 _('ENCODE')),
62 ('', 'encodingmode', encoding.encodingmode,
62 ('', 'encodingmode', encoding.encodingmode,
63 _('set the charset encoding mode'), _('MODE')),
63 _('set the charset encoding mode'), _('MODE')),
64 ('', 'traceback', None, _('always print a traceback on exception')),
64 ('', 'traceback', None, _('always print a traceback on exception')),
65 ('', 'time', None, _('time how long the command takes')),
65 ('', 'time', None, _('time how long the command takes')),
66 ('', 'profile', None, _('print command execution profile')),
66 ('', 'profile', None, _('print command execution profile')),
67 ('', 'version', None, _('output version information and exit')),
67 ('', 'version', None, _('output version information and exit')),
68 ('h', 'help', None, _('display help and exit')),
68 ('h', 'help', None, _('display help and exit')),
69 ('', 'hidden', False, _('consider hidden changesets')),
69 ('', 'hidden', False, _('consider hidden changesets')),
70 ]
70 ]
71
71
72 dryrunopts = [('n', 'dry-run', None,
72 dryrunopts = [('n', 'dry-run', None,
73 _('do not perform actions, just print output'))]
73 _('do not perform actions, just print output'))]
74
74
75 remoteopts = [
75 remoteopts = [
76 ('e', 'ssh', '',
76 ('e', 'ssh', '',
77 _('specify ssh command to use'), _('CMD')),
77 _('specify ssh command to use'), _('CMD')),
78 ('', 'remotecmd', '',
78 ('', 'remotecmd', '',
79 _('specify hg command to run on the remote side'), _('CMD')),
79 _('specify hg command to run on the remote side'), _('CMD')),
80 ('', 'insecure', None,
80 ('', 'insecure', None,
81 _('do not verify server certificate (ignoring web.cacerts config)')),
81 _('do not verify server certificate (ignoring web.cacerts config)')),
82 ]
82 ]
83
83
84 walkopts = [
84 walkopts = [
85 ('I', 'include', [],
85 ('I', 'include', [],
86 _('include names matching the given patterns'), _('PATTERN')),
86 _('include names matching the given patterns'), _('PATTERN')),
87 ('X', 'exclude', [],
87 ('X', 'exclude', [],
88 _('exclude names matching the given patterns'), _('PATTERN')),
88 _('exclude names matching the given patterns'), _('PATTERN')),
89 ]
89 ]
90
90
91 commitopts = [
91 commitopts = [
92 ('m', 'message', '',
92 ('m', 'message', '',
93 _('use text as commit message'), _('TEXT')),
93 _('use text as commit message'), _('TEXT')),
94 ('l', 'logfile', '',
94 ('l', 'logfile', '',
95 _('read commit message from file'), _('FILE')),
95 _('read commit message from file'), _('FILE')),
96 ]
96 ]
97
97
98 commitopts2 = [
98 commitopts2 = [
99 ('d', 'date', '',
99 ('d', 'date', '',
100 _('record the specified date as commit date'), _('DATE')),
100 _('record the specified date as commit date'), _('DATE')),
101 ('u', 'user', '',
101 ('u', 'user', '',
102 _('record the specified user as committer'), _('USER')),
102 _('record the specified user as committer'), _('USER')),
103 ]
103 ]
104
104
105 # hidden for now
105 # hidden for now
106 formatteropts = [
106 formatteropts = [
107 ('T', 'template', '',
107 ('T', 'template', '',
108 _('display with template (DEPRECATED)'), _('TEMPLATE')),
108 _('display with template (DEPRECATED)'), _('TEMPLATE')),
109 ]
109 ]
110
110
111 templateopts = [
111 templateopts = [
112 ('', 'style', '',
112 ('', 'style', '',
113 _('display using template map file (DEPRECATED)'), _('STYLE')),
113 _('display using template map file (DEPRECATED)'), _('STYLE')),
114 ('T', 'template', '',
114 ('T', 'template', '',
115 _('display with template'), _('TEMPLATE')),
115 _('display with template'), _('TEMPLATE')),
116 ]
116 ]
117
117
118 logopts = [
118 logopts = [
119 ('p', 'patch', None, _('show patch')),
119 ('p', 'patch', None, _('show patch')),
120 ('g', 'git', None, _('use git extended diff format')),
120 ('g', 'git', None, _('use git extended diff format')),
121 ('l', 'limit', '',
121 ('l', 'limit', '',
122 _('limit number of changes displayed'), _('NUM')),
122 _('limit number of changes displayed'), _('NUM')),
123 ('M', 'no-merges', None, _('do not show merges')),
123 ('M', 'no-merges', None, _('do not show merges')),
124 ('', 'stat', None, _('output diffstat-style summary of changes')),
124 ('', 'stat', None, _('output diffstat-style summary of changes')),
125 ('G', 'graph', None, _("show the revision DAG")),
125 ('G', 'graph', None, _("show the revision DAG")),
126 ] + templateopts
126 ] + templateopts
127
127
128 diffopts = [
128 diffopts = [
129 ('a', 'text', None, _('treat all files as text')),
129 ('a', 'text', None, _('treat all files as text')),
130 ('g', 'git', None, _('use git extended diff format')),
130 ('g', 'git', None, _('use git extended diff format')),
131 ('', 'nodates', None, _('omit dates from diff headers'))
131 ('', 'nodates', None, _('omit dates from diff headers'))
132 ]
132 ]
133
133
134 diffwsopts = [
134 diffwsopts = [
135 ('w', 'ignore-all-space', None,
135 ('w', 'ignore-all-space', None,
136 _('ignore white space when comparing lines')),
136 _('ignore white space when comparing lines')),
137 ('b', 'ignore-space-change', None,
137 ('b', 'ignore-space-change', None,
138 _('ignore changes in the amount of white space')),
138 _('ignore changes in the amount of white space')),
139 ('B', 'ignore-blank-lines', None,
139 ('B', 'ignore-blank-lines', None,
140 _('ignore changes whose lines are all blank')),
140 _('ignore changes whose lines are all blank')),
141 ]
141 ]
142
142
143 diffopts2 = [
143 diffopts2 = [
144 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
144 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
145 ('p', 'show-function', None, _('show which function each change is in')),
145 ('p', 'show-function', None, _('show which function each change is in')),
146 ('', 'reverse', None, _('produce a diff that undoes the changes')),
146 ('', 'reverse', None, _('produce a diff that undoes the changes')),
147 ] + diffwsopts + [
147 ] + diffwsopts + [
148 ('U', 'unified', '',
148 ('U', 'unified', '',
149 _('number of lines of context to show'), _('NUM')),
149 _('number of lines of context to show'), _('NUM')),
150 ('', 'stat', None, _('output diffstat-style summary of changes')),
150 ('', 'stat', None, _('output diffstat-style summary of changes')),
151 ]
151 ]
152
152
153 mergetoolopts = [
153 mergetoolopts = [
154 ('t', 'tool', '', _('specify merge tool')),
154 ('t', 'tool', '', _('specify merge tool')),
155 ]
155 ]
156
156
157 similarityopts = [
157 similarityopts = [
158 ('s', 'similarity', '',
158 ('s', 'similarity', '',
159 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
159 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
160 ]
160 ]
161
161
162 subrepoopts = [
162 subrepoopts = [
163 ('S', 'subrepos', None,
163 ('S', 'subrepos', None,
164 _('recurse into subrepositories'))
164 _('recurse into subrepositories'))
165 ]
165 ]
166
166
167 # Commands start here, listed alphabetically
167 # Commands start here, listed alphabetically
168
168
169 @command('^add',
169 @command('^add',
170 walkopts + subrepoopts + dryrunopts,
170 walkopts + subrepoopts + dryrunopts,
171 _('[OPTION]... [FILE]...'),
171 _('[OPTION]... [FILE]...'),
172 inferrepo=True)
172 inferrepo=True)
173 def add(ui, repo, *pats, **opts):
173 def add(ui, repo, *pats, **opts):
174 """add the specified files on the next commit
174 """add the specified files on the next commit
175
175
176 Schedule files to be version controlled and added to the
176 Schedule files to be version controlled and added to the
177 repository.
177 repository.
178
178
179 The files will be added to the repository at the next commit. To
179 The files will be added to the repository at the next commit. To
180 undo an add before that, see :hg:`forget`.
180 undo an add before that, see :hg:`forget`.
181
181
182 If no names are given, add all files to the repository.
182 If no names are given, add all files to the repository.
183
183
184 .. container:: verbose
184 .. container:: verbose
185
185
186 An example showing how new (unknown) files are added
186 An example showing how new (unknown) files are added
187 automatically by :hg:`add`::
187 automatically by :hg:`add`::
188
188
189 $ ls
189 $ ls
190 foo.c
190 foo.c
191 $ hg status
191 $ hg status
192 ? foo.c
192 ? foo.c
193 $ hg add
193 $ hg add
194 adding foo.c
194 adding foo.c
195 $ hg status
195 $ hg status
196 A foo.c
196 A foo.c
197
197
198 Returns 0 if all files are successfully added.
198 Returns 0 if all files are successfully added.
199 """
199 """
200
200
201 m = scmutil.match(repo[None], pats, opts)
201 m = scmutil.match(repo[None], pats, opts)
202 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
202 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
203 return rejected and 1 or 0
203 return rejected and 1 or 0
204
204
205 @command('addremove',
205 @command('addremove',
206 similarityopts + subrepoopts + walkopts + dryrunopts,
206 similarityopts + subrepoopts + walkopts + dryrunopts,
207 _('[OPTION]... [FILE]...'),
207 _('[OPTION]... [FILE]...'),
208 inferrepo=True)
208 inferrepo=True)
209 def addremove(ui, repo, *pats, **opts):
209 def addremove(ui, repo, *pats, **opts):
210 """add all new files, delete all missing files
210 """add all new files, delete all missing files
211
211
212 Add all new files and remove all missing files from the
212 Add all new files and remove all missing files from the
213 repository.
213 repository.
214
214
215 New files are ignored if they match any of the patterns in
215 New files are ignored if they match any of the patterns in
216 ``.hgignore``. As with add, these changes take effect at the next
216 ``.hgignore``. As with add, these changes take effect at the next
217 commit.
217 commit.
218
218
219 Use the -s/--similarity option to detect renamed files. This
219 Use the -s/--similarity option to detect renamed files. This
220 option takes a percentage between 0 (disabled) and 100 (files must
220 option takes a percentage between 0 (disabled) and 100 (files must
221 be identical) as its parameter. With a parameter greater than 0,
221 be identical) as its parameter. With a parameter greater than 0,
222 this compares every removed file with every added file and records
222 this compares every removed file with every added file and records
223 those similar enough as renames. Detecting renamed files this way
223 those similar enough as renames. Detecting renamed files this way
224 can be expensive. After using this option, :hg:`status -C` can be
224 can be expensive. After using this option, :hg:`status -C` can be
225 used to check which files were identified as moved or renamed. If
225 used to check which files were identified as moved or renamed. If
226 not specified, -s/--similarity defaults to 100 and only renames of
226 not specified, -s/--similarity defaults to 100 and only renames of
227 identical files are detected.
227 identical files are detected.
228
228
229 Returns 0 if all files are successfully added.
229 Returns 0 if all files are successfully added.
230 """
230 """
231 try:
231 try:
232 sim = float(opts.get('similarity') or 100)
232 sim = float(opts.get('similarity') or 100)
233 except ValueError:
233 except ValueError:
234 raise util.Abort(_('similarity must be a number'))
234 raise util.Abort(_('similarity must be a number'))
235 if sim < 0 or sim > 100:
235 if sim < 0 or sim > 100:
236 raise util.Abort(_('similarity must be between 0 and 100'))
236 raise util.Abort(_('similarity must be between 0 and 100'))
237 matcher = scmutil.match(repo[None], pats, opts)
237 matcher = scmutil.match(repo[None], pats, opts)
238 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
238 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
239
239
240 @command('^annotate|blame',
240 @command('^annotate|blame',
241 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
241 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
242 ('', 'follow', None,
242 ('', 'follow', None,
243 _('follow copies/renames and list the filename (DEPRECATED)')),
243 _('follow copies/renames and list the filename (DEPRECATED)')),
244 ('', 'no-follow', None, _("don't follow copies and renames")),
244 ('', 'no-follow', None, _("don't follow copies and renames")),
245 ('a', 'text', None, _('treat all files as text')),
245 ('a', 'text', None, _('treat all files as text')),
246 ('u', 'user', None, _('list the author (long with -v)')),
246 ('u', 'user', None, _('list the author (long with -v)')),
247 ('f', 'file', None, _('list the filename')),
247 ('f', 'file', None, _('list the filename')),
248 ('d', 'date', None, _('list the date (short with -q)')),
248 ('d', 'date', None, _('list the date (short with -q)')),
249 ('n', 'number', None, _('list the revision number (default)')),
249 ('n', 'number', None, _('list the revision number (default)')),
250 ('c', 'changeset', None, _('list the changeset')),
250 ('c', 'changeset', None, _('list the changeset')),
251 ('l', 'line-number', None, _('show line number at the first appearance'))
251 ('l', 'line-number', None, _('show line number at the first appearance'))
252 ] + diffwsopts + walkopts + formatteropts,
252 ] + diffwsopts + walkopts + formatteropts,
253 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
253 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
254 inferrepo=True)
254 inferrepo=True)
255 def annotate(ui, repo, *pats, **opts):
255 def annotate(ui, repo, *pats, **opts):
256 """show changeset information by line for each file
256 """show changeset information by line for each file
257
257
258 List changes in files, showing the revision id responsible for
258 List changes in files, showing the revision id responsible for
259 each line
259 each line
260
260
261 This command is useful for discovering when a change was made and
261 This command is useful for discovering when a change was made and
262 by whom.
262 by whom.
263
263
264 Without the -a/--text option, annotate will avoid processing files
264 Without the -a/--text option, annotate will avoid processing files
265 it detects as binary. With -a, annotate will annotate the file
265 it detects as binary. With -a, annotate will annotate the file
266 anyway, although the results will probably be neither useful
266 anyway, although the results will probably be neither useful
267 nor desirable.
267 nor desirable.
268
268
269 By default, annotate files in the parent of the working directory.
270 Use -r "wdir()" to annotate the working directory files.
271
269 Returns 0 on success.
272 Returns 0 on success.
270 """
273 """
271 if not pats:
274 if not pats:
272 raise util.Abort(_('at least one filename or pattern is required'))
275 raise util.Abort(_('at least one filename or pattern is required'))
273
276
274 if opts.get('follow'):
277 if opts.get('follow'):
275 # --follow is deprecated and now just an alias for -f/--file
278 # --follow is deprecated and now just an alias for -f/--file
276 # to mimic the behavior of Mercurial before version 1.5
279 # to mimic the behavior of Mercurial before version 1.5
277 opts['file'] = True
280 opts['file'] = True
278
281
282 ctx = scmutil.revsingle(repo, opts.get('rev'))
283
279 fm = ui.formatter('annotate', opts)
284 fm = ui.formatter('annotate', opts)
280 if ui.quiet:
285 if ui.quiet:
281 datefunc = util.shortdate
286 datefunc = util.shortdate
282 else:
287 else:
283 datefunc = util.datestr
288 datefunc = util.datestr
284 hexfn = fm.hexfunc
289 if ctx.rev() is None:
290 def hexfn(node):
291 if node is None:
292 return None
293 else:
294 return fm.hexfunc(node)
295 if opts.get('changeset'):
296 # omit "+" suffix which is appended to node hex
297 def formatrev(rev):
298 if rev is None:
299 return '%d' % ctx.p1().rev()
300 else:
301 return '%d' % rev
302 else:
303 def formatrev(rev):
304 if rev is None:
305 return '%d+' % ctx.p1().rev()
306 else:
307 return '%d ' % rev
308 def formathex(hex):
309 if hex is None:
310 return '%s+' % fm.hexfunc(ctx.p1().node())
311 else:
312 return '%s ' % hex
313 else:
314 hexfn = fm.hexfunc
315 formatrev = formathex = str
285
316
286 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
317 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
287 ('number', ' ', lambda x: x[0].rev(), str),
318 ('number', ' ', lambda x: x[0].rev(), formatrev),
288 ('changeset', ' ', lambda x: hexfn(x[0].node()), str),
319 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
289 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
320 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
290 ('file', ' ', lambda x: x[0].path(), str),
321 ('file', ' ', lambda x: x[0].path(), str),
291 ('line_number', ':', lambda x: x[1], str),
322 ('line_number', ':', lambda x: x[1], str),
292 ]
323 ]
293 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
324 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
294
325
295 if (not opts.get('user') and not opts.get('changeset')
326 if (not opts.get('user') and not opts.get('changeset')
296 and not opts.get('date') and not opts.get('file')):
327 and not opts.get('date') and not opts.get('file')):
297 opts['number'] = True
328 opts['number'] = True
298
329
299 linenumber = opts.get('line_number') is not None
330 linenumber = opts.get('line_number') is not None
300 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
331 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
301 raise util.Abort(_('at least one of -n/-c is required for -l'))
332 raise util.Abort(_('at least one of -n/-c is required for -l'))
302
333
303 if fm:
334 if fm:
304 def makefunc(get, fmt):
335 def makefunc(get, fmt):
305 return get
336 return get
306 else:
337 else:
307 def makefunc(get, fmt):
338 def makefunc(get, fmt):
308 return lambda x: fmt(get(x))
339 return lambda x: fmt(get(x))
309 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
340 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
310 if opts.get(op)]
341 if opts.get(op)]
311 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
342 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
312 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
343 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
313 if opts.get(op))
344 if opts.get(op))
314
345
315 def bad(x, y):
346 def bad(x, y):
316 raise util.Abort("%s: %s" % (x, y))
347 raise util.Abort("%s: %s" % (x, y))
317
348
318 ctx = scmutil.revsingle(repo, opts.get('rev'))
319 m = scmutil.match(ctx, pats, opts)
349 m = scmutil.match(ctx, pats, opts)
320 m.bad = bad
350 m.bad = bad
321 follow = not opts.get('no_follow')
351 follow = not opts.get('no_follow')
322 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
352 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
323 whitespace=True)
353 whitespace=True)
324 for abs in ctx.walk(m):
354 for abs in ctx.walk(m):
325 fctx = ctx[abs]
355 fctx = ctx[abs]
326 if not opts.get('text') and util.binary(fctx.data()):
356 if not opts.get('text') and util.binary(fctx.data()):
327 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
357 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
328 continue
358 continue
329
359
330 lines = fctx.annotate(follow=follow, linenumber=linenumber,
360 lines = fctx.annotate(follow=follow, linenumber=linenumber,
331 diffopts=diffopts)
361 diffopts=diffopts)
332 formats = []
362 formats = []
333 pieces = []
363 pieces = []
334
364
335 for f, sep in funcmap:
365 for f, sep in funcmap:
336 l = [f(n) for n, dummy in lines]
366 l = [f(n) for n, dummy in lines]
337 if l:
367 if l:
338 if fm:
368 if fm:
339 formats.append(['%s' for x in l])
369 formats.append(['%s' for x in l])
340 else:
370 else:
341 sizes = [encoding.colwidth(x) for x in l]
371 sizes = [encoding.colwidth(x) for x in l]
342 ml = max(sizes)
372 ml = max(sizes)
343 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
373 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
344 pieces.append(l)
374 pieces.append(l)
345
375
346 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
376 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
347 fm.startitem()
377 fm.startitem()
348 fm.write(fields, "".join(f), *p)
378 fm.write(fields, "".join(f), *p)
349 fm.write('line', ": %s", l[1])
379 fm.write('line', ": %s", l[1])
350
380
351 if lines and not lines[-1][1].endswith('\n'):
381 if lines and not lines[-1][1].endswith('\n'):
352 fm.plain('\n')
382 fm.plain('\n')
353
383
354 fm.end()
384 fm.end()
355
385
356 @command('archive',
386 @command('archive',
357 [('', 'no-decode', None, _('do not pass files through decoders')),
387 [('', 'no-decode', None, _('do not pass files through decoders')),
358 ('p', 'prefix', '', _('directory prefix for files in archive'),
388 ('p', 'prefix', '', _('directory prefix for files in archive'),
359 _('PREFIX')),
389 _('PREFIX')),
360 ('r', 'rev', '', _('revision to distribute'), _('REV')),
390 ('r', 'rev', '', _('revision to distribute'), _('REV')),
361 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
391 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
362 ] + subrepoopts + walkopts,
392 ] + subrepoopts + walkopts,
363 _('[OPTION]... DEST'))
393 _('[OPTION]... DEST'))
364 def archive(ui, repo, dest, **opts):
394 def archive(ui, repo, dest, **opts):
365 '''create an unversioned archive of a repository revision
395 '''create an unversioned archive of a repository revision
366
396
367 By default, the revision used is the parent of the working
397 By default, the revision used is the parent of the working
368 directory; use -r/--rev to specify a different revision.
398 directory; use -r/--rev to specify a different revision.
369
399
370 The archive type is automatically detected based on file
400 The archive type is automatically detected based on file
371 extension (or override using -t/--type).
401 extension (or override using -t/--type).
372
402
373 .. container:: verbose
403 .. container:: verbose
374
404
375 Examples:
405 Examples:
376
406
377 - create a zip file containing the 1.0 release::
407 - create a zip file containing the 1.0 release::
378
408
379 hg archive -r 1.0 project-1.0.zip
409 hg archive -r 1.0 project-1.0.zip
380
410
381 - create a tarball excluding .hg files::
411 - create a tarball excluding .hg files::
382
412
383 hg archive project.tar.gz -X ".hg*"
413 hg archive project.tar.gz -X ".hg*"
384
414
385 Valid types are:
415 Valid types are:
386
416
387 :``files``: a directory full of files (default)
417 :``files``: a directory full of files (default)
388 :``tar``: tar archive, uncompressed
418 :``tar``: tar archive, uncompressed
389 :``tbz2``: tar archive, compressed using bzip2
419 :``tbz2``: tar archive, compressed using bzip2
390 :``tgz``: tar archive, compressed using gzip
420 :``tgz``: tar archive, compressed using gzip
391 :``uzip``: zip archive, uncompressed
421 :``uzip``: zip archive, uncompressed
392 :``zip``: zip archive, compressed using deflate
422 :``zip``: zip archive, compressed using deflate
393
423
394 The exact name of the destination archive or directory is given
424 The exact name of the destination archive or directory is given
395 using a format string; see :hg:`help export` for details.
425 using a format string; see :hg:`help export` for details.
396
426
397 Each member added to an archive file has a directory prefix
427 Each member added to an archive file has a directory prefix
398 prepended. Use -p/--prefix to specify a format string for the
428 prepended. Use -p/--prefix to specify a format string for the
399 prefix. The default is the basename of the archive, with suffixes
429 prefix. The default is the basename of the archive, with suffixes
400 removed.
430 removed.
401
431
402 Returns 0 on success.
432 Returns 0 on success.
403 '''
433 '''
404
434
405 ctx = scmutil.revsingle(repo, opts.get('rev'))
435 ctx = scmutil.revsingle(repo, opts.get('rev'))
406 if not ctx:
436 if not ctx:
407 raise util.Abort(_('no working directory: please specify a revision'))
437 raise util.Abort(_('no working directory: please specify a revision'))
408 node = ctx.node()
438 node = ctx.node()
409 dest = cmdutil.makefilename(repo, dest, node)
439 dest = cmdutil.makefilename(repo, dest, node)
410 if os.path.realpath(dest) == repo.root:
440 if os.path.realpath(dest) == repo.root:
411 raise util.Abort(_('repository root cannot be destination'))
441 raise util.Abort(_('repository root cannot be destination'))
412
442
413 kind = opts.get('type') or archival.guesskind(dest) or 'files'
443 kind = opts.get('type') or archival.guesskind(dest) or 'files'
414 prefix = opts.get('prefix')
444 prefix = opts.get('prefix')
415
445
416 if dest == '-':
446 if dest == '-':
417 if kind == 'files':
447 if kind == 'files':
418 raise util.Abort(_('cannot archive plain files to stdout'))
448 raise util.Abort(_('cannot archive plain files to stdout'))
419 dest = cmdutil.makefileobj(repo, dest)
449 dest = cmdutil.makefileobj(repo, dest)
420 if not prefix:
450 if not prefix:
421 prefix = os.path.basename(repo.root) + '-%h'
451 prefix = os.path.basename(repo.root) + '-%h'
422
452
423 prefix = cmdutil.makefilename(repo, prefix, node)
453 prefix = cmdutil.makefilename(repo, prefix, node)
424 matchfn = scmutil.match(ctx, [], opts)
454 matchfn = scmutil.match(ctx, [], opts)
425 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
455 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
426 matchfn, prefix, subrepos=opts.get('subrepos'))
456 matchfn, prefix, subrepos=opts.get('subrepos'))
427
457
428 @command('backout',
458 @command('backout',
429 [('', 'merge', None, _('merge with old dirstate parent after backout')),
459 [('', 'merge', None, _('merge with old dirstate parent after backout')),
430 ('', 'commit', None, _('commit if no conflicts were encountered')),
460 ('', 'commit', None, _('commit if no conflicts were encountered')),
431 ('', 'parent', '',
461 ('', 'parent', '',
432 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
462 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
433 ('r', 'rev', '', _('revision to backout'), _('REV')),
463 ('r', 'rev', '', _('revision to backout'), _('REV')),
434 ('e', 'edit', False, _('invoke editor on commit messages')),
464 ('e', 'edit', False, _('invoke editor on commit messages')),
435 ] + mergetoolopts + walkopts + commitopts + commitopts2,
465 ] + mergetoolopts + walkopts + commitopts + commitopts2,
436 _('[OPTION]... [-r] REV'))
466 _('[OPTION]... [-r] REV'))
437 def backout(ui, repo, node=None, rev=None, commit=False, **opts):
467 def backout(ui, repo, node=None, rev=None, commit=False, **opts):
438 '''reverse effect of earlier changeset
468 '''reverse effect of earlier changeset
439
469
440 Prepare a new changeset with the effect of REV undone in the
470 Prepare a new changeset with the effect of REV undone in the
441 current working directory.
471 current working directory.
442
472
443 If REV is the parent of the working directory, then this new changeset
473 If REV is the parent of the working directory, then this new changeset
444 is committed automatically. Otherwise, hg needs to merge the
474 is committed automatically. Otherwise, hg needs to merge the
445 changes and the merged result is left uncommitted.
475 changes and the merged result is left uncommitted.
446
476
447 .. note::
477 .. note::
448
478
449 backout cannot be used to fix either an unwanted or
479 backout cannot be used to fix either an unwanted or
450 incorrect merge.
480 incorrect merge.
451
481
452 .. container:: verbose
482 .. container:: verbose
453
483
454 By default, the pending changeset will have one parent,
484 By default, the pending changeset will have one parent,
455 maintaining a linear history. With --merge, the pending
485 maintaining a linear history. With --merge, the pending
456 changeset will instead have two parents: the old parent of the
486 changeset will instead have two parents: the old parent of the
457 working directory and a new child of REV that simply undoes REV.
487 working directory and a new child of REV that simply undoes REV.
458
488
459 Before version 1.7, the behavior without --merge was equivalent
489 Before version 1.7, the behavior without --merge was equivalent
460 to specifying --merge followed by :hg:`update --clean .` to
490 to specifying --merge followed by :hg:`update --clean .` to
461 cancel the merge and leave the child of REV as a head to be
491 cancel the merge and leave the child of REV as a head to be
462 merged separately.
492 merged separately.
463
493
464 See :hg:`help dates` for a list of formats valid for -d/--date.
494 See :hg:`help dates` for a list of formats valid for -d/--date.
465
495
466 Returns 0 on success, 1 if nothing to backout or there are unresolved
496 Returns 0 on success, 1 if nothing to backout or there are unresolved
467 files.
497 files.
468 '''
498 '''
469 if rev and node:
499 if rev and node:
470 raise util.Abort(_("please specify just one revision"))
500 raise util.Abort(_("please specify just one revision"))
471
501
472 if not rev:
502 if not rev:
473 rev = node
503 rev = node
474
504
475 if not rev:
505 if not rev:
476 raise util.Abort(_("please specify a revision to backout"))
506 raise util.Abort(_("please specify a revision to backout"))
477
507
478 date = opts.get('date')
508 date = opts.get('date')
479 if date:
509 if date:
480 opts['date'] = util.parsedate(date)
510 opts['date'] = util.parsedate(date)
481
511
482 cmdutil.checkunfinished(repo)
512 cmdutil.checkunfinished(repo)
483 cmdutil.bailifchanged(repo)
513 cmdutil.bailifchanged(repo)
484 node = scmutil.revsingle(repo, rev).node()
514 node = scmutil.revsingle(repo, rev).node()
485
515
486 op1, op2 = repo.dirstate.parents()
516 op1, op2 = repo.dirstate.parents()
487 if not repo.changelog.isancestor(node, op1):
517 if not repo.changelog.isancestor(node, op1):
488 raise util.Abort(_('cannot backout change that is not an ancestor'))
518 raise util.Abort(_('cannot backout change that is not an ancestor'))
489
519
490 p1, p2 = repo.changelog.parents(node)
520 p1, p2 = repo.changelog.parents(node)
491 if p1 == nullid:
521 if p1 == nullid:
492 raise util.Abort(_('cannot backout a change with no parents'))
522 raise util.Abort(_('cannot backout a change with no parents'))
493 if p2 != nullid:
523 if p2 != nullid:
494 if not opts.get('parent'):
524 if not opts.get('parent'):
495 raise util.Abort(_('cannot backout a merge changeset'))
525 raise util.Abort(_('cannot backout a merge changeset'))
496 p = repo.lookup(opts['parent'])
526 p = repo.lookup(opts['parent'])
497 if p not in (p1, p2):
527 if p not in (p1, p2):
498 raise util.Abort(_('%s is not a parent of %s') %
528 raise util.Abort(_('%s is not a parent of %s') %
499 (short(p), short(node)))
529 (short(p), short(node)))
500 parent = p
530 parent = p
501 else:
531 else:
502 if opts.get('parent'):
532 if opts.get('parent'):
503 raise util.Abort(_('cannot use --parent on non-merge changeset'))
533 raise util.Abort(_('cannot use --parent on non-merge changeset'))
504 parent = p1
534 parent = p1
505
535
506 # the backout should appear on the same branch
536 # the backout should appear on the same branch
507 wlock = repo.wlock()
537 wlock = repo.wlock()
508 try:
538 try:
509 branch = repo.dirstate.branch()
539 branch = repo.dirstate.branch()
510 bheads = repo.branchheads(branch)
540 bheads = repo.branchheads(branch)
511 rctx = scmutil.revsingle(repo, hex(parent))
541 rctx = scmutil.revsingle(repo, hex(parent))
512 if not opts.get('merge') and op1 != node:
542 if not opts.get('merge') and op1 != node:
513 try:
543 try:
514 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
544 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
515 'backout')
545 'backout')
516 repo.dirstate.beginparentchange()
546 repo.dirstate.beginparentchange()
517 stats = mergemod.update(repo, parent, True, True, False,
547 stats = mergemod.update(repo, parent, True, True, False,
518 node, False)
548 node, False)
519 repo.setparents(op1, op2)
549 repo.setparents(op1, op2)
520 repo.dirstate.endparentchange()
550 repo.dirstate.endparentchange()
521 hg._showstats(repo, stats)
551 hg._showstats(repo, stats)
522 if stats[3]:
552 if stats[3]:
523 repo.ui.status(_("use 'hg resolve' to retry unresolved "
553 repo.ui.status(_("use 'hg resolve' to retry unresolved "
524 "file merges\n"))
554 "file merges\n"))
525 return 1
555 return 1
526 elif not commit:
556 elif not commit:
527 msg = _("changeset %s backed out, "
557 msg = _("changeset %s backed out, "
528 "don't forget to commit.\n")
558 "don't forget to commit.\n")
529 ui.status(msg % short(node))
559 ui.status(msg % short(node))
530 return 0
560 return 0
531 finally:
561 finally:
532 ui.setconfig('ui', 'forcemerge', '', '')
562 ui.setconfig('ui', 'forcemerge', '', '')
533 else:
563 else:
534 hg.clean(repo, node, show_stats=False)
564 hg.clean(repo, node, show_stats=False)
535 repo.dirstate.setbranch(branch)
565 repo.dirstate.setbranch(branch)
536 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
566 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
537
567
538
568
539 def commitfunc(ui, repo, message, match, opts):
569 def commitfunc(ui, repo, message, match, opts):
540 editform = 'backout'
570 editform = 'backout'
541 e = cmdutil.getcommiteditor(editform=editform, **opts)
571 e = cmdutil.getcommiteditor(editform=editform, **opts)
542 if not message:
572 if not message:
543 # we don't translate commit messages
573 # we don't translate commit messages
544 message = "Backed out changeset %s" % short(node)
574 message = "Backed out changeset %s" % short(node)
545 e = cmdutil.getcommiteditor(edit=True, editform=editform)
575 e = cmdutil.getcommiteditor(edit=True, editform=editform)
546 return repo.commit(message, opts.get('user'), opts.get('date'),
576 return repo.commit(message, opts.get('user'), opts.get('date'),
547 match, editor=e)
577 match, editor=e)
548 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
578 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
549 if not newnode:
579 if not newnode:
550 ui.status(_("nothing changed\n"))
580 ui.status(_("nothing changed\n"))
551 return 1
581 return 1
552 cmdutil.commitstatus(repo, newnode, branch, bheads)
582 cmdutil.commitstatus(repo, newnode, branch, bheads)
553
583
554 def nice(node):
584 def nice(node):
555 return '%d:%s' % (repo.changelog.rev(node), short(node))
585 return '%d:%s' % (repo.changelog.rev(node), short(node))
556 ui.status(_('changeset %s backs out changeset %s\n') %
586 ui.status(_('changeset %s backs out changeset %s\n') %
557 (nice(repo.changelog.tip()), nice(node)))
587 (nice(repo.changelog.tip()), nice(node)))
558 if opts.get('merge') and op1 != node:
588 if opts.get('merge') and op1 != node:
559 hg.clean(repo, op1, show_stats=False)
589 hg.clean(repo, op1, show_stats=False)
560 ui.status(_('merging with changeset %s\n')
590 ui.status(_('merging with changeset %s\n')
561 % nice(repo.changelog.tip()))
591 % nice(repo.changelog.tip()))
562 try:
592 try:
563 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
593 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
564 'backout')
594 'backout')
565 return hg.merge(repo, hex(repo.changelog.tip()))
595 return hg.merge(repo, hex(repo.changelog.tip()))
566 finally:
596 finally:
567 ui.setconfig('ui', 'forcemerge', '', '')
597 ui.setconfig('ui', 'forcemerge', '', '')
568 finally:
598 finally:
569 wlock.release()
599 wlock.release()
570 return 0
600 return 0
571
601
572 @command('bisect',
602 @command('bisect',
573 [('r', 'reset', False, _('reset bisect state')),
603 [('r', 'reset', False, _('reset bisect state')),
574 ('g', 'good', False, _('mark changeset good')),
604 ('g', 'good', False, _('mark changeset good')),
575 ('b', 'bad', False, _('mark changeset bad')),
605 ('b', 'bad', False, _('mark changeset bad')),
576 ('s', 'skip', False, _('skip testing changeset')),
606 ('s', 'skip', False, _('skip testing changeset')),
577 ('e', 'extend', False, _('extend the bisect range')),
607 ('e', 'extend', False, _('extend the bisect range')),
578 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
608 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
579 ('U', 'noupdate', False, _('do not update to target'))],
609 ('U', 'noupdate', False, _('do not update to target'))],
580 _("[-gbsr] [-U] [-c CMD] [REV]"))
610 _("[-gbsr] [-U] [-c CMD] [REV]"))
581 def bisect(ui, repo, rev=None, extra=None, command=None,
611 def bisect(ui, repo, rev=None, extra=None, command=None,
582 reset=None, good=None, bad=None, skip=None, extend=None,
612 reset=None, good=None, bad=None, skip=None, extend=None,
583 noupdate=None):
613 noupdate=None):
584 """subdivision search of changesets
614 """subdivision search of changesets
585
615
586 This command helps to find changesets which introduce problems. To
616 This command helps to find changesets which introduce problems. To
587 use, mark the earliest changeset you know exhibits the problem as
617 use, mark the earliest changeset you know exhibits the problem as
588 bad, then mark the latest changeset which is free from the problem
618 bad, then mark the latest changeset which is free from the problem
589 as good. Bisect will update your working directory to a revision
619 as good. Bisect will update your working directory to a revision
590 for testing (unless the -U/--noupdate option is specified). Once
620 for testing (unless the -U/--noupdate option is specified). Once
591 you have performed tests, mark the working directory as good or
621 you have performed tests, mark the working directory as good or
592 bad, and bisect will either update to another candidate changeset
622 bad, and bisect will either update to another candidate changeset
593 or announce that it has found the bad revision.
623 or announce that it has found the bad revision.
594
624
595 As a shortcut, you can also use the revision argument to mark a
625 As a shortcut, you can also use the revision argument to mark a
596 revision as good or bad without checking it out first.
626 revision as good or bad without checking it out first.
597
627
598 If you supply a command, it will be used for automatic bisection.
628 If you supply a command, it will be used for automatic bisection.
599 The environment variable HG_NODE will contain the ID of the
629 The environment variable HG_NODE will contain the ID of the
600 changeset being tested. The exit status of the command will be
630 changeset being tested. The exit status of the command will be
601 used to mark revisions as good or bad: status 0 means good, 125
631 used to mark revisions as good or bad: status 0 means good, 125
602 means to skip the revision, 127 (command not found) will abort the
632 means to skip the revision, 127 (command not found) will abort the
603 bisection, and any other non-zero exit status means the revision
633 bisection, and any other non-zero exit status means the revision
604 is bad.
634 is bad.
605
635
606 .. container:: verbose
636 .. container:: verbose
607
637
608 Some examples:
638 Some examples:
609
639
610 - start a bisection with known bad revision 34, and good revision 12::
640 - start a bisection with known bad revision 34, and good revision 12::
611
641
612 hg bisect --bad 34
642 hg bisect --bad 34
613 hg bisect --good 12
643 hg bisect --good 12
614
644
615 - advance the current bisection by marking current revision as good or
645 - advance the current bisection by marking current revision as good or
616 bad::
646 bad::
617
647
618 hg bisect --good
648 hg bisect --good
619 hg bisect --bad
649 hg bisect --bad
620
650
621 - mark the current revision, or a known revision, to be skipped (e.g. if
651 - mark the current revision, or a known revision, to be skipped (e.g. if
622 that revision is not usable because of another issue)::
652 that revision is not usable because of another issue)::
623
653
624 hg bisect --skip
654 hg bisect --skip
625 hg bisect --skip 23
655 hg bisect --skip 23
626
656
627 - skip all revisions that do not touch directories ``foo`` or ``bar``::
657 - skip all revisions that do not touch directories ``foo`` or ``bar``::
628
658
629 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
659 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
630
660
631 - forget the current bisection::
661 - forget the current bisection::
632
662
633 hg bisect --reset
663 hg bisect --reset
634
664
635 - use 'make && make tests' to automatically find the first broken
665 - use 'make && make tests' to automatically find the first broken
636 revision::
666 revision::
637
667
638 hg bisect --reset
668 hg bisect --reset
639 hg bisect --bad 34
669 hg bisect --bad 34
640 hg bisect --good 12
670 hg bisect --good 12
641 hg bisect --command "make && make tests"
671 hg bisect --command "make && make tests"
642
672
643 - see all changesets whose states are already known in the current
673 - see all changesets whose states are already known in the current
644 bisection::
674 bisection::
645
675
646 hg log -r "bisect(pruned)"
676 hg log -r "bisect(pruned)"
647
677
648 - see the changeset currently being bisected (especially useful
678 - see the changeset currently being bisected (especially useful
649 if running with -U/--noupdate)::
679 if running with -U/--noupdate)::
650
680
651 hg log -r "bisect(current)"
681 hg log -r "bisect(current)"
652
682
653 - see all changesets that took part in the current bisection::
683 - see all changesets that took part in the current bisection::
654
684
655 hg log -r "bisect(range)"
685 hg log -r "bisect(range)"
656
686
657 - you can even get a nice graph::
687 - you can even get a nice graph::
658
688
659 hg log --graph -r "bisect(range)"
689 hg log --graph -r "bisect(range)"
660
690
661 See :hg:`help revsets` for more about the `bisect()` keyword.
691 See :hg:`help revsets` for more about the `bisect()` keyword.
662
692
663 Returns 0 on success.
693 Returns 0 on success.
664 """
694 """
665 def extendbisectrange(nodes, good):
695 def extendbisectrange(nodes, good):
666 # bisect is incomplete when it ends on a merge node and
696 # bisect is incomplete when it ends on a merge node and
667 # one of the parent was not checked.
697 # one of the parent was not checked.
668 parents = repo[nodes[0]].parents()
698 parents = repo[nodes[0]].parents()
669 if len(parents) > 1:
699 if len(parents) > 1:
670 if good:
700 if good:
671 side = state['bad']
701 side = state['bad']
672 else:
702 else:
673 side = state['good']
703 side = state['good']
674 num = len(set(i.node() for i in parents) & set(side))
704 num = len(set(i.node() for i in parents) & set(side))
675 if num == 1:
705 if num == 1:
676 return parents[0].ancestor(parents[1])
706 return parents[0].ancestor(parents[1])
677 return None
707 return None
678
708
679 def print_result(nodes, good):
709 def print_result(nodes, good):
680 displayer = cmdutil.show_changeset(ui, repo, {})
710 displayer = cmdutil.show_changeset(ui, repo, {})
681 if len(nodes) == 1:
711 if len(nodes) == 1:
682 # narrowed it down to a single revision
712 # narrowed it down to a single revision
683 if good:
713 if good:
684 ui.write(_("The first good revision is:\n"))
714 ui.write(_("The first good revision is:\n"))
685 else:
715 else:
686 ui.write(_("The first bad revision is:\n"))
716 ui.write(_("The first bad revision is:\n"))
687 displayer.show(repo[nodes[0]])
717 displayer.show(repo[nodes[0]])
688 extendnode = extendbisectrange(nodes, good)
718 extendnode = extendbisectrange(nodes, good)
689 if extendnode is not None:
719 if extendnode is not None:
690 ui.write(_('Not all ancestors of this changeset have been'
720 ui.write(_('Not all ancestors of this changeset have been'
691 ' checked.\nUse bisect --extend to continue the '
721 ' checked.\nUse bisect --extend to continue the '
692 'bisection from\nthe common ancestor, %s.\n')
722 'bisection from\nthe common ancestor, %s.\n')
693 % extendnode)
723 % extendnode)
694 else:
724 else:
695 # multiple possible revisions
725 # multiple possible revisions
696 if good:
726 if good:
697 ui.write(_("Due to skipped revisions, the first "
727 ui.write(_("Due to skipped revisions, the first "
698 "good revision could be any of:\n"))
728 "good revision could be any of:\n"))
699 else:
729 else:
700 ui.write(_("Due to skipped revisions, the first "
730 ui.write(_("Due to skipped revisions, the first "
701 "bad revision could be any of:\n"))
731 "bad revision could be any of:\n"))
702 for n in nodes:
732 for n in nodes:
703 displayer.show(repo[n])
733 displayer.show(repo[n])
704 displayer.close()
734 displayer.close()
705
735
706 def check_state(state, interactive=True):
736 def check_state(state, interactive=True):
707 if not state['good'] or not state['bad']:
737 if not state['good'] or not state['bad']:
708 if (good or bad or skip or reset) and interactive:
738 if (good or bad or skip or reset) and interactive:
709 return
739 return
710 if not state['good']:
740 if not state['good']:
711 raise util.Abort(_('cannot bisect (no known good revisions)'))
741 raise util.Abort(_('cannot bisect (no known good revisions)'))
712 else:
742 else:
713 raise util.Abort(_('cannot bisect (no known bad revisions)'))
743 raise util.Abort(_('cannot bisect (no known bad revisions)'))
714 return True
744 return True
715
745
716 # backward compatibility
746 # backward compatibility
717 if rev in "good bad reset init".split():
747 if rev in "good bad reset init".split():
718 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
748 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
719 cmd, rev, extra = rev, extra, None
749 cmd, rev, extra = rev, extra, None
720 if cmd == "good":
750 if cmd == "good":
721 good = True
751 good = True
722 elif cmd == "bad":
752 elif cmd == "bad":
723 bad = True
753 bad = True
724 else:
754 else:
725 reset = True
755 reset = True
726 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
756 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
727 raise util.Abort(_('incompatible arguments'))
757 raise util.Abort(_('incompatible arguments'))
728
758
729 cmdutil.checkunfinished(repo)
759 cmdutil.checkunfinished(repo)
730
760
731 if reset:
761 if reset:
732 p = repo.join("bisect.state")
762 p = repo.join("bisect.state")
733 if os.path.exists(p):
763 if os.path.exists(p):
734 os.unlink(p)
764 os.unlink(p)
735 return
765 return
736
766
737 state = hbisect.load_state(repo)
767 state = hbisect.load_state(repo)
738
768
739 if command:
769 if command:
740 changesets = 1
770 changesets = 1
741 if noupdate:
771 if noupdate:
742 try:
772 try:
743 node = state['current'][0]
773 node = state['current'][0]
744 except LookupError:
774 except LookupError:
745 raise util.Abort(_('current bisect revision is unknown - '
775 raise util.Abort(_('current bisect revision is unknown - '
746 'start a new bisect to fix'))
776 'start a new bisect to fix'))
747 else:
777 else:
748 node, p2 = repo.dirstate.parents()
778 node, p2 = repo.dirstate.parents()
749 if p2 != nullid:
779 if p2 != nullid:
750 raise util.Abort(_('current bisect revision is a merge'))
780 raise util.Abort(_('current bisect revision is a merge'))
751 try:
781 try:
752 while changesets:
782 while changesets:
753 # update state
783 # update state
754 state['current'] = [node]
784 state['current'] = [node]
755 hbisect.save_state(repo, state)
785 hbisect.save_state(repo, state)
756 status = ui.system(command, environ={'HG_NODE': hex(node)})
786 status = ui.system(command, environ={'HG_NODE': hex(node)})
757 if status == 125:
787 if status == 125:
758 transition = "skip"
788 transition = "skip"
759 elif status == 0:
789 elif status == 0:
760 transition = "good"
790 transition = "good"
761 # status < 0 means process was killed
791 # status < 0 means process was killed
762 elif status == 127:
792 elif status == 127:
763 raise util.Abort(_("failed to execute %s") % command)
793 raise util.Abort(_("failed to execute %s") % command)
764 elif status < 0:
794 elif status < 0:
765 raise util.Abort(_("%s killed") % command)
795 raise util.Abort(_("%s killed") % command)
766 else:
796 else:
767 transition = "bad"
797 transition = "bad"
768 ctx = scmutil.revsingle(repo, rev, node)
798 ctx = scmutil.revsingle(repo, rev, node)
769 rev = None # clear for future iterations
799 rev = None # clear for future iterations
770 state[transition].append(ctx.node())
800 state[transition].append(ctx.node())
771 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
801 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
772 check_state(state, interactive=False)
802 check_state(state, interactive=False)
773 # bisect
803 # bisect
774 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
804 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
775 # update to next check
805 # update to next check
776 node = nodes[0]
806 node = nodes[0]
777 if not noupdate:
807 if not noupdate:
778 cmdutil.bailifchanged(repo)
808 cmdutil.bailifchanged(repo)
779 hg.clean(repo, node, show_stats=False)
809 hg.clean(repo, node, show_stats=False)
780 finally:
810 finally:
781 state['current'] = [node]
811 state['current'] = [node]
782 hbisect.save_state(repo, state)
812 hbisect.save_state(repo, state)
783 print_result(nodes, bgood)
813 print_result(nodes, bgood)
784 return
814 return
785
815
786 # update state
816 # update state
787
817
788 if rev:
818 if rev:
789 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
819 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
790 else:
820 else:
791 nodes = [repo.lookup('.')]
821 nodes = [repo.lookup('.')]
792
822
793 if good or bad or skip:
823 if good or bad or skip:
794 if good:
824 if good:
795 state['good'] += nodes
825 state['good'] += nodes
796 elif bad:
826 elif bad:
797 state['bad'] += nodes
827 state['bad'] += nodes
798 elif skip:
828 elif skip:
799 state['skip'] += nodes
829 state['skip'] += nodes
800 hbisect.save_state(repo, state)
830 hbisect.save_state(repo, state)
801
831
802 if not check_state(state):
832 if not check_state(state):
803 return
833 return
804
834
805 # actually bisect
835 # actually bisect
806 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
836 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
807 if extend:
837 if extend:
808 if not changesets:
838 if not changesets:
809 extendnode = extendbisectrange(nodes, good)
839 extendnode = extendbisectrange(nodes, good)
810 if extendnode is not None:
840 if extendnode is not None:
811 ui.write(_("Extending search to changeset %d:%s\n")
841 ui.write(_("Extending search to changeset %d:%s\n")
812 % (extendnode.rev(), extendnode))
842 % (extendnode.rev(), extendnode))
813 state['current'] = [extendnode.node()]
843 state['current'] = [extendnode.node()]
814 hbisect.save_state(repo, state)
844 hbisect.save_state(repo, state)
815 if noupdate:
845 if noupdate:
816 return
846 return
817 cmdutil.bailifchanged(repo)
847 cmdutil.bailifchanged(repo)
818 return hg.clean(repo, extendnode.node())
848 return hg.clean(repo, extendnode.node())
819 raise util.Abort(_("nothing to extend"))
849 raise util.Abort(_("nothing to extend"))
820
850
821 if changesets == 0:
851 if changesets == 0:
822 print_result(nodes, good)
852 print_result(nodes, good)
823 else:
853 else:
824 assert len(nodes) == 1 # only a single node can be tested next
854 assert len(nodes) == 1 # only a single node can be tested next
825 node = nodes[0]
855 node = nodes[0]
826 # compute the approximate number of remaining tests
856 # compute the approximate number of remaining tests
827 tests, size = 0, 2
857 tests, size = 0, 2
828 while size <= changesets:
858 while size <= changesets:
829 tests, size = tests + 1, size * 2
859 tests, size = tests + 1, size * 2
830 rev = repo.changelog.rev(node)
860 rev = repo.changelog.rev(node)
831 ui.write(_("Testing changeset %d:%s "
861 ui.write(_("Testing changeset %d:%s "
832 "(%d changesets remaining, ~%d tests)\n")
862 "(%d changesets remaining, ~%d tests)\n")
833 % (rev, short(node), changesets, tests))
863 % (rev, short(node), changesets, tests))
834 state['current'] = [node]
864 state['current'] = [node]
835 hbisect.save_state(repo, state)
865 hbisect.save_state(repo, state)
836 if not noupdate:
866 if not noupdate:
837 cmdutil.bailifchanged(repo)
867 cmdutil.bailifchanged(repo)
838 return hg.clean(repo, node)
868 return hg.clean(repo, node)
839
869
840 @command('bookmarks|bookmark',
870 @command('bookmarks|bookmark',
841 [('f', 'force', False, _('force')),
871 [('f', 'force', False, _('force')),
842 ('r', 'rev', '', _('revision'), _('REV')),
872 ('r', 'rev', '', _('revision'), _('REV')),
843 ('d', 'delete', False, _('delete a given bookmark')),
873 ('d', 'delete', False, _('delete a given bookmark')),
844 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
874 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
845 ('i', 'inactive', False, _('mark a bookmark inactive')),
875 ('i', 'inactive', False, _('mark a bookmark inactive')),
846 ] + formatteropts,
876 ] + formatteropts,
847 _('hg bookmarks [OPTIONS]... [NAME]...'))
877 _('hg bookmarks [OPTIONS]... [NAME]...'))
848 def bookmark(ui, repo, *names, **opts):
878 def bookmark(ui, repo, *names, **opts):
849 '''create a new bookmark or list existing bookmarks
879 '''create a new bookmark or list existing bookmarks
850
880
851 Bookmarks are labels on changesets to help track lines of development.
881 Bookmarks are labels on changesets to help track lines of development.
852 Bookmarks are unversioned and can be moved, renamed and deleted.
882 Bookmarks are unversioned and can be moved, renamed and deleted.
853 Deleting or moving a bookmark has no effect on the associated changesets.
883 Deleting or moving a bookmark has no effect on the associated changesets.
854
884
855 Creating or updating to a bookmark causes it to be marked as 'active'.
885 Creating or updating to a bookmark causes it to be marked as 'active'.
856 The active bookmark is indicated with a '*'.
886 The active bookmark is indicated with a '*'.
857 When a commit is made, the active bookmark will advance to the new commit.
887 When a commit is made, the active bookmark will advance to the new commit.
858 A plain :hg:`update` will also advance an active bookmark, if possible.
888 A plain :hg:`update` will also advance an active bookmark, if possible.
859 Updating away from a bookmark will cause it to be deactivated.
889 Updating away from a bookmark will cause it to be deactivated.
860
890
861 Bookmarks can be pushed and pulled between repositories (see
891 Bookmarks can be pushed and pulled between repositories (see
862 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
892 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
863 diverged, a new 'divergent bookmark' of the form 'name@path' will
893 diverged, a new 'divergent bookmark' of the form 'name@path' will
864 be created. Using :hg:`merge` will resolve the divergence.
894 be created. Using :hg:`merge` will resolve the divergence.
865
895
866 A bookmark named '@' has the special property that :hg:`clone` will
896 A bookmark named '@' has the special property that :hg:`clone` will
867 check it out by default if it exists.
897 check it out by default if it exists.
868
898
869 .. container:: verbose
899 .. container:: verbose
870
900
871 Examples:
901 Examples:
872
902
873 - create an active bookmark for a new line of development::
903 - create an active bookmark for a new line of development::
874
904
875 hg book new-feature
905 hg book new-feature
876
906
877 - create an inactive bookmark as a place marker::
907 - create an inactive bookmark as a place marker::
878
908
879 hg book -i reviewed
909 hg book -i reviewed
880
910
881 - create an inactive bookmark on another changeset::
911 - create an inactive bookmark on another changeset::
882
912
883 hg book -r .^ tested
913 hg book -r .^ tested
884
914
885 - move the '@' bookmark from another branch::
915 - move the '@' bookmark from another branch::
886
916
887 hg book -f @
917 hg book -f @
888 '''
918 '''
889 force = opts.get('force')
919 force = opts.get('force')
890 rev = opts.get('rev')
920 rev = opts.get('rev')
891 delete = opts.get('delete')
921 delete = opts.get('delete')
892 rename = opts.get('rename')
922 rename = opts.get('rename')
893 inactive = opts.get('inactive')
923 inactive = opts.get('inactive')
894
924
895 def checkformat(mark):
925 def checkformat(mark):
896 mark = mark.strip()
926 mark = mark.strip()
897 if not mark:
927 if not mark:
898 raise util.Abort(_("bookmark names cannot consist entirely of "
928 raise util.Abort(_("bookmark names cannot consist entirely of "
899 "whitespace"))
929 "whitespace"))
900 scmutil.checknewlabel(repo, mark, 'bookmark')
930 scmutil.checknewlabel(repo, mark, 'bookmark')
901 return mark
931 return mark
902
932
903 def checkconflict(repo, mark, cur, force=False, target=None):
933 def checkconflict(repo, mark, cur, force=False, target=None):
904 if mark in marks and not force:
934 if mark in marks and not force:
905 if target:
935 if target:
906 if marks[mark] == target and target == cur:
936 if marks[mark] == target and target == cur:
907 # re-activating a bookmark
937 # re-activating a bookmark
908 return
938 return
909 anc = repo.changelog.ancestors([repo[target].rev()])
939 anc = repo.changelog.ancestors([repo[target].rev()])
910 bmctx = repo[marks[mark]]
940 bmctx = repo[marks[mark]]
911 divs = [repo[b].node() for b in marks
941 divs = [repo[b].node() for b in marks
912 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
942 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
913
943
914 # allow resolving a single divergent bookmark even if moving
944 # allow resolving a single divergent bookmark even if moving
915 # the bookmark across branches when a revision is specified
945 # the bookmark across branches when a revision is specified
916 # that contains a divergent bookmark
946 # that contains a divergent bookmark
917 if bmctx.rev() not in anc and target in divs:
947 if bmctx.rev() not in anc and target in divs:
918 bookmarks.deletedivergent(repo, [target], mark)
948 bookmarks.deletedivergent(repo, [target], mark)
919 return
949 return
920
950
921 deletefrom = [b for b in divs
951 deletefrom = [b for b in divs
922 if repo[b].rev() in anc or b == target]
952 if repo[b].rev() in anc or b == target]
923 bookmarks.deletedivergent(repo, deletefrom, mark)
953 bookmarks.deletedivergent(repo, deletefrom, mark)
924 if bookmarks.validdest(repo, bmctx, repo[target]):
954 if bookmarks.validdest(repo, bmctx, repo[target]):
925 ui.status(_("moving bookmark '%s' forward from %s\n") %
955 ui.status(_("moving bookmark '%s' forward from %s\n") %
926 (mark, short(bmctx.node())))
956 (mark, short(bmctx.node())))
927 return
957 return
928 raise util.Abort(_("bookmark '%s' already exists "
958 raise util.Abort(_("bookmark '%s' already exists "
929 "(use -f to force)") % mark)
959 "(use -f to force)") % mark)
930 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
960 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
931 and not force):
961 and not force):
932 raise util.Abort(
962 raise util.Abort(
933 _("a bookmark cannot have the name of an existing branch"))
963 _("a bookmark cannot have the name of an existing branch"))
934
964
935 if delete and rename:
965 if delete and rename:
936 raise util.Abort(_("--delete and --rename are incompatible"))
966 raise util.Abort(_("--delete and --rename are incompatible"))
937 if delete and rev:
967 if delete and rev:
938 raise util.Abort(_("--rev is incompatible with --delete"))
968 raise util.Abort(_("--rev is incompatible with --delete"))
939 if rename and rev:
969 if rename and rev:
940 raise util.Abort(_("--rev is incompatible with --rename"))
970 raise util.Abort(_("--rev is incompatible with --rename"))
941 if not names and (delete or rev):
971 if not names and (delete or rev):
942 raise util.Abort(_("bookmark name required"))
972 raise util.Abort(_("bookmark name required"))
943
973
944 if delete or rename or names or inactive:
974 if delete or rename or names or inactive:
945 wlock = repo.wlock()
975 wlock = repo.wlock()
946 try:
976 try:
947 cur = repo.changectx('.').node()
977 cur = repo.changectx('.').node()
948 marks = repo._bookmarks
978 marks = repo._bookmarks
949 if delete:
979 if delete:
950 for mark in names:
980 for mark in names:
951 if mark not in marks:
981 if mark not in marks:
952 raise util.Abort(_("bookmark '%s' does not exist") %
982 raise util.Abort(_("bookmark '%s' does not exist") %
953 mark)
983 mark)
954 if mark == repo._bookmarkcurrent:
984 if mark == repo._bookmarkcurrent:
955 bookmarks.unsetcurrent(repo)
985 bookmarks.unsetcurrent(repo)
956 del marks[mark]
986 del marks[mark]
957 marks.write()
987 marks.write()
958
988
959 elif rename:
989 elif rename:
960 if not names:
990 if not names:
961 raise util.Abort(_("new bookmark name required"))
991 raise util.Abort(_("new bookmark name required"))
962 elif len(names) > 1:
992 elif len(names) > 1:
963 raise util.Abort(_("only one new bookmark name allowed"))
993 raise util.Abort(_("only one new bookmark name allowed"))
964 mark = checkformat(names[0])
994 mark = checkformat(names[0])
965 if rename not in marks:
995 if rename not in marks:
966 raise util.Abort(_("bookmark '%s' does not exist") % rename)
996 raise util.Abort(_("bookmark '%s' does not exist") % rename)
967 checkconflict(repo, mark, cur, force)
997 checkconflict(repo, mark, cur, force)
968 marks[mark] = marks[rename]
998 marks[mark] = marks[rename]
969 if repo._bookmarkcurrent == rename and not inactive:
999 if repo._bookmarkcurrent == rename and not inactive:
970 bookmarks.setcurrent(repo, mark)
1000 bookmarks.setcurrent(repo, mark)
971 del marks[rename]
1001 del marks[rename]
972 marks.write()
1002 marks.write()
973
1003
974 elif names:
1004 elif names:
975 newact = None
1005 newact = None
976 for mark in names:
1006 for mark in names:
977 mark = checkformat(mark)
1007 mark = checkformat(mark)
978 if newact is None:
1008 if newact is None:
979 newact = mark
1009 newact = mark
980 if inactive and mark == repo._bookmarkcurrent:
1010 if inactive and mark == repo._bookmarkcurrent:
981 bookmarks.unsetcurrent(repo)
1011 bookmarks.unsetcurrent(repo)
982 return
1012 return
983 tgt = cur
1013 tgt = cur
984 if rev:
1014 if rev:
985 tgt = scmutil.revsingle(repo, rev).node()
1015 tgt = scmutil.revsingle(repo, rev).node()
986 checkconflict(repo, mark, cur, force, tgt)
1016 checkconflict(repo, mark, cur, force, tgt)
987 marks[mark] = tgt
1017 marks[mark] = tgt
988 if not inactive and cur == marks[newact] and not rev:
1018 if not inactive and cur == marks[newact] and not rev:
989 bookmarks.setcurrent(repo, newact)
1019 bookmarks.setcurrent(repo, newact)
990 elif cur != tgt and newact == repo._bookmarkcurrent:
1020 elif cur != tgt and newact == repo._bookmarkcurrent:
991 bookmarks.unsetcurrent(repo)
1021 bookmarks.unsetcurrent(repo)
992 marks.write()
1022 marks.write()
993
1023
994 elif inactive:
1024 elif inactive:
995 if len(marks) == 0:
1025 if len(marks) == 0:
996 ui.status(_("no bookmarks set\n"))
1026 ui.status(_("no bookmarks set\n"))
997 elif not repo._bookmarkcurrent:
1027 elif not repo._bookmarkcurrent:
998 ui.status(_("no active bookmark\n"))
1028 ui.status(_("no active bookmark\n"))
999 else:
1029 else:
1000 bookmarks.unsetcurrent(repo)
1030 bookmarks.unsetcurrent(repo)
1001 finally:
1031 finally:
1002 wlock.release()
1032 wlock.release()
1003 else: # show bookmarks
1033 else: # show bookmarks
1004 fm = ui.formatter('bookmarks', opts)
1034 fm = ui.formatter('bookmarks', opts)
1005 hexfn = fm.hexfunc
1035 hexfn = fm.hexfunc
1006 marks = repo._bookmarks
1036 marks = repo._bookmarks
1007 if len(marks) == 0 and not fm:
1037 if len(marks) == 0 and not fm:
1008 ui.status(_("no bookmarks set\n"))
1038 ui.status(_("no bookmarks set\n"))
1009 for bmark, n in sorted(marks.iteritems()):
1039 for bmark, n in sorted(marks.iteritems()):
1010 current = repo._bookmarkcurrent
1040 current = repo._bookmarkcurrent
1011 if bmark == current:
1041 if bmark == current:
1012 prefix, label = '*', 'bookmarks.current'
1042 prefix, label = '*', 'bookmarks.current'
1013 else:
1043 else:
1014 prefix, label = ' ', ''
1044 prefix, label = ' ', ''
1015
1045
1016 fm.startitem()
1046 fm.startitem()
1017 if not ui.quiet:
1047 if not ui.quiet:
1018 fm.plain(' %s ' % prefix, label=label)
1048 fm.plain(' %s ' % prefix, label=label)
1019 fm.write('bookmark', '%s', bmark, label=label)
1049 fm.write('bookmark', '%s', bmark, label=label)
1020 pad = " " * (25 - encoding.colwidth(bmark))
1050 pad = " " * (25 - encoding.colwidth(bmark))
1021 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1051 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1022 repo.changelog.rev(n), hexfn(n), label=label)
1052 repo.changelog.rev(n), hexfn(n), label=label)
1023 fm.data(active=(bmark == current))
1053 fm.data(active=(bmark == current))
1024 fm.plain('\n')
1054 fm.plain('\n')
1025 fm.end()
1055 fm.end()
1026
1056
1027 @command('branch',
1057 @command('branch',
1028 [('f', 'force', None,
1058 [('f', 'force', None,
1029 _('set branch name even if it shadows an existing branch')),
1059 _('set branch name even if it shadows an existing branch')),
1030 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1060 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1031 _('[-fC] [NAME]'))
1061 _('[-fC] [NAME]'))
1032 def branch(ui, repo, label=None, **opts):
1062 def branch(ui, repo, label=None, **opts):
1033 """set or show the current branch name
1063 """set or show the current branch name
1034
1064
1035 .. note::
1065 .. note::
1036
1066
1037 Branch names are permanent and global. Use :hg:`bookmark` to create a
1067 Branch names are permanent and global. Use :hg:`bookmark` to create a
1038 light-weight bookmark instead. See :hg:`help glossary` for more
1068 light-weight bookmark instead. See :hg:`help glossary` for more
1039 information about named branches and bookmarks.
1069 information about named branches and bookmarks.
1040
1070
1041 With no argument, show the current branch name. With one argument,
1071 With no argument, show the current branch name. With one argument,
1042 set the working directory branch name (the branch will not exist
1072 set the working directory branch name (the branch will not exist
1043 in the repository until the next commit). Standard practice
1073 in the repository until the next commit). Standard practice
1044 recommends that primary development take place on the 'default'
1074 recommends that primary development take place on the 'default'
1045 branch.
1075 branch.
1046
1076
1047 Unless -f/--force is specified, branch will not let you set a
1077 Unless -f/--force is specified, branch will not let you set a
1048 branch name that already exists.
1078 branch name that already exists.
1049
1079
1050 Use -C/--clean to reset the working directory branch to that of
1080 Use -C/--clean to reset the working directory branch to that of
1051 the parent of the working directory, negating a previous branch
1081 the parent of the working directory, negating a previous branch
1052 change.
1082 change.
1053
1083
1054 Use the command :hg:`update` to switch to an existing branch. Use
1084 Use the command :hg:`update` to switch to an existing branch. Use
1055 :hg:`commit --close-branch` to mark this branch as closed.
1085 :hg:`commit --close-branch` to mark this branch as closed.
1056
1086
1057 Returns 0 on success.
1087 Returns 0 on success.
1058 """
1088 """
1059 if label:
1089 if label:
1060 label = label.strip()
1090 label = label.strip()
1061
1091
1062 if not opts.get('clean') and not label:
1092 if not opts.get('clean') and not label:
1063 ui.write("%s\n" % repo.dirstate.branch())
1093 ui.write("%s\n" % repo.dirstate.branch())
1064 return
1094 return
1065
1095
1066 wlock = repo.wlock()
1096 wlock = repo.wlock()
1067 try:
1097 try:
1068 if opts.get('clean'):
1098 if opts.get('clean'):
1069 label = repo[None].p1().branch()
1099 label = repo[None].p1().branch()
1070 repo.dirstate.setbranch(label)
1100 repo.dirstate.setbranch(label)
1071 ui.status(_('reset working directory to branch %s\n') % label)
1101 ui.status(_('reset working directory to branch %s\n') % label)
1072 elif label:
1102 elif label:
1073 if not opts.get('force') and label in repo.branchmap():
1103 if not opts.get('force') and label in repo.branchmap():
1074 if label not in [p.branch() for p in repo.parents()]:
1104 if label not in [p.branch() for p in repo.parents()]:
1075 raise util.Abort(_('a branch of the same name already'
1105 raise util.Abort(_('a branch of the same name already'
1076 ' exists'),
1106 ' exists'),
1077 # i18n: "it" refers to an existing branch
1107 # i18n: "it" refers to an existing branch
1078 hint=_("use 'hg update' to switch to it"))
1108 hint=_("use 'hg update' to switch to it"))
1079 scmutil.checknewlabel(repo, label, 'branch')
1109 scmutil.checknewlabel(repo, label, 'branch')
1080 repo.dirstate.setbranch(label)
1110 repo.dirstate.setbranch(label)
1081 ui.status(_('marked working directory as branch %s\n') % label)
1111 ui.status(_('marked working directory as branch %s\n') % label)
1082 ui.status(_('(branches are permanent and global, '
1112 ui.status(_('(branches are permanent and global, '
1083 'did you want a bookmark?)\n'))
1113 'did you want a bookmark?)\n'))
1084 finally:
1114 finally:
1085 wlock.release()
1115 wlock.release()
1086
1116
1087 @command('branches',
1117 @command('branches',
1088 [('a', 'active', False,
1118 [('a', 'active', False,
1089 _('show only branches that have unmerged heads (DEPRECATED)')),
1119 _('show only branches that have unmerged heads (DEPRECATED)')),
1090 ('c', 'closed', False, _('show normal and closed branches')),
1120 ('c', 'closed', False, _('show normal and closed branches')),
1091 ] + formatteropts,
1121 ] + formatteropts,
1092 _('[-ac]'))
1122 _('[-ac]'))
1093 def branches(ui, repo, active=False, closed=False, **opts):
1123 def branches(ui, repo, active=False, closed=False, **opts):
1094 """list repository named branches
1124 """list repository named branches
1095
1125
1096 List the repository's named branches, indicating which ones are
1126 List the repository's named branches, indicating which ones are
1097 inactive. If -c/--closed is specified, also list branches which have
1127 inactive. If -c/--closed is specified, also list branches which have
1098 been marked closed (see :hg:`commit --close-branch`).
1128 been marked closed (see :hg:`commit --close-branch`).
1099
1129
1100 Use the command :hg:`update` to switch to an existing branch.
1130 Use the command :hg:`update` to switch to an existing branch.
1101
1131
1102 Returns 0.
1132 Returns 0.
1103 """
1133 """
1104
1134
1105 fm = ui.formatter('branches', opts)
1135 fm = ui.formatter('branches', opts)
1106 hexfunc = fm.hexfunc
1136 hexfunc = fm.hexfunc
1107
1137
1108 allheads = set(repo.heads())
1138 allheads = set(repo.heads())
1109 branches = []
1139 branches = []
1110 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1140 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1111 isactive = not isclosed and bool(set(heads) & allheads)
1141 isactive = not isclosed and bool(set(heads) & allheads)
1112 branches.append((tag, repo[tip], isactive, not isclosed))
1142 branches.append((tag, repo[tip], isactive, not isclosed))
1113 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1143 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1114 reverse=True)
1144 reverse=True)
1115
1145
1116 for tag, ctx, isactive, isopen in branches:
1146 for tag, ctx, isactive, isopen in branches:
1117 if active and not isactive:
1147 if active and not isactive:
1118 continue
1148 continue
1119 if isactive:
1149 if isactive:
1120 label = 'branches.active'
1150 label = 'branches.active'
1121 notice = ''
1151 notice = ''
1122 elif not isopen:
1152 elif not isopen:
1123 if not closed:
1153 if not closed:
1124 continue
1154 continue
1125 label = 'branches.closed'
1155 label = 'branches.closed'
1126 notice = _(' (closed)')
1156 notice = _(' (closed)')
1127 else:
1157 else:
1128 label = 'branches.inactive'
1158 label = 'branches.inactive'
1129 notice = _(' (inactive)')
1159 notice = _(' (inactive)')
1130 current = (tag == repo.dirstate.branch())
1160 current = (tag == repo.dirstate.branch())
1131 if current:
1161 if current:
1132 label = 'branches.current'
1162 label = 'branches.current'
1133
1163
1134 fm.startitem()
1164 fm.startitem()
1135 fm.write('branch', '%s', tag, label=label)
1165 fm.write('branch', '%s', tag, label=label)
1136 rev = ctx.rev()
1166 rev = ctx.rev()
1137 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1167 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1138 fmt = ' ' * padsize + ' %d:%s'
1168 fmt = ' ' * padsize + ' %d:%s'
1139 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1169 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1140 label='log.changeset changeset.%s' % ctx.phasestr())
1170 label='log.changeset changeset.%s' % ctx.phasestr())
1141 fm.data(active=isactive, closed=not isopen, current=current)
1171 fm.data(active=isactive, closed=not isopen, current=current)
1142 if not ui.quiet:
1172 if not ui.quiet:
1143 fm.plain(notice)
1173 fm.plain(notice)
1144 fm.plain('\n')
1174 fm.plain('\n')
1145 fm.end()
1175 fm.end()
1146
1176
1147 @command('bundle',
1177 @command('bundle',
1148 [('f', 'force', None, _('run even when the destination is unrelated')),
1178 [('f', 'force', None, _('run even when the destination is unrelated')),
1149 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1179 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1150 _('REV')),
1180 _('REV')),
1151 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1181 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1152 _('BRANCH')),
1182 _('BRANCH')),
1153 ('', 'base', [],
1183 ('', 'base', [],
1154 _('a base changeset assumed to be available at the destination'),
1184 _('a base changeset assumed to be available at the destination'),
1155 _('REV')),
1185 _('REV')),
1156 ('a', 'all', None, _('bundle all changesets in the repository')),
1186 ('a', 'all', None, _('bundle all changesets in the repository')),
1157 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1187 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1158 ] + remoteopts,
1188 ] + remoteopts,
1159 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1189 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1160 def bundle(ui, repo, fname, dest=None, **opts):
1190 def bundle(ui, repo, fname, dest=None, **opts):
1161 """create a changegroup file
1191 """create a changegroup file
1162
1192
1163 Generate a compressed changegroup file collecting changesets not
1193 Generate a compressed changegroup file collecting changesets not
1164 known to be in another repository.
1194 known to be in another repository.
1165
1195
1166 If you omit the destination repository, then hg assumes the
1196 If you omit the destination repository, then hg assumes the
1167 destination will have all the nodes you specify with --base
1197 destination will have all the nodes you specify with --base
1168 parameters. To create a bundle containing all changesets, use
1198 parameters. To create a bundle containing all changesets, use
1169 -a/--all (or --base null).
1199 -a/--all (or --base null).
1170
1200
1171 You can change compression method with the -t/--type option.
1201 You can change compression method with the -t/--type option.
1172 The available compression methods are: none, bzip2, and
1202 The available compression methods are: none, bzip2, and
1173 gzip (by default, bundles are compressed using bzip2).
1203 gzip (by default, bundles are compressed using bzip2).
1174
1204
1175 The bundle file can then be transferred using conventional means
1205 The bundle file can then be transferred using conventional means
1176 and applied to another repository with the unbundle or pull
1206 and applied to another repository with the unbundle or pull
1177 command. This is useful when direct push and pull are not
1207 command. This is useful when direct push and pull are not
1178 available or when exporting an entire repository is undesirable.
1208 available or when exporting an entire repository is undesirable.
1179
1209
1180 Applying bundles preserves all changeset contents including
1210 Applying bundles preserves all changeset contents including
1181 permissions, copy/rename information, and revision history.
1211 permissions, copy/rename information, and revision history.
1182
1212
1183 Returns 0 on success, 1 if no changes found.
1213 Returns 0 on success, 1 if no changes found.
1184 """
1214 """
1185 revs = None
1215 revs = None
1186 if 'rev' in opts:
1216 if 'rev' in opts:
1187 revs = scmutil.revrange(repo, opts['rev'])
1217 revs = scmutil.revrange(repo, opts['rev'])
1188
1218
1189 bundletype = opts.get('type', 'bzip2').lower()
1219 bundletype = opts.get('type', 'bzip2').lower()
1190 btypes = {'none': 'HG10UN',
1220 btypes = {'none': 'HG10UN',
1191 'bzip2': 'HG10BZ',
1221 'bzip2': 'HG10BZ',
1192 'gzip': 'HG10GZ',
1222 'gzip': 'HG10GZ',
1193 'bundle2': 'HG2Y'}
1223 'bundle2': 'HG2Y'}
1194 bundletype = btypes.get(bundletype)
1224 bundletype = btypes.get(bundletype)
1195 if bundletype not in changegroup.bundletypes:
1225 if bundletype not in changegroup.bundletypes:
1196 raise util.Abort(_('unknown bundle type specified with --type'))
1226 raise util.Abort(_('unknown bundle type specified with --type'))
1197
1227
1198 if opts.get('all'):
1228 if opts.get('all'):
1199 base = ['null']
1229 base = ['null']
1200 else:
1230 else:
1201 base = scmutil.revrange(repo, opts.get('base'))
1231 base = scmutil.revrange(repo, opts.get('base'))
1202 # TODO: get desired bundlecaps from command line.
1232 # TODO: get desired bundlecaps from command line.
1203 bundlecaps = None
1233 bundlecaps = None
1204 if base:
1234 if base:
1205 if dest:
1235 if dest:
1206 raise util.Abort(_("--base is incompatible with specifying "
1236 raise util.Abort(_("--base is incompatible with specifying "
1207 "a destination"))
1237 "a destination"))
1208 common = [repo.lookup(rev) for rev in base]
1238 common = [repo.lookup(rev) for rev in base]
1209 heads = revs and map(repo.lookup, revs) or revs
1239 heads = revs and map(repo.lookup, revs) or revs
1210 cg = changegroup.getchangegroup(repo, 'bundle', heads=heads,
1240 cg = changegroup.getchangegroup(repo, 'bundle', heads=heads,
1211 common=common, bundlecaps=bundlecaps)
1241 common=common, bundlecaps=bundlecaps)
1212 outgoing = None
1242 outgoing = None
1213 else:
1243 else:
1214 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1244 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1215 dest, branches = hg.parseurl(dest, opts.get('branch'))
1245 dest, branches = hg.parseurl(dest, opts.get('branch'))
1216 other = hg.peer(repo, opts, dest)
1246 other = hg.peer(repo, opts, dest)
1217 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1247 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1218 heads = revs and map(repo.lookup, revs) or revs
1248 heads = revs and map(repo.lookup, revs) or revs
1219 outgoing = discovery.findcommonoutgoing(repo, other,
1249 outgoing = discovery.findcommonoutgoing(repo, other,
1220 onlyheads=heads,
1250 onlyheads=heads,
1221 force=opts.get('force'),
1251 force=opts.get('force'),
1222 portable=True)
1252 portable=True)
1223 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1253 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1224 bundlecaps)
1254 bundlecaps)
1225 if not cg:
1255 if not cg:
1226 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1256 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1227 return 1
1257 return 1
1228
1258
1229 changegroup.writebundle(ui, cg, fname, bundletype)
1259 changegroup.writebundle(ui, cg, fname, bundletype)
1230
1260
1231 @command('cat',
1261 @command('cat',
1232 [('o', 'output', '',
1262 [('o', 'output', '',
1233 _('print output to file with formatted name'), _('FORMAT')),
1263 _('print output to file with formatted name'), _('FORMAT')),
1234 ('r', 'rev', '', _('print the given revision'), _('REV')),
1264 ('r', 'rev', '', _('print the given revision'), _('REV')),
1235 ('', 'decode', None, _('apply any matching decode filter')),
1265 ('', 'decode', None, _('apply any matching decode filter')),
1236 ] + walkopts,
1266 ] + walkopts,
1237 _('[OPTION]... FILE...'),
1267 _('[OPTION]... FILE...'),
1238 inferrepo=True)
1268 inferrepo=True)
1239 def cat(ui, repo, file1, *pats, **opts):
1269 def cat(ui, repo, file1, *pats, **opts):
1240 """output the current or given revision of files
1270 """output the current or given revision of files
1241
1271
1242 Print the specified files as they were at the given revision. If
1272 Print the specified files as they were at the given revision. If
1243 no revision is given, the parent of the working directory is used.
1273 no revision is given, the parent of the working directory is used.
1244
1274
1245 Output may be to a file, in which case the name of the file is
1275 Output may be to a file, in which case the name of the file is
1246 given using a format string. The formatting rules as follows:
1276 given using a format string. The formatting rules as follows:
1247
1277
1248 :``%%``: literal "%" character
1278 :``%%``: literal "%" character
1249 :``%s``: basename of file being printed
1279 :``%s``: basename of file being printed
1250 :``%d``: dirname of file being printed, or '.' if in repository root
1280 :``%d``: dirname of file being printed, or '.' if in repository root
1251 :``%p``: root-relative path name of file being printed
1281 :``%p``: root-relative path name of file being printed
1252 :``%H``: changeset hash (40 hexadecimal digits)
1282 :``%H``: changeset hash (40 hexadecimal digits)
1253 :``%R``: changeset revision number
1283 :``%R``: changeset revision number
1254 :``%h``: short-form changeset hash (12 hexadecimal digits)
1284 :``%h``: short-form changeset hash (12 hexadecimal digits)
1255 :``%r``: zero-padded changeset revision number
1285 :``%r``: zero-padded changeset revision number
1256 :``%b``: basename of the exporting repository
1286 :``%b``: basename of the exporting repository
1257
1287
1258 Returns 0 on success.
1288 Returns 0 on success.
1259 """
1289 """
1260 ctx = scmutil.revsingle(repo, opts.get('rev'))
1290 ctx = scmutil.revsingle(repo, opts.get('rev'))
1261 m = scmutil.match(ctx, (file1,) + pats, opts)
1291 m = scmutil.match(ctx, (file1,) + pats, opts)
1262
1292
1263 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1293 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1264
1294
1265 @command('^clone',
1295 @command('^clone',
1266 [('U', 'noupdate', None, _('the clone will include an empty working '
1296 [('U', 'noupdate', None, _('the clone will include an empty working '
1267 'directory (only a repository)')),
1297 'directory (only a repository)')),
1268 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1298 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1269 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1299 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1270 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1300 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1271 ('', 'pull', None, _('use pull protocol to copy metadata')),
1301 ('', 'pull', None, _('use pull protocol to copy metadata')),
1272 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1302 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1273 ] + remoteopts,
1303 ] + remoteopts,
1274 _('[OPTION]... SOURCE [DEST]'),
1304 _('[OPTION]... SOURCE [DEST]'),
1275 norepo=True)
1305 norepo=True)
1276 def clone(ui, source, dest=None, **opts):
1306 def clone(ui, source, dest=None, **opts):
1277 """make a copy of an existing repository
1307 """make a copy of an existing repository
1278
1308
1279 Create a copy of an existing repository in a new directory.
1309 Create a copy of an existing repository in a new directory.
1280
1310
1281 If no destination directory name is specified, it defaults to the
1311 If no destination directory name is specified, it defaults to the
1282 basename of the source.
1312 basename of the source.
1283
1313
1284 The location of the source is added to the new repository's
1314 The location of the source is added to the new repository's
1285 ``.hg/hgrc`` file, as the default to be used for future pulls.
1315 ``.hg/hgrc`` file, as the default to be used for future pulls.
1286
1316
1287 Only local paths and ``ssh://`` URLs are supported as
1317 Only local paths and ``ssh://`` URLs are supported as
1288 destinations. For ``ssh://`` destinations, no working directory or
1318 destinations. For ``ssh://`` destinations, no working directory or
1289 ``.hg/hgrc`` will be created on the remote side.
1319 ``.hg/hgrc`` will be created on the remote side.
1290
1320
1291 To pull only a subset of changesets, specify one or more revisions
1321 To pull only a subset of changesets, specify one or more revisions
1292 identifiers with -r/--rev or branches with -b/--branch. The
1322 identifiers with -r/--rev or branches with -b/--branch. The
1293 resulting clone will contain only the specified changesets and
1323 resulting clone will contain only the specified changesets and
1294 their ancestors. These options (or 'clone src#rev dest') imply
1324 their ancestors. These options (or 'clone src#rev dest') imply
1295 --pull, even for local source repositories. Note that specifying a
1325 --pull, even for local source repositories. Note that specifying a
1296 tag will include the tagged changeset but not the changeset
1326 tag will include the tagged changeset but not the changeset
1297 containing the tag.
1327 containing the tag.
1298
1328
1299 If the source repository has a bookmark called '@' set, that
1329 If the source repository has a bookmark called '@' set, that
1300 revision will be checked out in the new repository by default.
1330 revision will be checked out in the new repository by default.
1301
1331
1302 To check out a particular version, use -u/--update, or
1332 To check out a particular version, use -u/--update, or
1303 -U/--noupdate to create a clone with no working directory.
1333 -U/--noupdate to create a clone with no working directory.
1304
1334
1305 .. container:: verbose
1335 .. container:: verbose
1306
1336
1307 For efficiency, hardlinks are used for cloning whenever the
1337 For efficiency, hardlinks are used for cloning whenever the
1308 source and destination are on the same filesystem (note this
1338 source and destination are on the same filesystem (note this
1309 applies only to the repository data, not to the working
1339 applies only to the repository data, not to the working
1310 directory). Some filesystems, such as AFS, implement hardlinking
1340 directory). Some filesystems, such as AFS, implement hardlinking
1311 incorrectly, but do not report errors. In these cases, use the
1341 incorrectly, but do not report errors. In these cases, use the
1312 --pull option to avoid hardlinking.
1342 --pull option to avoid hardlinking.
1313
1343
1314 In some cases, you can clone repositories and the working
1344 In some cases, you can clone repositories and the working
1315 directory using full hardlinks with ::
1345 directory using full hardlinks with ::
1316
1346
1317 $ cp -al REPO REPOCLONE
1347 $ cp -al REPO REPOCLONE
1318
1348
1319 This is the fastest way to clone, but it is not always safe. The
1349 This is the fastest way to clone, but it is not always safe. The
1320 operation is not atomic (making sure REPO is not modified during
1350 operation is not atomic (making sure REPO is not modified during
1321 the operation is up to you) and you have to make sure your
1351 the operation is up to you) and you have to make sure your
1322 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1352 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1323 so). Also, this is not compatible with certain extensions that
1353 so). Also, this is not compatible with certain extensions that
1324 place their metadata under the .hg directory, such as mq.
1354 place their metadata under the .hg directory, such as mq.
1325
1355
1326 Mercurial will update the working directory to the first applicable
1356 Mercurial will update the working directory to the first applicable
1327 revision from this list:
1357 revision from this list:
1328
1358
1329 a) null if -U or the source repository has no changesets
1359 a) null if -U or the source repository has no changesets
1330 b) if -u . and the source repository is local, the first parent of
1360 b) if -u . and the source repository is local, the first parent of
1331 the source repository's working directory
1361 the source repository's working directory
1332 c) the changeset specified with -u (if a branch name, this means the
1362 c) the changeset specified with -u (if a branch name, this means the
1333 latest head of that branch)
1363 latest head of that branch)
1334 d) the changeset specified with -r
1364 d) the changeset specified with -r
1335 e) the tipmost head specified with -b
1365 e) the tipmost head specified with -b
1336 f) the tipmost head specified with the url#branch source syntax
1366 f) the tipmost head specified with the url#branch source syntax
1337 g) the revision marked with the '@' bookmark, if present
1367 g) the revision marked with the '@' bookmark, if present
1338 h) the tipmost head of the default branch
1368 h) the tipmost head of the default branch
1339 i) tip
1369 i) tip
1340
1370
1341 Examples:
1371 Examples:
1342
1372
1343 - clone a remote repository to a new directory named hg/::
1373 - clone a remote repository to a new directory named hg/::
1344
1374
1345 hg clone http://selenic.com/hg
1375 hg clone http://selenic.com/hg
1346
1376
1347 - create a lightweight local clone::
1377 - create a lightweight local clone::
1348
1378
1349 hg clone project/ project-feature/
1379 hg clone project/ project-feature/
1350
1380
1351 - clone from an absolute path on an ssh server (note double-slash)::
1381 - clone from an absolute path on an ssh server (note double-slash)::
1352
1382
1353 hg clone ssh://user@server//home/projects/alpha/
1383 hg clone ssh://user@server//home/projects/alpha/
1354
1384
1355 - do a high-speed clone over a LAN while checking out a
1385 - do a high-speed clone over a LAN while checking out a
1356 specified version::
1386 specified version::
1357
1387
1358 hg clone --uncompressed http://server/repo -u 1.5
1388 hg clone --uncompressed http://server/repo -u 1.5
1359
1389
1360 - create a repository without changesets after a particular revision::
1390 - create a repository without changesets after a particular revision::
1361
1391
1362 hg clone -r 04e544 experimental/ good/
1392 hg clone -r 04e544 experimental/ good/
1363
1393
1364 - clone (and track) a particular named branch::
1394 - clone (and track) a particular named branch::
1365
1395
1366 hg clone http://selenic.com/hg#stable
1396 hg clone http://selenic.com/hg#stable
1367
1397
1368 See :hg:`help urls` for details on specifying URLs.
1398 See :hg:`help urls` for details on specifying URLs.
1369
1399
1370 Returns 0 on success.
1400 Returns 0 on success.
1371 """
1401 """
1372 if opts.get('noupdate') and opts.get('updaterev'):
1402 if opts.get('noupdate') and opts.get('updaterev'):
1373 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1403 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1374
1404
1375 r = hg.clone(ui, opts, source, dest,
1405 r = hg.clone(ui, opts, source, dest,
1376 pull=opts.get('pull'),
1406 pull=opts.get('pull'),
1377 stream=opts.get('uncompressed'),
1407 stream=opts.get('uncompressed'),
1378 rev=opts.get('rev'),
1408 rev=opts.get('rev'),
1379 update=opts.get('updaterev') or not opts.get('noupdate'),
1409 update=opts.get('updaterev') or not opts.get('noupdate'),
1380 branch=opts.get('branch'))
1410 branch=opts.get('branch'))
1381
1411
1382 return r is None
1412 return r is None
1383
1413
1384 @command('^commit|ci',
1414 @command('^commit|ci',
1385 [('A', 'addremove', None,
1415 [('A', 'addremove', None,
1386 _('mark new/missing files as added/removed before committing')),
1416 _('mark new/missing files as added/removed before committing')),
1387 ('', 'close-branch', None,
1417 ('', 'close-branch', None,
1388 _('mark a branch as closed, hiding it from the branch list')),
1418 _('mark a branch as closed, hiding it from the branch list')),
1389 ('', 'amend', None, _('amend the parent of the working directory')),
1419 ('', 'amend', None, _('amend the parent of the working directory')),
1390 ('s', 'secret', None, _('use the secret phase for committing')),
1420 ('s', 'secret', None, _('use the secret phase for committing')),
1391 ('e', 'edit', None, _('invoke editor on commit messages')),
1421 ('e', 'edit', None, _('invoke editor on commit messages')),
1392 ('i', 'interactive', None, _('use interactive mode')),
1422 ('i', 'interactive', None, _('use interactive mode')),
1393 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1423 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1394 _('[OPTION]... [FILE]...'),
1424 _('[OPTION]... [FILE]...'),
1395 inferrepo=True)
1425 inferrepo=True)
1396 def commit(ui, repo, *pats, **opts):
1426 def commit(ui, repo, *pats, **opts):
1397 """commit the specified files or all outstanding changes
1427 """commit the specified files or all outstanding changes
1398
1428
1399 Commit changes to the given files into the repository. Unlike a
1429 Commit changes to the given files into the repository. Unlike a
1400 centralized SCM, this operation is a local operation. See
1430 centralized SCM, this operation is a local operation. See
1401 :hg:`push` for a way to actively distribute your changes.
1431 :hg:`push` for a way to actively distribute your changes.
1402
1432
1403 If a list of files is omitted, all changes reported by :hg:`status`
1433 If a list of files is omitted, all changes reported by :hg:`status`
1404 will be committed.
1434 will be committed.
1405
1435
1406 If you are committing the result of a merge, do not provide any
1436 If you are committing the result of a merge, do not provide any
1407 filenames or -I/-X filters.
1437 filenames or -I/-X filters.
1408
1438
1409 If no commit message is specified, Mercurial starts your
1439 If no commit message is specified, Mercurial starts your
1410 configured editor where you can enter a message. In case your
1440 configured editor where you can enter a message. In case your
1411 commit fails, you will find a backup of your message in
1441 commit fails, you will find a backup of your message in
1412 ``.hg/last-message.txt``.
1442 ``.hg/last-message.txt``.
1413
1443
1414 The --amend flag can be used to amend the parent of the
1444 The --amend flag can be used to amend the parent of the
1415 working directory with a new commit that contains the changes
1445 working directory with a new commit that contains the changes
1416 in the parent in addition to those currently reported by :hg:`status`,
1446 in the parent in addition to those currently reported by :hg:`status`,
1417 if there are any. The old commit is stored in a backup bundle in
1447 if there are any. The old commit is stored in a backup bundle in
1418 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1448 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1419 on how to restore it).
1449 on how to restore it).
1420
1450
1421 Message, user and date are taken from the amended commit unless
1451 Message, user and date are taken from the amended commit unless
1422 specified. When a message isn't specified on the command line,
1452 specified. When a message isn't specified on the command line,
1423 the editor will open with the message of the amended commit.
1453 the editor will open with the message of the amended commit.
1424
1454
1425 It is not possible to amend public changesets (see :hg:`help phases`)
1455 It is not possible to amend public changesets (see :hg:`help phases`)
1426 or changesets that have children.
1456 or changesets that have children.
1427
1457
1428 See :hg:`help dates` for a list of formats valid for -d/--date.
1458 See :hg:`help dates` for a list of formats valid for -d/--date.
1429
1459
1430 Returns 0 on success, 1 if nothing changed.
1460 Returns 0 on success, 1 if nothing changed.
1431 """
1461 """
1432 if opts.get('interactive'):
1462 if opts.get('interactive'):
1433 opts.pop('interactive')
1463 opts.pop('interactive')
1434 cmdutil.dorecord(ui, repo, commit, 'commit', False,
1464 cmdutil.dorecord(ui, repo, commit, 'commit', False,
1435 cmdutil.recordfilter, *pats, **opts)
1465 cmdutil.recordfilter, *pats, **opts)
1436 return
1466 return
1437
1467
1438 if opts.get('subrepos'):
1468 if opts.get('subrepos'):
1439 if opts.get('amend'):
1469 if opts.get('amend'):
1440 raise util.Abort(_('cannot amend with --subrepos'))
1470 raise util.Abort(_('cannot amend with --subrepos'))
1441 # Let --subrepos on the command line override config setting.
1471 # Let --subrepos on the command line override config setting.
1442 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1472 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1443
1473
1444 cmdutil.checkunfinished(repo, commit=True)
1474 cmdutil.checkunfinished(repo, commit=True)
1445
1475
1446 branch = repo[None].branch()
1476 branch = repo[None].branch()
1447 bheads = repo.branchheads(branch)
1477 bheads = repo.branchheads(branch)
1448
1478
1449 extra = {}
1479 extra = {}
1450 if opts.get('close_branch'):
1480 if opts.get('close_branch'):
1451 extra['close'] = 1
1481 extra['close'] = 1
1452
1482
1453 if not bheads:
1483 if not bheads:
1454 raise util.Abort(_('can only close branch heads'))
1484 raise util.Abort(_('can only close branch heads'))
1455 elif opts.get('amend'):
1485 elif opts.get('amend'):
1456 if repo.parents()[0].p1().branch() != branch and \
1486 if repo.parents()[0].p1().branch() != branch and \
1457 repo.parents()[0].p2().branch() != branch:
1487 repo.parents()[0].p2().branch() != branch:
1458 raise util.Abort(_('can only close branch heads'))
1488 raise util.Abort(_('can only close branch heads'))
1459
1489
1460 if opts.get('amend'):
1490 if opts.get('amend'):
1461 if ui.configbool('ui', 'commitsubrepos'):
1491 if ui.configbool('ui', 'commitsubrepos'):
1462 raise util.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1492 raise util.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1463
1493
1464 old = repo['.']
1494 old = repo['.']
1465 if not old.mutable():
1495 if not old.mutable():
1466 raise util.Abort(_('cannot amend public changesets'))
1496 raise util.Abort(_('cannot amend public changesets'))
1467 if len(repo[None].parents()) > 1:
1497 if len(repo[None].parents()) > 1:
1468 raise util.Abort(_('cannot amend while merging'))
1498 raise util.Abort(_('cannot amend while merging'))
1469 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1499 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1470 if not allowunstable and old.children():
1500 if not allowunstable and old.children():
1471 raise util.Abort(_('cannot amend changeset with children'))
1501 raise util.Abort(_('cannot amend changeset with children'))
1472
1502
1473 # commitfunc is used only for temporary amend commit by cmdutil.amend
1503 # commitfunc is used only for temporary amend commit by cmdutil.amend
1474 def commitfunc(ui, repo, message, match, opts):
1504 def commitfunc(ui, repo, message, match, opts):
1475 return repo.commit(message,
1505 return repo.commit(message,
1476 opts.get('user') or old.user(),
1506 opts.get('user') or old.user(),
1477 opts.get('date') or old.date(),
1507 opts.get('date') or old.date(),
1478 match,
1508 match,
1479 extra=extra)
1509 extra=extra)
1480
1510
1481 current = repo._bookmarkcurrent
1511 current = repo._bookmarkcurrent
1482 marks = old.bookmarks()
1512 marks = old.bookmarks()
1483 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1513 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1484 if node == old.node():
1514 if node == old.node():
1485 ui.status(_("nothing changed\n"))
1515 ui.status(_("nothing changed\n"))
1486 return 1
1516 return 1
1487 elif marks:
1517 elif marks:
1488 ui.debug('moving bookmarks %r from %s to %s\n' %
1518 ui.debug('moving bookmarks %r from %s to %s\n' %
1489 (marks, old.hex(), hex(node)))
1519 (marks, old.hex(), hex(node)))
1490 newmarks = repo._bookmarks
1520 newmarks = repo._bookmarks
1491 for bm in marks:
1521 for bm in marks:
1492 newmarks[bm] = node
1522 newmarks[bm] = node
1493 if bm == current:
1523 if bm == current:
1494 bookmarks.setcurrent(repo, bm)
1524 bookmarks.setcurrent(repo, bm)
1495 newmarks.write()
1525 newmarks.write()
1496 else:
1526 else:
1497 def commitfunc(ui, repo, message, match, opts):
1527 def commitfunc(ui, repo, message, match, opts):
1498 backup = ui.backupconfig('phases', 'new-commit')
1528 backup = ui.backupconfig('phases', 'new-commit')
1499 baseui = repo.baseui
1529 baseui = repo.baseui
1500 basebackup = baseui.backupconfig('phases', 'new-commit')
1530 basebackup = baseui.backupconfig('phases', 'new-commit')
1501 try:
1531 try:
1502 if opts.get('secret'):
1532 if opts.get('secret'):
1503 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1533 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1504 # Propagate to subrepos
1534 # Propagate to subrepos
1505 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1535 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1506
1536
1507 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1537 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1508 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1538 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1509 return repo.commit(message, opts.get('user'), opts.get('date'),
1539 return repo.commit(message, opts.get('user'), opts.get('date'),
1510 match,
1540 match,
1511 editor=editor,
1541 editor=editor,
1512 extra=extra)
1542 extra=extra)
1513 finally:
1543 finally:
1514 ui.restoreconfig(backup)
1544 ui.restoreconfig(backup)
1515 repo.baseui.restoreconfig(basebackup)
1545 repo.baseui.restoreconfig(basebackup)
1516
1546
1517
1547
1518 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1548 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1519
1549
1520 if not node:
1550 if not node:
1521 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1551 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1522 if stat[3]:
1552 if stat[3]:
1523 ui.status(_("nothing changed (%d missing files, see "
1553 ui.status(_("nothing changed (%d missing files, see "
1524 "'hg status')\n") % len(stat[3]))
1554 "'hg status')\n") % len(stat[3]))
1525 else:
1555 else:
1526 ui.status(_("nothing changed\n"))
1556 ui.status(_("nothing changed\n"))
1527 return 1
1557 return 1
1528
1558
1529 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1559 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1530
1560
1531 @command('config|showconfig|debugconfig',
1561 @command('config|showconfig|debugconfig',
1532 [('u', 'untrusted', None, _('show untrusted configuration options')),
1562 [('u', 'untrusted', None, _('show untrusted configuration options')),
1533 ('e', 'edit', None, _('edit user config')),
1563 ('e', 'edit', None, _('edit user config')),
1534 ('l', 'local', None, _('edit repository config')),
1564 ('l', 'local', None, _('edit repository config')),
1535 ('g', 'global', None, _('edit global config'))],
1565 ('g', 'global', None, _('edit global config'))],
1536 _('[-u] [NAME]...'),
1566 _('[-u] [NAME]...'),
1537 optionalrepo=True)
1567 optionalrepo=True)
1538 def config(ui, repo, *values, **opts):
1568 def config(ui, repo, *values, **opts):
1539 """show combined config settings from all hgrc files
1569 """show combined config settings from all hgrc files
1540
1570
1541 With no arguments, print names and values of all config items.
1571 With no arguments, print names and values of all config items.
1542
1572
1543 With one argument of the form section.name, print just the value
1573 With one argument of the form section.name, print just the value
1544 of that config item.
1574 of that config item.
1545
1575
1546 With multiple arguments, print names and values of all config
1576 With multiple arguments, print names and values of all config
1547 items with matching section names.
1577 items with matching section names.
1548
1578
1549 With --edit, start an editor on the user-level config file. With
1579 With --edit, start an editor on the user-level config file. With
1550 --global, edit the system-wide config file. With --local, edit the
1580 --global, edit the system-wide config file. With --local, edit the
1551 repository-level config file.
1581 repository-level config file.
1552
1582
1553 With --debug, the source (filename and line number) is printed
1583 With --debug, the source (filename and line number) is printed
1554 for each config item.
1584 for each config item.
1555
1585
1556 See :hg:`help config` for more information about config files.
1586 See :hg:`help config` for more information about config files.
1557
1587
1558 Returns 0 on success, 1 if NAME does not exist.
1588 Returns 0 on success, 1 if NAME does not exist.
1559
1589
1560 """
1590 """
1561
1591
1562 if opts.get('edit') or opts.get('local') or opts.get('global'):
1592 if opts.get('edit') or opts.get('local') or opts.get('global'):
1563 if opts.get('local') and opts.get('global'):
1593 if opts.get('local') and opts.get('global'):
1564 raise util.Abort(_("can't use --local and --global together"))
1594 raise util.Abort(_("can't use --local and --global together"))
1565
1595
1566 if opts.get('local'):
1596 if opts.get('local'):
1567 if not repo:
1597 if not repo:
1568 raise util.Abort(_("can't use --local outside a repository"))
1598 raise util.Abort(_("can't use --local outside a repository"))
1569 paths = [repo.join('hgrc')]
1599 paths = [repo.join('hgrc')]
1570 elif opts.get('global'):
1600 elif opts.get('global'):
1571 paths = scmutil.systemrcpath()
1601 paths = scmutil.systemrcpath()
1572 else:
1602 else:
1573 paths = scmutil.userrcpath()
1603 paths = scmutil.userrcpath()
1574
1604
1575 for f in paths:
1605 for f in paths:
1576 if os.path.exists(f):
1606 if os.path.exists(f):
1577 break
1607 break
1578 else:
1608 else:
1579 if opts.get('global'):
1609 if opts.get('global'):
1580 samplehgrc = uimod.samplehgrcs['global']
1610 samplehgrc = uimod.samplehgrcs['global']
1581 elif opts.get('local'):
1611 elif opts.get('local'):
1582 samplehgrc = uimod.samplehgrcs['local']
1612 samplehgrc = uimod.samplehgrcs['local']
1583 else:
1613 else:
1584 samplehgrc = uimod.samplehgrcs['user']
1614 samplehgrc = uimod.samplehgrcs['user']
1585
1615
1586 f = paths[0]
1616 f = paths[0]
1587 fp = open(f, "w")
1617 fp = open(f, "w")
1588 fp.write(samplehgrc)
1618 fp.write(samplehgrc)
1589 fp.close()
1619 fp.close()
1590
1620
1591 editor = ui.geteditor()
1621 editor = ui.geteditor()
1592 ui.system("%s \"%s\"" % (editor, f),
1622 ui.system("%s \"%s\"" % (editor, f),
1593 onerr=util.Abort, errprefix=_("edit failed"))
1623 onerr=util.Abort, errprefix=_("edit failed"))
1594 return
1624 return
1595
1625
1596 for f in scmutil.rcpath():
1626 for f in scmutil.rcpath():
1597 ui.debug('read config from: %s\n' % f)
1627 ui.debug('read config from: %s\n' % f)
1598 untrusted = bool(opts.get('untrusted'))
1628 untrusted = bool(opts.get('untrusted'))
1599 if values:
1629 if values:
1600 sections = [v for v in values if '.' not in v]
1630 sections = [v for v in values if '.' not in v]
1601 items = [v for v in values if '.' in v]
1631 items = [v for v in values if '.' in v]
1602 if len(items) > 1 or items and sections:
1632 if len(items) > 1 or items and sections:
1603 raise util.Abort(_('only one config item permitted'))
1633 raise util.Abort(_('only one config item permitted'))
1604 matched = False
1634 matched = False
1605 for section, name, value in ui.walkconfig(untrusted=untrusted):
1635 for section, name, value in ui.walkconfig(untrusted=untrusted):
1606 value = str(value).replace('\n', '\\n')
1636 value = str(value).replace('\n', '\\n')
1607 sectname = section + '.' + name
1637 sectname = section + '.' + name
1608 if values:
1638 if values:
1609 for v in values:
1639 for v in values:
1610 if v == section:
1640 if v == section:
1611 ui.debug('%s: ' %
1641 ui.debug('%s: ' %
1612 ui.configsource(section, name, untrusted))
1642 ui.configsource(section, name, untrusted))
1613 ui.write('%s=%s\n' % (sectname, value))
1643 ui.write('%s=%s\n' % (sectname, value))
1614 matched = True
1644 matched = True
1615 elif v == sectname:
1645 elif v == sectname:
1616 ui.debug('%s: ' %
1646 ui.debug('%s: ' %
1617 ui.configsource(section, name, untrusted))
1647 ui.configsource(section, name, untrusted))
1618 ui.write(value, '\n')
1648 ui.write(value, '\n')
1619 matched = True
1649 matched = True
1620 else:
1650 else:
1621 ui.debug('%s: ' %
1651 ui.debug('%s: ' %
1622 ui.configsource(section, name, untrusted))
1652 ui.configsource(section, name, untrusted))
1623 ui.write('%s=%s\n' % (sectname, value))
1653 ui.write('%s=%s\n' % (sectname, value))
1624 matched = True
1654 matched = True
1625 if matched:
1655 if matched:
1626 return 0
1656 return 0
1627 return 1
1657 return 1
1628
1658
1629 @command('copy|cp',
1659 @command('copy|cp',
1630 [('A', 'after', None, _('record a copy that has already occurred')),
1660 [('A', 'after', None, _('record a copy that has already occurred')),
1631 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1661 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1632 ] + walkopts + dryrunopts,
1662 ] + walkopts + dryrunopts,
1633 _('[OPTION]... [SOURCE]... DEST'))
1663 _('[OPTION]... [SOURCE]... DEST'))
1634 def copy(ui, repo, *pats, **opts):
1664 def copy(ui, repo, *pats, **opts):
1635 """mark files as copied for the next commit
1665 """mark files as copied for the next commit
1636
1666
1637 Mark dest as having copies of source files. If dest is a
1667 Mark dest as having copies of source files. If dest is a
1638 directory, copies are put in that directory. If dest is a file,
1668 directory, copies are put in that directory. If dest is a file,
1639 the source must be a single file.
1669 the source must be a single file.
1640
1670
1641 By default, this command copies the contents of files as they
1671 By default, this command copies the contents of files as they
1642 exist in the working directory. If invoked with -A/--after, the
1672 exist in the working directory. If invoked with -A/--after, the
1643 operation is recorded, but no copying is performed.
1673 operation is recorded, but no copying is performed.
1644
1674
1645 This command takes effect with the next commit. To undo a copy
1675 This command takes effect with the next commit. To undo a copy
1646 before that, see :hg:`revert`.
1676 before that, see :hg:`revert`.
1647
1677
1648 Returns 0 on success, 1 if errors are encountered.
1678 Returns 0 on success, 1 if errors are encountered.
1649 """
1679 """
1650 wlock = repo.wlock(False)
1680 wlock = repo.wlock(False)
1651 try:
1681 try:
1652 return cmdutil.copy(ui, repo, pats, opts)
1682 return cmdutil.copy(ui, repo, pats, opts)
1653 finally:
1683 finally:
1654 wlock.release()
1684 wlock.release()
1655
1685
1656 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
1686 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
1657 def debugancestor(ui, repo, *args):
1687 def debugancestor(ui, repo, *args):
1658 """find the ancestor revision of two revisions in a given index"""
1688 """find the ancestor revision of two revisions in a given index"""
1659 if len(args) == 3:
1689 if len(args) == 3:
1660 index, rev1, rev2 = args
1690 index, rev1, rev2 = args
1661 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1691 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1662 lookup = r.lookup
1692 lookup = r.lookup
1663 elif len(args) == 2:
1693 elif len(args) == 2:
1664 if not repo:
1694 if not repo:
1665 raise util.Abort(_("there is no Mercurial repository here "
1695 raise util.Abort(_("there is no Mercurial repository here "
1666 "(.hg not found)"))
1696 "(.hg not found)"))
1667 rev1, rev2 = args
1697 rev1, rev2 = args
1668 r = repo.changelog
1698 r = repo.changelog
1669 lookup = repo.lookup
1699 lookup = repo.lookup
1670 else:
1700 else:
1671 raise util.Abort(_('either two or three arguments required'))
1701 raise util.Abort(_('either two or three arguments required'))
1672 a = r.ancestor(lookup(rev1), lookup(rev2))
1702 a = r.ancestor(lookup(rev1), lookup(rev2))
1673 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1703 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1674
1704
1675 @command('debugbuilddag',
1705 @command('debugbuilddag',
1676 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1706 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1677 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1707 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1678 ('n', 'new-file', None, _('add new file at each rev'))],
1708 ('n', 'new-file', None, _('add new file at each rev'))],
1679 _('[OPTION]... [TEXT]'))
1709 _('[OPTION]... [TEXT]'))
1680 def debugbuilddag(ui, repo, text=None,
1710 def debugbuilddag(ui, repo, text=None,
1681 mergeable_file=False,
1711 mergeable_file=False,
1682 overwritten_file=False,
1712 overwritten_file=False,
1683 new_file=False):
1713 new_file=False):
1684 """builds a repo with a given DAG from scratch in the current empty repo
1714 """builds a repo with a given DAG from scratch in the current empty repo
1685
1715
1686 The description of the DAG is read from stdin if not given on the
1716 The description of the DAG is read from stdin if not given on the
1687 command line.
1717 command line.
1688
1718
1689 Elements:
1719 Elements:
1690
1720
1691 - "+n" is a linear run of n nodes based on the current default parent
1721 - "+n" is a linear run of n nodes based on the current default parent
1692 - "." is a single node based on the current default parent
1722 - "." is a single node based on the current default parent
1693 - "$" resets the default parent to null (implied at the start);
1723 - "$" resets the default parent to null (implied at the start);
1694 otherwise the default parent is always the last node created
1724 otherwise the default parent is always the last node created
1695 - "<p" sets the default parent to the backref p
1725 - "<p" sets the default parent to the backref p
1696 - "*p" is a fork at parent p, which is a backref
1726 - "*p" is a fork at parent p, which is a backref
1697 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1727 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1698 - "/p2" is a merge of the preceding node and p2
1728 - "/p2" is a merge of the preceding node and p2
1699 - ":tag" defines a local tag for the preceding node
1729 - ":tag" defines a local tag for the preceding node
1700 - "@branch" sets the named branch for subsequent nodes
1730 - "@branch" sets the named branch for subsequent nodes
1701 - "#...\\n" is a comment up to the end of the line
1731 - "#...\\n" is a comment up to the end of the line
1702
1732
1703 Whitespace between the above elements is ignored.
1733 Whitespace between the above elements is ignored.
1704
1734
1705 A backref is either
1735 A backref is either
1706
1736
1707 - a number n, which references the node curr-n, where curr is the current
1737 - a number n, which references the node curr-n, where curr is the current
1708 node, or
1738 node, or
1709 - the name of a local tag you placed earlier using ":tag", or
1739 - the name of a local tag you placed earlier using ":tag", or
1710 - empty to denote the default parent.
1740 - empty to denote the default parent.
1711
1741
1712 All string valued-elements are either strictly alphanumeric, or must
1742 All string valued-elements are either strictly alphanumeric, or must
1713 be enclosed in double quotes ("..."), with "\\" as escape character.
1743 be enclosed in double quotes ("..."), with "\\" as escape character.
1714 """
1744 """
1715
1745
1716 if text is None:
1746 if text is None:
1717 ui.status(_("reading DAG from stdin\n"))
1747 ui.status(_("reading DAG from stdin\n"))
1718 text = ui.fin.read()
1748 text = ui.fin.read()
1719
1749
1720 cl = repo.changelog
1750 cl = repo.changelog
1721 if len(cl) > 0:
1751 if len(cl) > 0:
1722 raise util.Abort(_('repository is not empty'))
1752 raise util.Abort(_('repository is not empty'))
1723
1753
1724 # determine number of revs in DAG
1754 # determine number of revs in DAG
1725 total = 0
1755 total = 0
1726 for type, data in dagparser.parsedag(text):
1756 for type, data in dagparser.parsedag(text):
1727 if type == 'n':
1757 if type == 'n':
1728 total += 1
1758 total += 1
1729
1759
1730 if mergeable_file:
1760 if mergeable_file:
1731 linesperrev = 2
1761 linesperrev = 2
1732 # make a file with k lines per rev
1762 # make a file with k lines per rev
1733 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1763 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1734 initialmergedlines.append("")
1764 initialmergedlines.append("")
1735
1765
1736 tags = []
1766 tags = []
1737
1767
1738 lock = tr = None
1768 lock = tr = None
1739 try:
1769 try:
1740 lock = repo.lock()
1770 lock = repo.lock()
1741 tr = repo.transaction("builddag")
1771 tr = repo.transaction("builddag")
1742
1772
1743 at = -1
1773 at = -1
1744 atbranch = 'default'
1774 atbranch = 'default'
1745 nodeids = []
1775 nodeids = []
1746 id = 0
1776 id = 0
1747 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1777 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1748 for type, data in dagparser.parsedag(text):
1778 for type, data in dagparser.parsedag(text):
1749 if type == 'n':
1779 if type == 'n':
1750 ui.note(('node %s\n' % str(data)))
1780 ui.note(('node %s\n' % str(data)))
1751 id, ps = data
1781 id, ps = data
1752
1782
1753 files = []
1783 files = []
1754 fctxs = {}
1784 fctxs = {}
1755
1785
1756 p2 = None
1786 p2 = None
1757 if mergeable_file:
1787 if mergeable_file:
1758 fn = "mf"
1788 fn = "mf"
1759 p1 = repo[ps[0]]
1789 p1 = repo[ps[0]]
1760 if len(ps) > 1:
1790 if len(ps) > 1:
1761 p2 = repo[ps[1]]
1791 p2 = repo[ps[1]]
1762 pa = p1.ancestor(p2)
1792 pa = p1.ancestor(p2)
1763 base, local, other = [x[fn].data() for x in (pa, p1,
1793 base, local, other = [x[fn].data() for x in (pa, p1,
1764 p2)]
1794 p2)]
1765 m3 = simplemerge.Merge3Text(base, local, other)
1795 m3 = simplemerge.Merge3Text(base, local, other)
1766 ml = [l.strip() for l in m3.merge_lines()]
1796 ml = [l.strip() for l in m3.merge_lines()]
1767 ml.append("")
1797 ml.append("")
1768 elif at > 0:
1798 elif at > 0:
1769 ml = p1[fn].data().split("\n")
1799 ml = p1[fn].data().split("\n")
1770 else:
1800 else:
1771 ml = initialmergedlines
1801 ml = initialmergedlines
1772 ml[id * linesperrev] += " r%i" % id
1802 ml[id * linesperrev] += " r%i" % id
1773 mergedtext = "\n".join(ml)
1803 mergedtext = "\n".join(ml)
1774 files.append(fn)
1804 files.append(fn)
1775 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
1805 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
1776
1806
1777 if overwritten_file:
1807 if overwritten_file:
1778 fn = "of"
1808 fn = "of"
1779 files.append(fn)
1809 files.append(fn)
1780 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1810 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1781
1811
1782 if new_file:
1812 if new_file:
1783 fn = "nf%i" % id
1813 fn = "nf%i" % id
1784 files.append(fn)
1814 files.append(fn)
1785 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1815 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1786 if len(ps) > 1:
1816 if len(ps) > 1:
1787 if not p2:
1817 if not p2:
1788 p2 = repo[ps[1]]
1818 p2 = repo[ps[1]]
1789 for fn in p2:
1819 for fn in p2:
1790 if fn.startswith("nf"):
1820 if fn.startswith("nf"):
1791 files.append(fn)
1821 files.append(fn)
1792 fctxs[fn] = p2[fn]
1822 fctxs[fn] = p2[fn]
1793
1823
1794 def fctxfn(repo, cx, path):
1824 def fctxfn(repo, cx, path):
1795 return fctxs.get(path)
1825 return fctxs.get(path)
1796
1826
1797 if len(ps) == 0 or ps[0] < 0:
1827 if len(ps) == 0 or ps[0] < 0:
1798 pars = [None, None]
1828 pars = [None, None]
1799 elif len(ps) == 1:
1829 elif len(ps) == 1:
1800 pars = [nodeids[ps[0]], None]
1830 pars = [nodeids[ps[0]], None]
1801 else:
1831 else:
1802 pars = [nodeids[p] for p in ps]
1832 pars = [nodeids[p] for p in ps]
1803 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1833 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1804 date=(id, 0),
1834 date=(id, 0),
1805 user="debugbuilddag",
1835 user="debugbuilddag",
1806 extra={'branch': atbranch})
1836 extra={'branch': atbranch})
1807 nodeid = repo.commitctx(cx)
1837 nodeid = repo.commitctx(cx)
1808 nodeids.append(nodeid)
1838 nodeids.append(nodeid)
1809 at = id
1839 at = id
1810 elif type == 'l':
1840 elif type == 'l':
1811 id, name = data
1841 id, name = data
1812 ui.note(('tag %s\n' % name))
1842 ui.note(('tag %s\n' % name))
1813 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1843 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1814 elif type == 'a':
1844 elif type == 'a':
1815 ui.note(('branch %s\n' % data))
1845 ui.note(('branch %s\n' % data))
1816 atbranch = data
1846 atbranch = data
1817 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1847 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1818 tr.close()
1848 tr.close()
1819
1849
1820 if tags:
1850 if tags:
1821 repo.vfs.write("localtags", "".join(tags))
1851 repo.vfs.write("localtags", "".join(tags))
1822 finally:
1852 finally:
1823 ui.progress(_('building'), None)
1853 ui.progress(_('building'), None)
1824 release(tr, lock)
1854 release(tr, lock)
1825
1855
1826 @command('debugbundle',
1856 @command('debugbundle',
1827 [('a', 'all', None, _('show all details'))],
1857 [('a', 'all', None, _('show all details'))],
1828 _('FILE'),
1858 _('FILE'),
1829 norepo=True)
1859 norepo=True)
1830 def debugbundle(ui, bundlepath, all=None, **opts):
1860 def debugbundle(ui, bundlepath, all=None, **opts):
1831 """lists the contents of a bundle"""
1861 """lists the contents of a bundle"""
1832 f = hg.openpath(ui, bundlepath)
1862 f = hg.openpath(ui, bundlepath)
1833 try:
1863 try:
1834 gen = exchange.readbundle(ui, f, bundlepath)
1864 gen = exchange.readbundle(ui, f, bundlepath)
1835 if isinstance(gen, bundle2.unbundle20):
1865 if isinstance(gen, bundle2.unbundle20):
1836 return _debugbundle2(ui, gen, all=all, **opts)
1866 return _debugbundle2(ui, gen, all=all, **opts)
1837 if all:
1867 if all:
1838 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1868 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1839
1869
1840 def showchunks(named):
1870 def showchunks(named):
1841 ui.write("\n%s\n" % named)
1871 ui.write("\n%s\n" % named)
1842 chain = None
1872 chain = None
1843 while True:
1873 while True:
1844 chunkdata = gen.deltachunk(chain)
1874 chunkdata = gen.deltachunk(chain)
1845 if not chunkdata:
1875 if not chunkdata:
1846 break
1876 break
1847 node = chunkdata['node']
1877 node = chunkdata['node']
1848 p1 = chunkdata['p1']
1878 p1 = chunkdata['p1']
1849 p2 = chunkdata['p2']
1879 p2 = chunkdata['p2']
1850 cs = chunkdata['cs']
1880 cs = chunkdata['cs']
1851 deltabase = chunkdata['deltabase']
1881 deltabase = chunkdata['deltabase']
1852 delta = chunkdata['delta']
1882 delta = chunkdata['delta']
1853 ui.write("%s %s %s %s %s %s\n" %
1883 ui.write("%s %s %s %s %s %s\n" %
1854 (hex(node), hex(p1), hex(p2),
1884 (hex(node), hex(p1), hex(p2),
1855 hex(cs), hex(deltabase), len(delta)))
1885 hex(cs), hex(deltabase), len(delta)))
1856 chain = node
1886 chain = node
1857
1887
1858 chunkdata = gen.changelogheader()
1888 chunkdata = gen.changelogheader()
1859 showchunks("changelog")
1889 showchunks("changelog")
1860 chunkdata = gen.manifestheader()
1890 chunkdata = gen.manifestheader()
1861 showchunks("manifest")
1891 showchunks("manifest")
1862 while True:
1892 while True:
1863 chunkdata = gen.filelogheader()
1893 chunkdata = gen.filelogheader()
1864 if not chunkdata:
1894 if not chunkdata:
1865 break
1895 break
1866 fname = chunkdata['filename']
1896 fname = chunkdata['filename']
1867 showchunks(fname)
1897 showchunks(fname)
1868 else:
1898 else:
1869 if isinstance(gen, bundle2.unbundle20):
1899 if isinstance(gen, bundle2.unbundle20):
1870 raise util.Abort(_('use debugbundle2 for this file'))
1900 raise util.Abort(_('use debugbundle2 for this file'))
1871 chunkdata = gen.changelogheader()
1901 chunkdata = gen.changelogheader()
1872 chain = None
1902 chain = None
1873 while True:
1903 while True:
1874 chunkdata = gen.deltachunk(chain)
1904 chunkdata = gen.deltachunk(chain)
1875 if not chunkdata:
1905 if not chunkdata:
1876 break
1906 break
1877 node = chunkdata['node']
1907 node = chunkdata['node']
1878 ui.write("%s\n" % hex(node))
1908 ui.write("%s\n" % hex(node))
1879 chain = node
1909 chain = node
1880 finally:
1910 finally:
1881 f.close()
1911 f.close()
1882
1912
1883 def _debugbundle2(ui, gen, **opts):
1913 def _debugbundle2(ui, gen, **opts):
1884 """lists the contents of a bundle2"""
1914 """lists the contents of a bundle2"""
1885 if not isinstance(gen, bundle2.unbundle20):
1915 if not isinstance(gen, bundle2.unbundle20):
1886 raise util.Abort(_('not a bundle2 file'))
1916 raise util.Abort(_('not a bundle2 file'))
1887 ui.write(('Stream params: %s\n' % repr(gen.params)))
1917 ui.write(('Stream params: %s\n' % repr(gen.params)))
1888 for part in gen.iterparts():
1918 for part in gen.iterparts():
1889 ui.write('%s -- %r\n' % (part.type, repr(part.params)))
1919 ui.write('%s -- %r\n' % (part.type, repr(part.params)))
1890 if part.type == 'b2x:changegroup':
1920 if part.type == 'b2x:changegroup':
1891 version = part.params.get('version', '01')
1921 version = part.params.get('version', '01')
1892 cg = changegroup.packermap[version][1](part, 'UN')
1922 cg = changegroup.packermap[version][1](part, 'UN')
1893 chunkdata = cg.changelogheader()
1923 chunkdata = cg.changelogheader()
1894 chain = None
1924 chain = None
1895 while True:
1925 while True:
1896 chunkdata = cg.deltachunk(chain)
1926 chunkdata = cg.deltachunk(chain)
1897 if not chunkdata:
1927 if not chunkdata:
1898 break
1928 break
1899 node = chunkdata['node']
1929 node = chunkdata['node']
1900 ui.write(" %s\n" % hex(node))
1930 ui.write(" %s\n" % hex(node))
1901 chain = node
1931 chain = node
1902
1932
1903 @command('debugcheckstate', [], '')
1933 @command('debugcheckstate', [], '')
1904 def debugcheckstate(ui, repo):
1934 def debugcheckstate(ui, repo):
1905 """validate the correctness of the current dirstate"""
1935 """validate the correctness of the current dirstate"""
1906 parent1, parent2 = repo.dirstate.parents()
1936 parent1, parent2 = repo.dirstate.parents()
1907 m1 = repo[parent1].manifest()
1937 m1 = repo[parent1].manifest()
1908 m2 = repo[parent2].manifest()
1938 m2 = repo[parent2].manifest()
1909 errors = 0
1939 errors = 0
1910 for f in repo.dirstate:
1940 for f in repo.dirstate:
1911 state = repo.dirstate[f]
1941 state = repo.dirstate[f]
1912 if state in "nr" and f not in m1:
1942 if state in "nr" and f not in m1:
1913 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1943 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1914 errors += 1
1944 errors += 1
1915 if state in "a" and f in m1:
1945 if state in "a" and f in m1:
1916 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1946 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1917 errors += 1
1947 errors += 1
1918 if state in "m" and f not in m1 and f not in m2:
1948 if state in "m" and f not in m1 and f not in m2:
1919 ui.warn(_("%s in state %s, but not in either manifest\n") %
1949 ui.warn(_("%s in state %s, but not in either manifest\n") %
1920 (f, state))
1950 (f, state))
1921 errors += 1
1951 errors += 1
1922 for f in m1:
1952 for f in m1:
1923 state = repo.dirstate[f]
1953 state = repo.dirstate[f]
1924 if state not in "nrm":
1954 if state not in "nrm":
1925 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1955 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1926 errors += 1
1956 errors += 1
1927 if errors:
1957 if errors:
1928 error = _(".hg/dirstate inconsistent with current parent's manifest")
1958 error = _(".hg/dirstate inconsistent with current parent's manifest")
1929 raise util.Abort(error)
1959 raise util.Abort(error)
1930
1960
1931 @command('debugcommands', [], _('[COMMAND]'), norepo=True)
1961 @command('debugcommands', [], _('[COMMAND]'), norepo=True)
1932 def debugcommands(ui, cmd='', *args):
1962 def debugcommands(ui, cmd='', *args):
1933 """list all available commands and options"""
1963 """list all available commands and options"""
1934 for cmd, vals in sorted(table.iteritems()):
1964 for cmd, vals in sorted(table.iteritems()):
1935 cmd = cmd.split('|')[0].strip('^')
1965 cmd = cmd.split('|')[0].strip('^')
1936 opts = ', '.join([i[1] for i in vals[1]])
1966 opts = ', '.join([i[1] for i in vals[1]])
1937 ui.write('%s: %s\n' % (cmd, opts))
1967 ui.write('%s: %s\n' % (cmd, opts))
1938
1968
1939 @command('debugcomplete',
1969 @command('debugcomplete',
1940 [('o', 'options', None, _('show the command options'))],
1970 [('o', 'options', None, _('show the command options'))],
1941 _('[-o] CMD'),
1971 _('[-o] CMD'),
1942 norepo=True)
1972 norepo=True)
1943 def debugcomplete(ui, cmd='', **opts):
1973 def debugcomplete(ui, cmd='', **opts):
1944 """returns the completion list associated with the given command"""
1974 """returns the completion list associated with the given command"""
1945
1975
1946 if opts.get('options'):
1976 if opts.get('options'):
1947 options = []
1977 options = []
1948 otables = [globalopts]
1978 otables = [globalopts]
1949 if cmd:
1979 if cmd:
1950 aliases, entry = cmdutil.findcmd(cmd, table, False)
1980 aliases, entry = cmdutil.findcmd(cmd, table, False)
1951 otables.append(entry[1])
1981 otables.append(entry[1])
1952 for t in otables:
1982 for t in otables:
1953 for o in t:
1983 for o in t:
1954 if "(DEPRECATED)" in o[3]:
1984 if "(DEPRECATED)" in o[3]:
1955 continue
1985 continue
1956 if o[0]:
1986 if o[0]:
1957 options.append('-%s' % o[0])
1987 options.append('-%s' % o[0])
1958 options.append('--%s' % o[1])
1988 options.append('--%s' % o[1])
1959 ui.write("%s\n" % "\n".join(options))
1989 ui.write("%s\n" % "\n".join(options))
1960 return
1990 return
1961
1991
1962 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
1992 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
1963 if ui.verbose:
1993 if ui.verbose:
1964 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1994 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1965 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1995 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1966
1996
1967 @command('debugdag',
1997 @command('debugdag',
1968 [('t', 'tags', None, _('use tags as labels')),
1998 [('t', 'tags', None, _('use tags as labels')),
1969 ('b', 'branches', None, _('annotate with branch names')),
1999 ('b', 'branches', None, _('annotate with branch names')),
1970 ('', 'dots', None, _('use dots for runs')),
2000 ('', 'dots', None, _('use dots for runs')),
1971 ('s', 'spaces', None, _('separate elements by spaces'))],
2001 ('s', 'spaces', None, _('separate elements by spaces'))],
1972 _('[OPTION]... [FILE [REV]...]'),
2002 _('[OPTION]... [FILE [REV]...]'),
1973 optionalrepo=True)
2003 optionalrepo=True)
1974 def debugdag(ui, repo, file_=None, *revs, **opts):
2004 def debugdag(ui, repo, file_=None, *revs, **opts):
1975 """format the changelog or an index DAG as a concise textual description
2005 """format the changelog or an index DAG as a concise textual description
1976
2006
1977 If you pass a revlog index, the revlog's DAG is emitted. If you list
2007 If you pass a revlog index, the revlog's DAG is emitted. If you list
1978 revision numbers, they get labeled in the output as rN.
2008 revision numbers, they get labeled in the output as rN.
1979
2009
1980 Otherwise, the changelog DAG of the current repo is emitted.
2010 Otherwise, the changelog DAG of the current repo is emitted.
1981 """
2011 """
1982 spaces = opts.get('spaces')
2012 spaces = opts.get('spaces')
1983 dots = opts.get('dots')
2013 dots = opts.get('dots')
1984 if file_:
2014 if file_:
1985 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2015 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1986 revs = set((int(r) for r in revs))
2016 revs = set((int(r) for r in revs))
1987 def events():
2017 def events():
1988 for r in rlog:
2018 for r in rlog:
1989 yield 'n', (r, list(p for p in rlog.parentrevs(r)
2019 yield 'n', (r, list(p for p in rlog.parentrevs(r)
1990 if p != -1))
2020 if p != -1))
1991 if r in revs:
2021 if r in revs:
1992 yield 'l', (r, "r%i" % r)
2022 yield 'l', (r, "r%i" % r)
1993 elif repo:
2023 elif repo:
1994 cl = repo.changelog
2024 cl = repo.changelog
1995 tags = opts.get('tags')
2025 tags = opts.get('tags')
1996 branches = opts.get('branches')
2026 branches = opts.get('branches')
1997 if tags:
2027 if tags:
1998 labels = {}
2028 labels = {}
1999 for l, n in repo.tags().items():
2029 for l, n in repo.tags().items():
2000 labels.setdefault(cl.rev(n), []).append(l)
2030 labels.setdefault(cl.rev(n), []).append(l)
2001 def events():
2031 def events():
2002 b = "default"
2032 b = "default"
2003 for r in cl:
2033 for r in cl:
2004 if branches:
2034 if branches:
2005 newb = cl.read(cl.node(r))[5]['branch']
2035 newb = cl.read(cl.node(r))[5]['branch']
2006 if newb != b:
2036 if newb != b:
2007 yield 'a', newb
2037 yield 'a', newb
2008 b = newb
2038 b = newb
2009 yield 'n', (r, list(p for p in cl.parentrevs(r)
2039 yield 'n', (r, list(p for p in cl.parentrevs(r)
2010 if p != -1))
2040 if p != -1))
2011 if tags:
2041 if tags:
2012 ls = labels.get(r)
2042 ls = labels.get(r)
2013 if ls:
2043 if ls:
2014 for l in ls:
2044 for l in ls:
2015 yield 'l', (r, l)
2045 yield 'l', (r, l)
2016 else:
2046 else:
2017 raise util.Abort(_('need repo for changelog dag'))
2047 raise util.Abort(_('need repo for changelog dag'))
2018
2048
2019 for line in dagparser.dagtextlines(events(),
2049 for line in dagparser.dagtextlines(events(),
2020 addspaces=spaces,
2050 addspaces=spaces,
2021 wraplabels=True,
2051 wraplabels=True,
2022 wrapannotations=True,
2052 wrapannotations=True,
2023 wrapnonlinear=dots,
2053 wrapnonlinear=dots,
2024 usedots=dots,
2054 usedots=dots,
2025 maxlinewidth=70):
2055 maxlinewidth=70):
2026 ui.write(line)
2056 ui.write(line)
2027 ui.write("\n")
2057 ui.write("\n")
2028
2058
2029 @command('debugdata',
2059 @command('debugdata',
2030 [('c', 'changelog', False, _('open changelog')),
2060 [('c', 'changelog', False, _('open changelog')),
2031 ('m', 'manifest', False, _('open manifest'))],
2061 ('m', 'manifest', False, _('open manifest'))],
2032 _('-c|-m|FILE REV'))
2062 _('-c|-m|FILE REV'))
2033 def debugdata(ui, repo, file_, rev=None, **opts):
2063 def debugdata(ui, repo, file_, rev=None, **opts):
2034 """dump the contents of a data file revision"""
2064 """dump the contents of a data file revision"""
2035 if opts.get('changelog') or opts.get('manifest'):
2065 if opts.get('changelog') or opts.get('manifest'):
2036 file_, rev = None, file_
2066 file_, rev = None, file_
2037 elif rev is None:
2067 elif rev is None:
2038 raise error.CommandError('debugdata', _('invalid arguments'))
2068 raise error.CommandError('debugdata', _('invalid arguments'))
2039 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
2069 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
2040 try:
2070 try:
2041 ui.write(r.revision(r.lookup(rev)))
2071 ui.write(r.revision(r.lookup(rev)))
2042 except KeyError:
2072 except KeyError:
2043 raise util.Abort(_('invalid revision identifier %s') % rev)
2073 raise util.Abort(_('invalid revision identifier %s') % rev)
2044
2074
2045 @command('debugdate',
2075 @command('debugdate',
2046 [('e', 'extended', None, _('try extended date formats'))],
2076 [('e', 'extended', None, _('try extended date formats'))],
2047 _('[-e] DATE [RANGE]'),
2077 _('[-e] DATE [RANGE]'),
2048 norepo=True, optionalrepo=True)
2078 norepo=True, optionalrepo=True)
2049 def debugdate(ui, date, range=None, **opts):
2079 def debugdate(ui, date, range=None, **opts):
2050 """parse and display a date"""
2080 """parse and display a date"""
2051 if opts["extended"]:
2081 if opts["extended"]:
2052 d = util.parsedate(date, util.extendeddateformats)
2082 d = util.parsedate(date, util.extendeddateformats)
2053 else:
2083 else:
2054 d = util.parsedate(date)
2084 d = util.parsedate(date)
2055 ui.write(("internal: %s %s\n") % d)
2085 ui.write(("internal: %s %s\n") % d)
2056 ui.write(("standard: %s\n") % util.datestr(d))
2086 ui.write(("standard: %s\n") % util.datestr(d))
2057 if range:
2087 if range:
2058 m = util.matchdate(range)
2088 m = util.matchdate(range)
2059 ui.write(("match: %s\n") % m(d[0]))
2089 ui.write(("match: %s\n") % m(d[0]))
2060
2090
2061 @command('debugdiscovery',
2091 @command('debugdiscovery',
2062 [('', 'old', None, _('use old-style discovery')),
2092 [('', 'old', None, _('use old-style discovery')),
2063 ('', 'nonheads', None,
2093 ('', 'nonheads', None,
2064 _('use old-style discovery with non-heads included')),
2094 _('use old-style discovery with non-heads included')),
2065 ] + remoteopts,
2095 ] + remoteopts,
2066 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
2096 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
2067 def debugdiscovery(ui, repo, remoteurl="default", **opts):
2097 def debugdiscovery(ui, repo, remoteurl="default", **opts):
2068 """runs the changeset discovery protocol in isolation"""
2098 """runs the changeset discovery protocol in isolation"""
2069 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
2099 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
2070 opts.get('branch'))
2100 opts.get('branch'))
2071 remote = hg.peer(repo, opts, remoteurl)
2101 remote = hg.peer(repo, opts, remoteurl)
2072 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
2102 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
2073
2103
2074 # make sure tests are repeatable
2104 # make sure tests are repeatable
2075 random.seed(12323)
2105 random.seed(12323)
2076
2106
2077 def doit(localheads, remoteheads, remote=remote):
2107 def doit(localheads, remoteheads, remote=remote):
2078 if opts.get('old'):
2108 if opts.get('old'):
2079 if localheads:
2109 if localheads:
2080 raise util.Abort('cannot use localheads with old style '
2110 raise util.Abort('cannot use localheads with old style '
2081 'discovery')
2111 'discovery')
2082 if not util.safehasattr(remote, 'branches'):
2112 if not util.safehasattr(remote, 'branches'):
2083 # enable in-client legacy support
2113 # enable in-client legacy support
2084 remote = localrepo.locallegacypeer(remote.local())
2114 remote = localrepo.locallegacypeer(remote.local())
2085 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
2115 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
2086 force=True)
2116 force=True)
2087 common = set(common)
2117 common = set(common)
2088 if not opts.get('nonheads'):
2118 if not opts.get('nonheads'):
2089 ui.write(("unpruned common: %s\n") %
2119 ui.write(("unpruned common: %s\n") %
2090 " ".join(sorted(short(n) for n in common)))
2120 " ".join(sorted(short(n) for n in common)))
2091 dag = dagutil.revlogdag(repo.changelog)
2121 dag = dagutil.revlogdag(repo.changelog)
2092 all = dag.ancestorset(dag.internalizeall(common))
2122 all = dag.ancestorset(dag.internalizeall(common))
2093 common = dag.externalizeall(dag.headsetofconnecteds(all))
2123 common = dag.externalizeall(dag.headsetofconnecteds(all))
2094 else:
2124 else:
2095 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
2125 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
2096 common = set(common)
2126 common = set(common)
2097 rheads = set(hds)
2127 rheads = set(hds)
2098 lheads = set(repo.heads())
2128 lheads = set(repo.heads())
2099 ui.write(("common heads: %s\n") %
2129 ui.write(("common heads: %s\n") %
2100 " ".join(sorted(short(n) for n in common)))
2130 " ".join(sorted(short(n) for n in common)))
2101 if lheads <= common:
2131 if lheads <= common:
2102 ui.write(("local is subset\n"))
2132 ui.write(("local is subset\n"))
2103 elif rheads <= common:
2133 elif rheads <= common:
2104 ui.write(("remote is subset\n"))
2134 ui.write(("remote is subset\n"))
2105
2135
2106 serverlogs = opts.get('serverlog')
2136 serverlogs = opts.get('serverlog')
2107 if serverlogs:
2137 if serverlogs:
2108 for filename in serverlogs:
2138 for filename in serverlogs:
2109 logfile = open(filename, 'r')
2139 logfile = open(filename, 'r')
2110 try:
2140 try:
2111 line = logfile.readline()
2141 line = logfile.readline()
2112 while line:
2142 while line:
2113 parts = line.strip().split(';')
2143 parts = line.strip().split(';')
2114 op = parts[1]
2144 op = parts[1]
2115 if op == 'cg':
2145 if op == 'cg':
2116 pass
2146 pass
2117 elif op == 'cgss':
2147 elif op == 'cgss':
2118 doit(parts[2].split(' '), parts[3].split(' '))
2148 doit(parts[2].split(' '), parts[3].split(' '))
2119 elif op == 'unb':
2149 elif op == 'unb':
2120 doit(parts[3].split(' '), parts[2].split(' '))
2150 doit(parts[3].split(' '), parts[2].split(' '))
2121 line = logfile.readline()
2151 line = logfile.readline()
2122 finally:
2152 finally:
2123 logfile.close()
2153 logfile.close()
2124
2154
2125 else:
2155 else:
2126 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2156 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2127 opts.get('remote_head'))
2157 opts.get('remote_head'))
2128 localrevs = opts.get('local_head')
2158 localrevs = opts.get('local_head')
2129 doit(localrevs, remoterevs)
2159 doit(localrevs, remoterevs)
2130
2160
2131 @command('debugfileset',
2161 @command('debugfileset',
2132 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2162 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2133 _('[-r REV] FILESPEC'))
2163 _('[-r REV] FILESPEC'))
2134 def debugfileset(ui, repo, expr, **opts):
2164 def debugfileset(ui, repo, expr, **opts):
2135 '''parse and apply a fileset specification'''
2165 '''parse and apply a fileset specification'''
2136 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2166 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2137 if ui.verbose:
2167 if ui.verbose:
2138 tree = fileset.parse(expr)[0]
2168 tree = fileset.parse(expr)[0]
2139 ui.note(tree, "\n")
2169 ui.note(tree, "\n")
2140
2170
2141 for f in ctx.getfileset(expr):
2171 for f in ctx.getfileset(expr):
2142 ui.write("%s\n" % f)
2172 ui.write("%s\n" % f)
2143
2173
2144 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
2174 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
2145 def debugfsinfo(ui, path="."):
2175 def debugfsinfo(ui, path="."):
2146 """show information detected about current filesystem"""
2176 """show information detected about current filesystem"""
2147 util.writefile('.debugfsinfo', '')
2177 util.writefile('.debugfsinfo', '')
2148 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2178 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2149 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2179 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2150 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2180 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2151 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2181 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2152 and 'yes' or 'no'))
2182 and 'yes' or 'no'))
2153 os.unlink('.debugfsinfo')
2183 os.unlink('.debugfsinfo')
2154
2184
2155 @command('debuggetbundle',
2185 @command('debuggetbundle',
2156 [('H', 'head', [], _('id of head node'), _('ID')),
2186 [('H', 'head', [], _('id of head node'), _('ID')),
2157 ('C', 'common', [], _('id of common node'), _('ID')),
2187 ('C', 'common', [], _('id of common node'), _('ID')),
2158 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2188 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2159 _('REPO FILE [-H|-C ID]...'),
2189 _('REPO FILE [-H|-C ID]...'),
2160 norepo=True)
2190 norepo=True)
2161 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2191 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2162 """retrieves a bundle from a repo
2192 """retrieves a bundle from a repo
2163
2193
2164 Every ID must be a full-length hex node id string. Saves the bundle to the
2194 Every ID must be a full-length hex node id string. Saves the bundle to the
2165 given file.
2195 given file.
2166 """
2196 """
2167 repo = hg.peer(ui, opts, repopath)
2197 repo = hg.peer(ui, opts, repopath)
2168 if not repo.capable('getbundle'):
2198 if not repo.capable('getbundle'):
2169 raise util.Abort("getbundle() not supported by target repository")
2199 raise util.Abort("getbundle() not supported by target repository")
2170 args = {}
2200 args = {}
2171 if common:
2201 if common:
2172 args['common'] = [bin(s) for s in common]
2202 args['common'] = [bin(s) for s in common]
2173 if head:
2203 if head:
2174 args['heads'] = [bin(s) for s in head]
2204 args['heads'] = [bin(s) for s in head]
2175 # TODO: get desired bundlecaps from command line.
2205 # TODO: get desired bundlecaps from command line.
2176 args['bundlecaps'] = None
2206 args['bundlecaps'] = None
2177 bundle = repo.getbundle('debug', **args)
2207 bundle = repo.getbundle('debug', **args)
2178
2208
2179 bundletype = opts.get('type', 'bzip2').lower()
2209 bundletype = opts.get('type', 'bzip2').lower()
2180 btypes = {'none': 'HG10UN',
2210 btypes = {'none': 'HG10UN',
2181 'bzip2': 'HG10BZ',
2211 'bzip2': 'HG10BZ',
2182 'gzip': 'HG10GZ',
2212 'gzip': 'HG10GZ',
2183 'bundle2': 'HG2Y'}
2213 'bundle2': 'HG2Y'}
2184 bundletype = btypes.get(bundletype)
2214 bundletype = btypes.get(bundletype)
2185 if bundletype not in changegroup.bundletypes:
2215 if bundletype not in changegroup.bundletypes:
2186 raise util.Abort(_('unknown bundle type specified with --type'))
2216 raise util.Abort(_('unknown bundle type specified with --type'))
2187 changegroup.writebundle(ui, bundle, bundlepath, bundletype)
2217 changegroup.writebundle(ui, bundle, bundlepath, bundletype)
2188
2218
2189 @command('debugignore', [], '')
2219 @command('debugignore', [], '')
2190 def debugignore(ui, repo, *values, **opts):
2220 def debugignore(ui, repo, *values, **opts):
2191 """display the combined ignore pattern"""
2221 """display the combined ignore pattern"""
2192 ignore = repo.dirstate._ignore
2222 ignore = repo.dirstate._ignore
2193 includepat = getattr(ignore, 'includepat', None)
2223 includepat = getattr(ignore, 'includepat', None)
2194 if includepat is not None:
2224 if includepat is not None:
2195 ui.write("%s\n" % includepat)
2225 ui.write("%s\n" % includepat)
2196 else:
2226 else:
2197 raise util.Abort(_("no ignore patterns found"))
2227 raise util.Abort(_("no ignore patterns found"))
2198
2228
2199 @command('debugindex',
2229 @command('debugindex',
2200 [('c', 'changelog', False, _('open changelog')),
2230 [('c', 'changelog', False, _('open changelog')),
2201 ('m', 'manifest', False, _('open manifest')),
2231 ('m', 'manifest', False, _('open manifest')),
2202 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2232 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2203 _('[-f FORMAT] -c|-m|FILE'),
2233 _('[-f FORMAT] -c|-m|FILE'),
2204 optionalrepo=True)
2234 optionalrepo=True)
2205 def debugindex(ui, repo, file_=None, **opts):
2235 def debugindex(ui, repo, file_=None, **opts):
2206 """dump the contents of an index file"""
2236 """dump the contents of an index file"""
2207 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2237 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2208 format = opts.get('format', 0)
2238 format = opts.get('format', 0)
2209 if format not in (0, 1):
2239 if format not in (0, 1):
2210 raise util.Abort(_("unknown format %d") % format)
2240 raise util.Abort(_("unknown format %d") % format)
2211
2241
2212 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2242 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2213 if generaldelta:
2243 if generaldelta:
2214 basehdr = ' delta'
2244 basehdr = ' delta'
2215 else:
2245 else:
2216 basehdr = ' base'
2246 basehdr = ' base'
2217
2247
2218 if ui.debugflag:
2248 if ui.debugflag:
2219 shortfn = hex
2249 shortfn = hex
2220 else:
2250 else:
2221 shortfn = short
2251 shortfn = short
2222
2252
2223 # There might not be anything in r, so have a sane default
2253 # There might not be anything in r, so have a sane default
2224 idlen = 12
2254 idlen = 12
2225 for i in r:
2255 for i in r:
2226 idlen = len(shortfn(r.node(i)))
2256 idlen = len(shortfn(r.node(i)))
2227 break
2257 break
2228
2258
2229 if format == 0:
2259 if format == 0:
2230 ui.write(" rev offset length " + basehdr + " linkrev"
2260 ui.write(" rev offset length " + basehdr + " linkrev"
2231 " %s %s p2\n" % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
2261 " %s %s p2\n" % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
2232 elif format == 1:
2262 elif format == 1:
2233 ui.write(" rev flag offset length"
2263 ui.write(" rev flag offset length"
2234 " size " + basehdr + " link p1 p2"
2264 " size " + basehdr + " link p1 p2"
2235 " %s\n" % "nodeid".rjust(idlen))
2265 " %s\n" % "nodeid".rjust(idlen))
2236
2266
2237 for i in r:
2267 for i in r:
2238 node = r.node(i)
2268 node = r.node(i)
2239 if generaldelta:
2269 if generaldelta:
2240 base = r.deltaparent(i)
2270 base = r.deltaparent(i)
2241 else:
2271 else:
2242 base = r.chainbase(i)
2272 base = r.chainbase(i)
2243 if format == 0:
2273 if format == 0:
2244 try:
2274 try:
2245 pp = r.parents(node)
2275 pp = r.parents(node)
2246 except Exception:
2276 except Exception:
2247 pp = [nullid, nullid]
2277 pp = [nullid, nullid]
2248 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2278 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2249 i, r.start(i), r.length(i), base, r.linkrev(i),
2279 i, r.start(i), r.length(i), base, r.linkrev(i),
2250 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
2280 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
2251 elif format == 1:
2281 elif format == 1:
2252 pr = r.parentrevs(i)
2282 pr = r.parentrevs(i)
2253 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2283 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2254 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2284 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2255 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
2285 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
2256
2286
2257 @command('debugindexdot', [], _('FILE'), optionalrepo=True)
2287 @command('debugindexdot', [], _('FILE'), optionalrepo=True)
2258 def debugindexdot(ui, repo, file_):
2288 def debugindexdot(ui, repo, file_):
2259 """dump an index DAG as a graphviz dot file"""
2289 """dump an index DAG as a graphviz dot file"""
2260 r = None
2290 r = None
2261 if repo:
2291 if repo:
2262 filelog = repo.file(file_)
2292 filelog = repo.file(file_)
2263 if len(filelog):
2293 if len(filelog):
2264 r = filelog
2294 r = filelog
2265 if not r:
2295 if not r:
2266 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2296 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2267 ui.write(("digraph G {\n"))
2297 ui.write(("digraph G {\n"))
2268 for i in r:
2298 for i in r:
2269 node = r.node(i)
2299 node = r.node(i)
2270 pp = r.parents(node)
2300 pp = r.parents(node)
2271 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2301 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2272 if pp[1] != nullid:
2302 if pp[1] != nullid:
2273 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2303 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2274 ui.write("}\n")
2304 ui.write("}\n")
2275
2305
2276 @command('debuginstall', [], '', norepo=True)
2306 @command('debuginstall', [], '', norepo=True)
2277 def debuginstall(ui):
2307 def debuginstall(ui):
2278 '''test Mercurial installation
2308 '''test Mercurial installation
2279
2309
2280 Returns 0 on success.
2310 Returns 0 on success.
2281 '''
2311 '''
2282
2312
2283 def writetemp(contents):
2313 def writetemp(contents):
2284 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2314 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2285 f = os.fdopen(fd, "wb")
2315 f = os.fdopen(fd, "wb")
2286 f.write(contents)
2316 f.write(contents)
2287 f.close()
2317 f.close()
2288 return name
2318 return name
2289
2319
2290 problems = 0
2320 problems = 0
2291
2321
2292 # encoding
2322 # encoding
2293 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2323 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2294 try:
2324 try:
2295 encoding.fromlocal("test")
2325 encoding.fromlocal("test")
2296 except util.Abort, inst:
2326 except util.Abort, inst:
2297 ui.write(" %s\n" % inst)
2327 ui.write(" %s\n" % inst)
2298 ui.write(_(" (check that your locale is properly set)\n"))
2328 ui.write(_(" (check that your locale is properly set)\n"))
2299 problems += 1
2329 problems += 1
2300
2330
2301 # Python
2331 # Python
2302 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2332 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2303 ui.status(_("checking Python version (%s)\n")
2333 ui.status(_("checking Python version (%s)\n")
2304 % ("%s.%s.%s" % sys.version_info[:3]))
2334 % ("%s.%s.%s" % sys.version_info[:3]))
2305 ui.status(_("checking Python lib (%s)...\n")
2335 ui.status(_("checking Python lib (%s)...\n")
2306 % os.path.dirname(os.__file__))
2336 % os.path.dirname(os.__file__))
2307
2337
2308 # compiled modules
2338 # compiled modules
2309 ui.status(_("checking installed modules (%s)...\n")
2339 ui.status(_("checking installed modules (%s)...\n")
2310 % os.path.dirname(__file__))
2340 % os.path.dirname(__file__))
2311 try:
2341 try:
2312 import bdiff, mpatch, base85, osutil
2342 import bdiff, mpatch, base85, osutil
2313 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2343 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2314 except Exception, inst:
2344 except Exception, inst:
2315 ui.write(" %s\n" % inst)
2345 ui.write(" %s\n" % inst)
2316 ui.write(_(" One or more extensions could not be found"))
2346 ui.write(_(" One or more extensions could not be found"))
2317 ui.write(_(" (check that you compiled the extensions)\n"))
2347 ui.write(_(" (check that you compiled the extensions)\n"))
2318 problems += 1
2348 problems += 1
2319
2349
2320 # templates
2350 # templates
2321 import templater
2351 import templater
2322 p = templater.templatepaths()
2352 p = templater.templatepaths()
2323 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2353 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2324 if p:
2354 if p:
2325 m = templater.templatepath("map-cmdline.default")
2355 m = templater.templatepath("map-cmdline.default")
2326 if m:
2356 if m:
2327 # template found, check if it is working
2357 # template found, check if it is working
2328 try:
2358 try:
2329 templater.templater(m)
2359 templater.templater(m)
2330 except Exception, inst:
2360 except Exception, inst:
2331 ui.write(" %s\n" % inst)
2361 ui.write(" %s\n" % inst)
2332 p = None
2362 p = None
2333 else:
2363 else:
2334 ui.write(_(" template 'default' not found\n"))
2364 ui.write(_(" template 'default' not found\n"))
2335 p = None
2365 p = None
2336 else:
2366 else:
2337 ui.write(_(" no template directories found\n"))
2367 ui.write(_(" no template directories found\n"))
2338 if not p:
2368 if not p:
2339 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2369 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2340 problems += 1
2370 problems += 1
2341
2371
2342 # editor
2372 # editor
2343 ui.status(_("checking commit editor...\n"))
2373 ui.status(_("checking commit editor...\n"))
2344 editor = ui.geteditor()
2374 editor = ui.geteditor()
2345 cmdpath = util.findexe(shlex.split(editor)[0])
2375 cmdpath = util.findexe(shlex.split(editor)[0])
2346 if not cmdpath:
2376 if not cmdpath:
2347 if editor == 'vi':
2377 if editor == 'vi':
2348 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2378 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2349 ui.write(_(" (specify a commit editor in your configuration"
2379 ui.write(_(" (specify a commit editor in your configuration"
2350 " file)\n"))
2380 " file)\n"))
2351 else:
2381 else:
2352 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2382 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2353 ui.write(_(" (specify a commit editor in your configuration"
2383 ui.write(_(" (specify a commit editor in your configuration"
2354 " file)\n"))
2384 " file)\n"))
2355 problems += 1
2385 problems += 1
2356
2386
2357 # check username
2387 # check username
2358 ui.status(_("checking username...\n"))
2388 ui.status(_("checking username...\n"))
2359 try:
2389 try:
2360 ui.username()
2390 ui.username()
2361 except util.Abort, e:
2391 except util.Abort, e:
2362 ui.write(" %s\n" % e)
2392 ui.write(" %s\n" % e)
2363 ui.write(_(" (specify a username in your configuration file)\n"))
2393 ui.write(_(" (specify a username in your configuration file)\n"))
2364 problems += 1
2394 problems += 1
2365
2395
2366 if not problems:
2396 if not problems:
2367 ui.status(_("no problems detected\n"))
2397 ui.status(_("no problems detected\n"))
2368 else:
2398 else:
2369 ui.write(_("%s problems detected,"
2399 ui.write(_("%s problems detected,"
2370 " please check your install!\n") % problems)
2400 " please check your install!\n") % problems)
2371
2401
2372 return problems
2402 return problems
2373
2403
2374 @command('debugknown', [], _('REPO ID...'), norepo=True)
2404 @command('debugknown', [], _('REPO ID...'), norepo=True)
2375 def debugknown(ui, repopath, *ids, **opts):
2405 def debugknown(ui, repopath, *ids, **opts):
2376 """test whether node ids are known to a repo
2406 """test whether node ids are known to a repo
2377
2407
2378 Every ID must be a full-length hex node id string. Returns a list of 0s
2408 Every ID must be a full-length hex node id string. Returns a list of 0s
2379 and 1s indicating unknown/known.
2409 and 1s indicating unknown/known.
2380 """
2410 """
2381 repo = hg.peer(ui, opts, repopath)
2411 repo = hg.peer(ui, opts, repopath)
2382 if not repo.capable('known'):
2412 if not repo.capable('known'):
2383 raise util.Abort("known() not supported by target repository")
2413 raise util.Abort("known() not supported by target repository")
2384 flags = repo.known([bin(s) for s in ids])
2414 flags = repo.known([bin(s) for s in ids])
2385 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2415 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2386
2416
2387 @command('debuglabelcomplete', [], _('LABEL...'))
2417 @command('debuglabelcomplete', [], _('LABEL...'))
2388 def debuglabelcomplete(ui, repo, *args):
2418 def debuglabelcomplete(ui, repo, *args):
2389 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2419 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2390 debugnamecomplete(ui, repo, *args)
2420 debugnamecomplete(ui, repo, *args)
2391
2421
2392 @command('debugnamecomplete', [], _('NAME...'))
2422 @command('debugnamecomplete', [], _('NAME...'))
2393 def debugnamecomplete(ui, repo, *args):
2423 def debugnamecomplete(ui, repo, *args):
2394 '''complete "names" - tags, open branch names, bookmark names'''
2424 '''complete "names" - tags, open branch names, bookmark names'''
2395
2425
2396 names = set()
2426 names = set()
2397 # since we previously only listed open branches, we will handle that
2427 # since we previously only listed open branches, we will handle that
2398 # specially (after this for loop)
2428 # specially (after this for loop)
2399 for name, ns in repo.names.iteritems():
2429 for name, ns in repo.names.iteritems():
2400 if name != 'branches':
2430 if name != 'branches':
2401 names.update(ns.listnames(repo))
2431 names.update(ns.listnames(repo))
2402 names.update(tag for (tag, heads, tip, closed)
2432 names.update(tag for (tag, heads, tip, closed)
2403 in repo.branchmap().iterbranches() if not closed)
2433 in repo.branchmap().iterbranches() if not closed)
2404 completions = set()
2434 completions = set()
2405 if not args:
2435 if not args:
2406 args = ['']
2436 args = ['']
2407 for a in args:
2437 for a in args:
2408 completions.update(n for n in names if n.startswith(a))
2438 completions.update(n for n in names if n.startswith(a))
2409 ui.write('\n'.join(sorted(completions)))
2439 ui.write('\n'.join(sorted(completions)))
2410 ui.write('\n')
2440 ui.write('\n')
2411
2441
2412 @command('debuglocks',
2442 @command('debuglocks',
2413 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
2443 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
2414 ('W', 'force-wlock', None,
2444 ('W', 'force-wlock', None,
2415 _('free the working state lock (DANGEROUS)'))],
2445 _('free the working state lock (DANGEROUS)'))],
2416 _('[OPTION]...'))
2446 _('[OPTION]...'))
2417 def debuglocks(ui, repo, **opts):
2447 def debuglocks(ui, repo, **opts):
2418 """show or modify state of locks
2448 """show or modify state of locks
2419
2449
2420 By default, this command will show which locks are held. This
2450 By default, this command will show which locks are held. This
2421 includes the user and process holding the lock, the amount of time
2451 includes the user and process holding the lock, the amount of time
2422 the lock has been held, and the machine name where the process is
2452 the lock has been held, and the machine name where the process is
2423 running if it's not local.
2453 running if it's not local.
2424
2454
2425 Locks protect the integrity of Mercurial's data, so should be
2455 Locks protect the integrity of Mercurial's data, so should be
2426 treated with care. System crashes or other interruptions may cause
2456 treated with care. System crashes or other interruptions may cause
2427 locks to not be properly released, though Mercurial will usually
2457 locks to not be properly released, though Mercurial will usually
2428 detect and remove such stale locks automatically.
2458 detect and remove such stale locks automatically.
2429
2459
2430 However, detecting stale locks may not always be possible (for
2460 However, detecting stale locks may not always be possible (for
2431 instance, on a shared filesystem). Removing locks may also be
2461 instance, on a shared filesystem). Removing locks may also be
2432 blocked by filesystem permissions.
2462 blocked by filesystem permissions.
2433
2463
2434 Returns 0 if no locks are held.
2464 Returns 0 if no locks are held.
2435
2465
2436 """
2466 """
2437
2467
2438 if opts.get('force_lock'):
2468 if opts.get('force_lock'):
2439 repo.svfs.unlink('lock')
2469 repo.svfs.unlink('lock')
2440 if opts.get('force_wlock'):
2470 if opts.get('force_wlock'):
2441 repo.vfs.unlink('wlock')
2471 repo.vfs.unlink('wlock')
2442 if opts.get('force_lock') or opts.get('force_lock'):
2472 if opts.get('force_lock') or opts.get('force_lock'):
2443 return 0
2473 return 0
2444
2474
2445 now = time.time()
2475 now = time.time()
2446 held = 0
2476 held = 0
2447
2477
2448 def report(vfs, name, method):
2478 def report(vfs, name, method):
2449 # this causes stale locks to get reaped for more accurate reporting
2479 # this causes stale locks to get reaped for more accurate reporting
2450 try:
2480 try:
2451 l = method(False)
2481 l = method(False)
2452 except error.LockHeld:
2482 except error.LockHeld:
2453 l = None
2483 l = None
2454
2484
2455 if l:
2485 if l:
2456 l.release()
2486 l.release()
2457 else:
2487 else:
2458 try:
2488 try:
2459 stat = repo.svfs.lstat(name)
2489 stat = repo.svfs.lstat(name)
2460 age = now - stat.st_mtime
2490 age = now - stat.st_mtime
2461 user = util.username(stat.st_uid)
2491 user = util.username(stat.st_uid)
2462 locker = vfs.readlock(name)
2492 locker = vfs.readlock(name)
2463 if ":" in locker:
2493 if ":" in locker:
2464 host, pid = locker.split(':')
2494 host, pid = locker.split(':')
2465 if host == socket.gethostname():
2495 if host == socket.gethostname():
2466 locker = 'user %s, process %s' % (user, pid)
2496 locker = 'user %s, process %s' % (user, pid)
2467 else:
2497 else:
2468 locker = 'user %s, process %s, host %s' \
2498 locker = 'user %s, process %s, host %s' \
2469 % (user, pid, host)
2499 % (user, pid, host)
2470 ui.write("%-6s %s (%ds)\n" % (name + ":", locker, age))
2500 ui.write("%-6s %s (%ds)\n" % (name + ":", locker, age))
2471 return 1
2501 return 1
2472 except OSError, e:
2502 except OSError, e:
2473 if e.errno != errno.ENOENT:
2503 if e.errno != errno.ENOENT:
2474 raise
2504 raise
2475
2505
2476 ui.write("%-6s free\n" % (name + ":"))
2506 ui.write("%-6s free\n" % (name + ":"))
2477 return 0
2507 return 0
2478
2508
2479 held += report(repo.svfs, "lock", repo.lock)
2509 held += report(repo.svfs, "lock", repo.lock)
2480 held += report(repo.vfs, "wlock", repo.wlock)
2510 held += report(repo.vfs, "wlock", repo.wlock)
2481
2511
2482 return held
2512 return held
2483
2513
2484 @command('debugobsolete',
2514 @command('debugobsolete',
2485 [('', 'flags', 0, _('markers flag')),
2515 [('', 'flags', 0, _('markers flag')),
2486 ('', 'record-parents', False,
2516 ('', 'record-parents', False,
2487 _('record parent information for the precursor')),
2517 _('record parent information for the precursor')),
2488 ('r', 'rev', [], _('display markers relevant to REV')),
2518 ('r', 'rev', [], _('display markers relevant to REV')),
2489 ] + commitopts2,
2519 ] + commitopts2,
2490 _('[OBSOLETED [REPLACEMENT] [REPL... ]'))
2520 _('[OBSOLETED [REPLACEMENT] [REPL... ]'))
2491 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2521 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2492 """create arbitrary obsolete marker
2522 """create arbitrary obsolete marker
2493
2523
2494 With no arguments, displays the list of obsolescence markers."""
2524 With no arguments, displays the list of obsolescence markers."""
2495
2525
2496 def parsenodeid(s):
2526 def parsenodeid(s):
2497 try:
2527 try:
2498 # We do not use revsingle/revrange functions here to accept
2528 # We do not use revsingle/revrange functions here to accept
2499 # arbitrary node identifiers, possibly not present in the
2529 # arbitrary node identifiers, possibly not present in the
2500 # local repository.
2530 # local repository.
2501 n = bin(s)
2531 n = bin(s)
2502 if len(n) != len(nullid):
2532 if len(n) != len(nullid):
2503 raise TypeError()
2533 raise TypeError()
2504 return n
2534 return n
2505 except TypeError:
2535 except TypeError:
2506 raise util.Abort('changeset references must be full hexadecimal '
2536 raise util.Abort('changeset references must be full hexadecimal '
2507 'node identifiers')
2537 'node identifiers')
2508
2538
2509 if precursor is not None:
2539 if precursor is not None:
2510 if opts['rev']:
2540 if opts['rev']:
2511 raise util.Abort('cannot select revision when creating marker')
2541 raise util.Abort('cannot select revision when creating marker')
2512 metadata = {}
2542 metadata = {}
2513 metadata['user'] = opts['user'] or ui.username()
2543 metadata['user'] = opts['user'] or ui.username()
2514 succs = tuple(parsenodeid(succ) for succ in successors)
2544 succs = tuple(parsenodeid(succ) for succ in successors)
2515 l = repo.lock()
2545 l = repo.lock()
2516 try:
2546 try:
2517 tr = repo.transaction('debugobsolete')
2547 tr = repo.transaction('debugobsolete')
2518 try:
2548 try:
2519 try:
2549 try:
2520 date = opts.get('date')
2550 date = opts.get('date')
2521 if date:
2551 if date:
2522 date = util.parsedate(date)
2552 date = util.parsedate(date)
2523 else:
2553 else:
2524 date = None
2554 date = None
2525 prec = parsenodeid(precursor)
2555 prec = parsenodeid(precursor)
2526 parents = None
2556 parents = None
2527 if opts['record_parents']:
2557 if opts['record_parents']:
2528 if prec not in repo.unfiltered():
2558 if prec not in repo.unfiltered():
2529 raise util.Abort('cannot used --record-parents on '
2559 raise util.Abort('cannot used --record-parents on '
2530 'unknown changesets')
2560 'unknown changesets')
2531 parents = repo.unfiltered()[prec].parents()
2561 parents = repo.unfiltered()[prec].parents()
2532 parents = tuple(p.node() for p in parents)
2562 parents = tuple(p.node() for p in parents)
2533 repo.obsstore.create(tr, prec, succs, opts['flags'],
2563 repo.obsstore.create(tr, prec, succs, opts['flags'],
2534 parents=parents, date=date,
2564 parents=parents, date=date,
2535 metadata=metadata)
2565 metadata=metadata)
2536 tr.close()
2566 tr.close()
2537 except ValueError, exc:
2567 except ValueError, exc:
2538 raise util.Abort(_('bad obsmarker input: %s') % exc)
2568 raise util.Abort(_('bad obsmarker input: %s') % exc)
2539 finally:
2569 finally:
2540 tr.release()
2570 tr.release()
2541 finally:
2571 finally:
2542 l.release()
2572 l.release()
2543 else:
2573 else:
2544 if opts['rev']:
2574 if opts['rev']:
2545 revs = scmutil.revrange(repo, opts['rev'])
2575 revs = scmutil.revrange(repo, opts['rev'])
2546 nodes = [repo[r].node() for r in revs]
2576 nodes = [repo[r].node() for r in revs]
2547 markers = list(obsolete.getmarkers(repo, nodes=nodes))
2577 markers = list(obsolete.getmarkers(repo, nodes=nodes))
2548 markers.sort(key=lambda x: x._data)
2578 markers.sort(key=lambda x: x._data)
2549 else:
2579 else:
2550 markers = obsolete.getmarkers(repo)
2580 markers = obsolete.getmarkers(repo)
2551
2581
2552 for m in markers:
2582 for m in markers:
2553 cmdutil.showmarker(ui, m)
2583 cmdutil.showmarker(ui, m)
2554
2584
2555 @command('debugpathcomplete',
2585 @command('debugpathcomplete',
2556 [('f', 'full', None, _('complete an entire path')),
2586 [('f', 'full', None, _('complete an entire path')),
2557 ('n', 'normal', None, _('show only normal files')),
2587 ('n', 'normal', None, _('show only normal files')),
2558 ('a', 'added', None, _('show only added files')),
2588 ('a', 'added', None, _('show only added files')),
2559 ('r', 'removed', None, _('show only removed files'))],
2589 ('r', 'removed', None, _('show only removed files'))],
2560 _('FILESPEC...'))
2590 _('FILESPEC...'))
2561 def debugpathcomplete(ui, repo, *specs, **opts):
2591 def debugpathcomplete(ui, repo, *specs, **opts):
2562 '''complete part or all of a tracked path
2592 '''complete part or all of a tracked path
2563
2593
2564 This command supports shells that offer path name completion. It
2594 This command supports shells that offer path name completion. It
2565 currently completes only files already known to the dirstate.
2595 currently completes only files already known to the dirstate.
2566
2596
2567 Completion extends only to the next path segment unless
2597 Completion extends only to the next path segment unless
2568 --full is specified, in which case entire paths are used.'''
2598 --full is specified, in which case entire paths are used.'''
2569
2599
2570 def complete(path, acceptable):
2600 def complete(path, acceptable):
2571 dirstate = repo.dirstate
2601 dirstate = repo.dirstate
2572 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2602 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2573 rootdir = repo.root + os.sep
2603 rootdir = repo.root + os.sep
2574 if spec != repo.root and not spec.startswith(rootdir):
2604 if spec != repo.root and not spec.startswith(rootdir):
2575 return [], []
2605 return [], []
2576 if os.path.isdir(spec):
2606 if os.path.isdir(spec):
2577 spec += '/'
2607 spec += '/'
2578 spec = spec[len(rootdir):]
2608 spec = spec[len(rootdir):]
2579 fixpaths = os.sep != '/'
2609 fixpaths = os.sep != '/'
2580 if fixpaths:
2610 if fixpaths:
2581 spec = spec.replace(os.sep, '/')
2611 spec = spec.replace(os.sep, '/')
2582 speclen = len(spec)
2612 speclen = len(spec)
2583 fullpaths = opts['full']
2613 fullpaths = opts['full']
2584 files, dirs = set(), set()
2614 files, dirs = set(), set()
2585 adddir, addfile = dirs.add, files.add
2615 adddir, addfile = dirs.add, files.add
2586 for f, st in dirstate.iteritems():
2616 for f, st in dirstate.iteritems():
2587 if f.startswith(spec) and st[0] in acceptable:
2617 if f.startswith(spec) and st[0] in acceptable:
2588 if fixpaths:
2618 if fixpaths:
2589 f = f.replace('/', os.sep)
2619 f = f.replace('/', os.sep)
2590 if fullpaths:
2620 if fullpaths:
2591 addfile(f)
2621 addfile(f)
2592 continue
2622 continue
2593 s = f.find(os.sep, speclen)
2623 s = f.find(os.sep, speclen)
2594 if s >= 0:
2624 if s >= 0:
2595 adddir(f[:s])
2625 adddir(f[:s])
2596 else:
2626 else:
2597 addfile(f)
2627 addfile(f)
2598 return files, dirs
2628 return files, dirs
2599
2629
2600 acceptable = ''
2630 acceptable = ''
2601 if opts['normal']:
2631 if opts['normal']:
2602 acceptable += 'nm'
2632 acceptable += 'nm'
2603 if opts['added']:
2633 if opts['added']:
2604 acceptable += 'a'
2634 acceptable += 'a'
2605 if opts['removed']:
2635 if opts['removed']:
2606 acceptable += 'r'
2636 acceptable += 'r'
2607 cwd = repo.getcwd()
2637 cwd = repo.getcwd()
2608 if not specs:
2638 if not specs:
2609 specs = ['.']
2639 specs = ['.']
2610
2640
2611 files, dirs = set(), set()
2641 files, dirs = set(), set()
2612 for spec in specs:
2642 for spec in specs:
2613 f, d = complete(spec, acceptable or 'nmar')
2643 f, d = complete(spec, acceptable or 'nmar')
2614 files.update(f)
2644 files.update(f)
2615 dirs.update(d)
2645 dirs.update(d)
2616 files.update(dirs)
2646 files.update(dirs)
2617 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2647 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2618 ui.write('\n')
2648 ui.write('\n')
2619
2649
2620 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2650 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2621 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2651 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2622 '''access the pushkey key/value protocol
2652 '''access the pushkey key/value protocol
2623
2653
2624 With two args, list the keys in the given namespace.
2654 With two args, list the keys in the given namespace.
2625
2655
2626 With five args, set a key to new if it currently is set to old.
2656 With five args, set a key to new if it currently is set to old.
2627 Reports success or failure.
2657 Reports success or failure.
2628 '''
2658 '''
2629
2659
2630 target = hg.peer(ui, {}, repopath)
2660 target = hg.peer(ui, {}, repopath)
2631 if keyinfo:
2661 if keyinfo:
2632 key, old, new = keyinfo
2662 key, old, new = keyinfo
2633 r = target.pushkey(namespace, key, old, new)
2663 r = target.pushkey(namespace, key, old, new)
2634 ui.status(str(r) + '\n')
2664 ui.status(str(r) + '\n')
2635 return not r
2665 return not r
2636 else:
2666 else:
2637 for k, v in sorted(target.listkeys(namespace).iteritems()):
2667 for k, v in sorted(target.listkeys(namespace).iteritems()):
2638 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2668 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2639 v.encode('string-escape')))
2669 v.encode('string-escape')))
2640
2670
2641 @command('debugpvec', [], _('A B'))
2671 @command('debugpvec', [], _('A B'))
2642 def debugpvec(ui, repo, a, b=None):
2672 def debugpvec(ui, repo, a, b=None):
2643 ca = scmutil.revsingle(repo, a)
2673 ca = scmutil.revsingle(repo, a)
2644 cb = scmutil.revsingle(repo, b)
2674 cb = scmutil.revsingle(repo, b)
2645 pa = pvec.ctxpvec(ca)
2675 pa = pvec.ctxpvec(ca)
2646 pb = pvec.ctxpvec(cb)
2676 pb = pvec.ctxpvec(cb)
2647 if pa == pb:
2677 if pa == pb:
2648 rel = "="
2678 rel = "="
2649 elif pa > pb:
2679 elif pa > pb:
2650 rel = ">"
2680 rel = ">"
2651 elif pa < pb:
2681 elif pa < pb:
2652 rel = "<"
2682 rel = "<"
2653 elif pa | pb:
2683 elif pa | pb:
2654 rel = "|"
2684 rel = "|"
2655 ui.write(_("a: %s\n") % pa)
2685 ui.write(_("a: %s\n") % pa)
2656 ui.write(_("b: %s\n") % pb)
2686 ui.write(_("b: %s\n") % pb)
2657 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2687 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2658 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2688 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2659 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2689 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2660 pa.distance(pb), rel))
2690 pa.distance(pb), rel))
2661
2691
2662 @command('debugrebuilddirstate|debugrebuildstate',
2692 @command('debugrebuilddirstate|debugrebuildstate',
2663 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
2693 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
2664 _('[-r REV]'))
2694 _('[-r REV]'))
2665 def debugrebuilddirstate(ui, repo, rev):
2695 def debugrebuilddirstate(ui, repo, rev):
2666 """rebuild the dirstate as it would look like for the given revision
2696 """rebuild the dirstate as it would look like for the given revision
2667
2697
2668 If no revision is specified the first current parent will be used.
2698 If no revision is specified the first current parent will be used.
2669
2699
2670 The dirstate will be set to the files of the given revision.
2700 The dirstate will be set to the files of the given revision.
2671 The actual working directory content or existing dirstate
2701 The actual working directory content or existing dirstate
2672 information such as adds or removes is not considered.
2702 information such as adds or removes is not considered.
2673
2703
2674 One use of this command is to make the next :hg:`status` invocation
2704 One use of this command is to make the next :hg:`status` invocation
2675 check the actual file content.
2705 check the actual file content.
2676 """
2706 """
2677 ctx = scmutil.revsingle(repo, rev)
2707 ctx = scmutil.revsingle(repo, rev)
2678 wlock = repo.wlock()
2708 wlock = repo.wlock()
2679 try:
2709 try:
2680 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
2710 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
2681 finally:
2711 finally:
2682 wlock.release()
2712 wlock.release()
2683
2713
2684 @command('debugrename',
2714 @command('debugrename',
2685 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2715 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2686 _('[-r REV] FILE'))
2716 _('[-r REV] FILE'))
2687 def debugrename(ui, repo, file1, *pats, **opts):
2717 def debugrename(ui, repo, file1, *pats, **opts):
2688 """dump rename information"""
2718 """dump rename information"""
2689
2719
2690 ctx = scmutil.revsingle(repo, opts.get('rev'))
2720 ctx = scmutil.revsingle(repo, opts.get('rev'))
2691 m = scmutil.match(ctx, (file1,) + pats, opts)
2721 m = scmutil.match(ctx, (file1,) + pats, opts)
2692 for abs in ctx.walk(m):
2722 for abs in ctx.walk(m):
2693 fctx = ctx[abs]
2723 fctx = ctx[abs]
2694 o = fctx.filelog().renamed(fctx.filenode())
2724 o = fctx.filelog().renamed(fctx.filenode())
2695 rel = m.rel(abs)
2725 rel = m.rel(abs)
2696 if o:
2726 if o:
2697 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2727 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2698 else:
2728 else:
2699 ui.write(_("%s not renamed\n") % rel)
2729 ui.write(_("%s not renamed\n") % rel)
2700
2730
2701 @command('debugrevlog',
2731 @command('debugrevlog',
2702 [('c', 'changelog', False, _('open changelog')),
2732 [('c', 'changelog', False, _('open changelog')),
2703 ('m', 'manifest', False, _('open manifest')),
2733 ('m', 'manifest', False, _('open manifest')),
2704 ('d', 'dump', False, _('dump index data'))],
2734 ('d', 'dump', False, _('dump index data'))],
2705 _('-c|-m|FILE'),
2735 _('-c|-m|FILE'),
2706 optionalrepo=True)
2736 optionalrepo=True)
2707 def debugrevlog(ui, repo, file_=None, **opts):
2737 def debugrevlog(ui, repo, file_=None, **opts):
2708 """show data and statistics about a revlog"""
2738 """show data and statistics about a revlog"""
2709 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2739 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2710
2740
2711 if opts.get("dump"):
2741 if opts.get("dump"):
2712 numrevs = len(r)
2742 numrevs = len(r)
2713 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2743 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2714 " rawsize totalsize compression heads chainlen\n")
2744 " rawsize totalsize compression heads chainlen\n")
2715 ts = 0
2745 ts = 0
2716 heads = set()
2746 heads = set()
2717
2747
2718 for rev in xrange(numrevs):
2748 for rev in xrange(numrevs):
2719 dbase = r.deltaparent(rev)
2749 dbase = r.deltaparent(rev)
2720 if dbase == -1:
2750 if dbase == -1:
2721 dbase = rev
2751 dbase = rev
2722 cbase = r.chainbase(rev)
2752 cbase = r.chainbase(rev)
2723 clen = r.chainlen(rev)
2753 clen = r.chainlen(rev)
2724 p1, p2 = r.parentrevs(rev)
2754 p1, p2 = r.parentrevs(rev)
2725 rs = r.rawsize(rev)
2755 rs = r.rawsize(rev)
2726 ts = ts + rs
2756 ts = ts + rs
2727 heads -= set(r.parentrevs(rev))
2757 heads -= set(r.parentrevs(rev))
2728 heads.add(rev)
2758 heads.add(rev)
2729 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2759 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2730 "%11d %5d %8d\n" %
2760 "%11d %5d %8d\n" %
2731 (rev, p1, p2, r.start(rev), r.end(rev),
2761 (rev, p1, p2, r.start(rev), r.end(rev),
2732 r.start(dbase), r.start(cbase),
2762 r.start(dbase), r.start(cbase),
2733 r.start(p1), r.start(p2),
2763 r.start(p1), r.start(p2),
2734 rs, ts, ts / r.end(rev), len(heads), clen))
2764 rs, ts, ts / r.end(rev), len(heads), clen))
2735 return 0
2765 return 0
2736
2766
2737 v = r.version
2767 v = r.version
2738 format = v & 0xFFFF
2768 format = v & 0xFFFF
2739 flags = []
2769 flags = []
2740 gdelta = False
2770 gdelta = False
2741 if v & revlog.REVLOGNGINLINEDATA:
2771 if v & revlog.REVLOGNGINLINEDATA:
2742 flags.append('inline')
2772 flags.append('inline')
2743 if v & revlog.REVLOGGENERALDELTA:
2773 if v & revlog.REVLOGGENERALDELTA:
2744 gdelta = True
2774 gdelta = True
2745 flags.append('generaldelta')
2775 flags.append('generaldelta')
2746 if not flags:
2776 if not flags:
2747 flags = ['(none)']
2777 flags = ['(none)']
2748
2778
2749 nummerges = 0
2779 nummerges = 0
2750 numfull = 0
2780 numfull = 0
2751 numprev = 0
2781 numprev = 0
2752 nump1 = 0
2782 nump1 = 0
2753 nump2 = 0
2783 nump2 = 0
2754 numother = 0
2784 numother = 0
2755 nump1prev = 0
2785 nump1prev = 0
2756 nump2prev = 0
2786 nump2prev = 0
2757 chainlengths = []
2787 chainlengths = []
2758
2788
2759 datasize = [None, 0, 0L]
2789 datasize = [None, 0, 0L]
2760 fullsize = [None, 0, 0L]
2790 fullsize = [None, 0, 0L]
2761 deltasize = [None, 0, 0L]
2791 deltasize = [None, 0, 0L]
2762
2792
2763 def addsize(size, l):
2793 def addsize(size, l):
2764 if l[0] is None or size < l[0]:
2794 if l[0] is None or size < l[0]:
2765 l[0] = size
2795 l[0] = size
2766 if size > l[1]:
2796 if size > l[1]:
2767 l[1] = size
2797 l[1] = size
2768 l[2] += size
2798 l[2] += size
2769
2799
2770 numrevs = len(r)
2800 numrevs = len(r)
2771 for rev in xrange(numrevs):
2801 for rev in xrange(numrevs):
2772 p1, p2 = r.parentrevs(rev)
2802 p1, p2 = r.parentrevs(rev)
2773 delta = r.deltaparent(rev)
2803 delta = r.deltaparent(rev)
2774 if format > 0:
2804 if format > 0:
2775 addsize(r.rawsize(rev), datasize)
2805 addsize(r.rawsize(rev), datasize)
2776 if p2 != nullrev:
2806 if p2 != nullrev:
2777 nummerges += 1
2807 nummerges += 1
2778 size = r.length(rev)
2808 size = r.length(rev)
2779 if delta == nullrev:
2809 if delta == nullrev:
2780 chainlengths.append(0)
2810 chainlengths.append(0)
2781 numfull += 1
2811 numfull += 1
2782 addsize(size, fullsize)
2812 addsize(size, fullsize)
2783 else:
2813 else:
2784 chainlengths.append(chainlengths[delta] + 1)
2814 chainlengths.append(chainlengths[delta] + 1)
2785 addsize(size, deltasize)
2815 addsize(size, deltasize)
2786 if delta == rev - 1:
2816 if delta == rev - 1:
2787 numprev += 1
2817 numprev += 1
2788 if delta == p1:
2818 if delta == p1:
2789 nump1prev += 1
2819 nump1prev += 1
2790 elif delta == p2:
2820 elif delta == p2:
2791 nump2prev += 1
2821 nump2prev += 1
2792 elif delta == p1:
2822 elif delta == p1:
2793 nump1 += 1
2823 nump1 += 1
2794 elif delta == p2:
2824 elif delta == p2:
2795 nump2 += 1
2825 nump2 += 1
2796 elif delta != nullrev:
2826 elif delta != nullrev:
2797 numother += 1
2827 numother += 1
2798
2828
2799 # Adjust size min value for empty cases
2829 # Adjust size min value for empty cases
2800 for size in (datasize, fullsize, deltasize):
2830 for size in (datasize, fullsize, deltasize):
2801 if size[0] is None:
2831 if size[0] is None:
2802 size[0] = 0
2832 size[0] = 0
2803
2833
2804 numdeltas = numrevs - numfull
2834 numdeltas = numrevs - numfull
2805 numoprev = numprev - nump1prev - nump2prev
2835 numoprev = numprev - nump1prev - nump2prev
2806 totalrawsize = datasize[2]
2836 totalrawsize = datasize[2]
2807 datasize[2] /= numrevs
2837 datasize[2] /= numrevs
2808 fulltotal = fullsize[2]
2838 fulltotal = fullsize[2]
2809 fullsize[2] /= numfull
2839 fullsize[2] /= numfull
2810 deltatotal = deltasize[2]
2840 deltatotal = deltasize[2]
2811 if numrevs - numfull > 0:
2841 if numrevs - numfull > 0:
2812 deltasize[2] /= numrevs - numfull
2842 deltasize[2] /= numrevs - numfull
2813 totalsize = fulltotal + deltatotal
2843 totalsize = fulltotal + deltatotal
2814 avgchainlen = sum(chainlengths) / numrevs
2844 avgchainlen = sum(chainlengths) / numrevs
2815 compratio = totalrawsize / totalsize
2845 compratio = totalrawsize / totalsize
2816
2846
2817 basedfmtstr = '%%%dd\n'
2847 basedfmtstr = '%%%dd\n'
2818 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2848 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2819
2849
2820 def dfmtstr(max):
2850 def dfmtstr(max):
2821 return basedfmtstr % len(str(max))
2851 return basedfmtstr % len(str(max))
2822 def pcfmtstr(max, padding=0):
2852 def pcfmtstr(max, padding=0):
2823 return basepcfmtstr % (len(str(max)), ' ' * padding)
2853 return basepcfmtstr % (len(str(max)), ' ' * padding)
2824
2854
2825 def pcfmt(value, total):
2855 def pcfmt(value, total):
2826 return (value, 100 * float(value) / total)
2856 return (value, 100 * float(value) / total)
2827
2857
2828 ui.write(('format : %d\n') % format)
2858 ui.write(('format : %d\n') % format)
2829 ui.write(('flags : %s\n') % ', '.join(flags))
2859 ui.write(('flags : %s\n') % ', '.join(flags))
2830
2860
2831 ui.write('\n')
2861 ui.write('\n')
2832 fmt = pcfmtstr(totalsize)
2862 fmt = pcfmtstr(totalsize)
2833 fmt2 = dfmtstr(totalsize)
2863 fmt2 = dfmtstr(totalsize)
2834 ui.write(('revisions : ') + fmt2 % numrevs)
2864 ui.write(('revisions : ') + fmt2 % numrevs)
2835 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2865 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2836 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2866 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2837 ui.write(('revisions : ') + fmt2 % numrevs)
2867 ui.write(('revisions : ') + fmt2 % numrevs)
2838 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2868 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2839 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2869 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2840 ui.write(('revision size : ') + fmt2 % totalsize)
2870 ui.write(('revision size : ') + fmt2 % totalsize)
2841 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2871 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2842 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2872 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2843
2873
2844 ui.write('\n')
2874 ui.write('\n')
2845 fmt = dfmtstr(max(avgchainlen, compratio))
2875 fmt = dfmtstr(max(avgchainlen, compratio))
2846 ui.write(('avg chain length : ') + fmt % avgchainlen)
2876 ui.write(('avg chain length : ') + fmt % avgchainlen)
2847 ui.write(('compression ratio : ') + fmt % compratio)
2877 ui.write(('compression ratio : ') + fmt % compratio)
2848
2878
2849 if format > 0:
2879 if format > 0:
2850 ui.write('\n')
2880 ui.write('\n')
2851 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2881 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2852 % tuple(datasize))
2882 % tuple(datasize))
2853 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2883 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2854 % tuple(fullsize))
2884 % tuple(fullsize))
2855 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2885 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2856 % tuple(deltasize))
2886 % tuple(deltasize))
2857
2887
2858 if numdeltas > 0:
2888 if numdeltas > 0:
2859 ui.write('\n')
2889 ui.write('\n')
2860 fmt = pcfmtstr(numdeltas)
2890 fmt = pcfmtstr(numdeltas)
2861 fmt2 = pcfmtstr(numdeltas, 4)
2891 fmt2 = pcfmtstr(numdeltas, 4)
2862 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2892 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2863 if numprev > 0:
2893 if numprev > 0:
2864 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2894 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2865 numprev))
2895 numprev))
2866 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2896 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2867 numprev))
2897 numprev))
2868 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2898 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2869 numprev))
2899 numprev))
2870 if gdelta:
2900 if gdelta:
2871 ui.write(('deltas against p1 : ')
2901 ui.write(('deltas against p1 : ')
2872 + fmt % pcfmt(nump1, numdeltas))
2902 + fmt % pcfmt(nump1, numdeltas))
2873 ui.write(('deltas against p2 : ')
2903 ui.write(('deltas against p2 : ')
2874 + fmt % pcfmt(nump2, numdeltas))
2904 + fmt % pcfmt(nump2, numdeltas))
2875 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2905 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2876 numdeltas))
2906 numdeltas))
2877
2907
2878 @command('debugrevspec',
2908 @command('debugrevspec',
2879 [('', 'optimize', None, _('print parsed tree after optimizing'))],
2909 [('', 'optimize', None, _('print parsed tree after optimizing'))],
2880 ('REVSPEC'))
2910 ('REVSPEC'))
2881 def debugrevspec(ui, repo, expr, **opts):
2911 def debugrevspec(ui, repo, expr, **opts):
2882 """parse and apply a revision specification
2912 """parse and apply a revision specification
2883
2913
2884 Use --verbose to print the parsed tree before and after aliases
2914 Use --verbose to print the parsed tree before and after aliases
2885 expansion.
2915 expansion.
2886 """
2916 """
2887 if ui.verbose:
2917 if ui.verbose:
2888 tree = revset.parse(expr)[0]
2918 tree = revset.parse(expr)[0]
2889 ui.note(revset.prettyformat(tree), "\n")
2919 ui.note(revset.prettyformat(tree), "\n")
2890 newtree = revset.findaliases(ui, tree)
2920 newtree = revset.findaliases(ui, tree)
2891 if newtree != tree:
2921 if newtree != tree:
2892 ui.note(revset.prettyformat(newtree), "\n")
2922 ui.note(revset.prettyformat(newtree), "\n")
2893 tree = newtree
2923 tree = newtree
2894 newtree = revset.foldconcat(tree)
2924 newtree = revset.foldconcat(tree)
2895 if newtree != tree:
2925 if newtree != tree:
2896 ui.note(revset.prettyformat(newtree), "\n")
2926 ui.note(revset.prettyformat(newtree), "\n")
2897 if opts["optimize"]:
2927 if opts["optimize"]:
2898 weight, optimizedtree = revset.optimize(newtree, True)
2928 weight, optimizedtree = revset.optimize(newtree, True)
2899 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
2929 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
2900 func = revset.match(ui, expr)
2930 func = revset.match(ui, expr)
2901 for c in func(repo):
2931 for c in func(repo):
2902 ui.write("%s\n" % c)
2932 ui.write("%s\n" % c)
2903
2933
2904 @command('debugsetparents', [], _('REV1 [REV2]'))
2934 @command('debugsetparents', [], _('REV1 [REV2]'))
2905 def debugsetparents(ui, repo, rev1, rev2=None):
2935 def debugsetparents(ui, repo, rev1, rev2=None):
2906 """manually set the parents of the current working directory
2936 """manually set the parents of the current working directory
2907
2937
2908 This is useful for writing repository conversion tools, but should
2938 This is useful for writing repository conversion tools, but should
2909 be used with care. For example, neither the working directory nor the
2939 be used with care. For example, neither the working directory nor the
2910 dirstate is updated, so file status may be incorrect after running this
2940 dirstate is updated, so file status may be incorrect after running this
2911 command.
2941 command.
2912
2942
2913 Returns 0 on success.
2943 Returns 0 on success.
2914 """
2944 """
2915
2945
2916 r1 = scmutil.revsingle(repo, rev1).node()
2946 r1 = scmutil.revsingle(repo, rev1).node()
2917 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2947 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2918
2948
2919 wlock = repo.wlock()
2949 wlock = repo.wlock()
2920 try:
2950 try:
2921 repo.dirstate.beginparentchange()
2951 repo.dirstate.beginparentchange()
2922 repo.setparents(r1, r2)
2952 repo.setparents(r1, r2)
2923 repo.dirstate.endparentchange()
2953 repo.dirstate.endparentchange()
2924 finally:
2954 finally:
2925 wlock.release()
2955 wlock.release()
2926
2956
2927 @command('debugdirstate|debugstate',
2957 @command('debugdirstate|debugstate',
2928 [('', 'nodates', None, _('do not display the saved mtime')),
2958 [('', 'nodates', None, _('do not display the saved mtime')),
2929 ('', 'datesort', None, _('sort by saved mtime'))],
2959 ('', 'datesort', None, _('sort by saved mtime'))],
2930 _('[OPTION]...'))
2960 _('[OPTION]...'))
2931 def debugstate(ui, repo, nodates=None, datesort=None):
2961 def debugstate(ui, repo, nodates=None, datesort=None):
2932 """show the contents of the current dirstate"""
2962 """show the contents of the current dirstate"""
2933 timestr = ""
2963 timestr = ""
2934 if datesort:
2964 if datesort:
2935 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2965 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2936 else:
2966 else:
2937 keyfunc = None # sort by filename
2967 keyfunc = None # sort by filename
2938 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2968 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2939 if ent[3] == -1:
2969 if ent[3] == -1:
2940 timestr = 'unset '
2970 timestr = 'unset '
2941 elif nodates:
2971 elif nodates:
2942 timestr = 'set '
2972 timestr = 'set '
2943 else:
2973 else:
2944 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2974 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2945 time.localtime(ent[3]))
2975 time.localtime(ent[3]))
2946 if ent[1] & 020000:
2976 if ent[1] & 020000:
2947 mode = 'lnk'
2977 mode = 'lnk'
2948 else:
2978 else:
2949 mode = '%3o' % (ent[1] & 0777 & ~util.umask)
2979 mode = '%3o' % (ent[1] & 0777 & ~util.umask)
2950 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2980 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2951 for f in repo.dirstate.copies():
2981 for f in repo.dirstate.copies():
2952 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2982 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2953
2983
2954 @command('debugsub',
2984 @command('debugsub',
2955 [('r', 'rev', '',
2985 [('r', 'rev', '',
2956 _('revision to check'), _('REV'))],
2986 _('revision to check'), _('REV'))],
2957 _('[-r REV] [REV]'))
2987 _('[-r REV] [REV]'))
2958 def debugsub(ui, repo, rev=None):
2988 def debugsub(ui, repo, rev=None):
2959 ctx = scmutil.revsingle(repo, rev, None)
2989 ctx = scmutil.revsingle(repo, rev, None)
2960 for k, v in sorted(ctx.substate.items()):
2990 for k, v in sorted(ctx.substate.items()):
2961 ui.write(('path %s\n') % k)
2991 ui.write(('path %s\n') % k)
2962 ui.write((' source %s\n') % v[0])
2992 ui.write((' source %s\n') % v[0])
2963 ui.write((' revision %s\n') % v[1])
2993 ui.write((' revision %s\n') % v[1])
2964
2994
2965 @command('debugsuccessorssets',
2995 @command('debugsuccessorssets',
2966 [],
2996 [],
2967 _('[REV]'))
2997 _('[REV]'))
2968 def debugsuccessorssets(ui, repo, *revs):
2998 def debugsuccessorssets(ui, repo, *revs):
2969 """show set of successors for revision
2999 """show set of successors for revision
2970
3000
2971 A successors set of changeset A is a consistent group of revisions that
3001 A successors set of changeset A is a consistent group of revisions that
2972 succeed A. It contains non-obsolete changesets only.
3002 succeed A. It contains non-obsolete changesets only.
2973
3003
2974 In most cases a changeset A has a single successors set containing a single
3004 In most cases a changeset A has a single successors set containing a single
2975 successor (changeset A replaced by A').
3005 successor (changeset A replaced by A').
2976
3006
2977 A changeset that is made obsolete with no successors are called "pruned".
3007 A changeset that is made obsolete with no successors are called "pruned".
2978 Such changesets have no successors sets at all.
3008 Such changesets have no successors sets at all.
2979
3009
2980 A changeset that has been "split" will have a successors set containing
3010 A changeset that has been "split" will have a successors set containing
2981 more than one successor.
3011 more than one successor.
2982
3012
2983 A changeset that has been rewritten in multiple different ways is called
3013 A changeset that has been rewritten in multiple different ways is called
2984 "divergent". Such changesets have multiple successor sets (each of which
3014 "divergent". Such changesets have multiple successor sets (each of which
2985 may also be split, i.e. have multiple successors).
3015 may also be split, i.e. have multiple successors).
2986
3016
2987 Results are displayed as follows::
3017 Results are displayed as follows::
2988
3018
2989 <rev1>
3019 <rev1>
2990 <successors-1A>
3020 <successors-1A>
2991 <rev2>
3021 <rev2>
2992 <successors-2A>
3022 <successors-2A>
2993 <successors-2B1> <successors-2B2> <successors-2B3>
3023 <successors-2B1> <successors-2B2> <successors-2B3>
2994
3024
2995 Here rev2 has two possible (i.e. divergent) successors sets. The first
3025 Here rev2 has two possible (i.e. divergent) successors sets. The first
2996 holds one element, whereas the second holds three (i.e. the changeset has
3026 holds one element, whereas the second holds three (i.e. the changeset has
2997 been split).
3027 been split).
2998 """
3028 """
2999 # passed to successorssets caching computation from one call to another
3029 # passed to successorssets caching computation from one call to another
3000 cache = {}
3030 cache = {}
3001 ctx2str = str
3031 ctx2str = str
3002 node2str = short
3032 node2str = short
3003 if ui.debug():
3033 if ui.debug():
3004 def ctx2str(ctx):
3034 def ctx2str(ctx):
3005 return ctx.hex()
3035 return ctx.hex()
3006 node2str = hex
3036 node2str = hex
3007 for rev in scmutil.revrange(repo, revs):
3037 for rev in scmutil.revrange(repo, revs):
3008 ctx = repo[rev]
3038 ctx = repo[rev]
3009 ui.write('%s\n'% ctx2str(ctx))
3039 ui.write('%s\n'% ctx2str(ctx))
3010 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
3040 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
3011 if succsset:
3041 if succsset:
3012 ui.write(' ')
3042 ui.write(' ')
3013 ui.write(node2str(succsset[0]))
3043 ui.write(node2str(succsset[0]))
3014 for node in succsset[1:]:
3044 for node in succsset[1:]:
3015 ui.write(' ')
3045 ui.write(' ')
3016 ui.write(node2str(node))
3046 ui.write(node2str(node))
3017 ui.write('\n')
3047 ui.write('\n')
3018
3048
3019 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'), inferrepo=True)
3049 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'), inferrepo=True)
3020 def debugwalk(ui, repo, *pats, **opts):
3050 def debugwalk(ui, repo, *pats, **opts):
3021 """show how files match on given patterns"""
3051 """show how files match on given patterns"""
3022 m = scmutil.match(repo[None], pats, opts)
3052 m = scmutil.match(repo[None], pats, opts)
3023 items = list(repo.walk(m))
3053 items = list(repo.walk(m))
3024 if not items:
3054 if not items:
3025 return
3055 return
3026 f = lambda fn: fn
3056 f = lambda fn: fn
3027 if ui.configbool('ui', 'slash') and os.sep != '/':
3057 if ui.configbool('ui', 'slash') and os.sep != '/':
3028 f = lambda fn: util.normpath(fn)
3058 f = lambda fn: util.normpath(fn)
3029 fmt = 'f %%-%ds %%-%ds %%s' % (
3059 fmt = 'f %%-%ds %%-%ds %%s' % (
3030 max([len(abs) for abs in items]),
3060 max([len(abs) for abs in items]),
3031 max([len(m.rel(abs)) for abs in items]))
3061 max([len(m.rel(abs)) for abs in items]))
3032 for abs in items:
3062 for abs in items:
3033 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
3063 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
3034 ui.write("%s\n" % line.rstrip())
3064 ui.write("%s\n" % line.rstrip())
3035
3065
3036 @command('debugwireargs',
3066 @command('debugwireargs',
3037 [('', 'three', '', 'three'),
3067 [('', 'three', '', 'three'),
3038 ('', 'four', '', 'four'),
3068 ('', 'four', '', 'four'),
3039 ('', 'five', '', 'five'),
3069 ('', 'five', '', 'five'),
3040 ] + remoteopts,
3070 ] + remoteopts,
3041 _('REPO [OPTIONS]... [ONE [TWO]]'),
3071 _('REPO [OPTIONS]... [ONE [TWO]]'),
3042 norepo=True)
3072 norepo=True)
3043 def debugwireargs(ui, repopath, *vals, **opts):
3073 def debugwireargs(ui, repopath, *vals, **opts):
3044 repo = hg.peer(ui, opts, repopath)
3074 repo = hg.peer(ui, opts, repopath)
3045 for opt in remoteopts:
3075 for opt in remoteopts:
3046 del opts[opt[1]]
3076 del opts[opt[1]]
3047 args = {}
3077 args = {}
3048 for k, v in opts.iteritems():
3078 for k, v in opts.iteritems():
3049 if v:
3079 if v:
3050 args[k] = v
3080 args[k] = v
3051 # run twice to check that we don't mess up the stream for the next command
3081 # run twice to check that we don't mess up the stream for the next command
3052 res1 = repo.debugwireargs(*vals, **args)
3082 res1 = repo.debugwireargs(*vals, **args)
3053 res2 = repo.debugwireargs(*vals, **args)
3083 res2 = repo.debugwireargs(*vals, **args)
3054 ui.write("%s\n" % res1)
3084 ui.write("%s\n" % res1)
3055 if res1 != res2:
3085 if res1 != res2:
3056 ui.warn("%s\n" % res2)
3086 ui.warn("%s\n" % res2)
3057
3087
3058 @command('^diff',
3088 @command('^diff',
3059 [('r', 'rev', [], _('revision'), _('REV')),
3089 [('r', 'rev', [], _('revision'), _('REV')),
3060 ('c', 'change', '', _('change made by revision'), _('REV'))
3090 ('c', 'change', '', _('change made by revision'), _('REV'))
3061 ] + diffopts + diffopts2 + walkopts + subrepoopts,
3091 ] + diffopts + diffopts2 + walkopts + subrepoopts,
3062 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
3092 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
3063 inferrepo=True)
3093 inferrepo=True)
3064 def diff(ui, repo, *pats, **opts):
3094 def diff(ui, repo, *pats, **opts):
3065 """diff repository (or selected files)
3095 """diff repository (or selected files)
3066
3096
3067 Show differences between revisions for the specified files.
3097 Show differences between revisions for the specified files.
3068
3098
3069 Differences between files are shown using the unified diff format.
3099 Differences between files are shown using the unified diff format.
3070
3100
3071 .. note::
3101 .. note::
3072
3102
3073 diff may generate unexpected results for merges, as it will
3103 diff may generate unexpected results for merges, as it will
3074 default to comparing against the working directory's first
3104 default to comparing against the working directory's first
3075 parent changeset if no revisions are specified.
3105 parent changeset if no revisions are specified.
3076
3106
3077 When two revision arguments are given, then changes are shown
3107 When two revision arguments are given, then changes are shown
3078 between those revisions. If only one revision is specified then
3108 between those revisions. If only one revision is specified then
3079 that revision is compared to the working directory, and, when no
3109 that revision is compared to the working directory, and, when no
3080 revisions are specified, the working directory files are compared
3110 revisions are specified, the working directory files are compared
3081 to its parent.
3111 to its parent.
3082
3112
3083 Alternatively you can specify -c/--change with a revision to see
3113 Alternatively you can specify -c/--change with a revision to see
3084 the changes in that changeset relative to its first parent.
3114 the changes in that changeset relative to its first parent.
3085
3115
3086 Without the -a/--text option, diff will avoid generating diffs of
3116 Without the -a/--text option, diff will avoid generating diffs of
3087 files it detects as binary. With -a, diff will generate a diff
3117 files it detects as binary. With -a, diff will generate a diff
3088 anyway, probably with undesirable results.
3118 anyway, probably with undesirable results.
3089
3119
3090 Use the -g/--git option to generate diffs in the git extended diff
3120 Use the -g/--git option to generate diffs in the git extended diff
3091 format. For more information, read :hg:`help diffs`.
3121 format. For more information, read :hg:`help diffs`.
3092
3122
3093 .. container:: verbose
3123 .. container:: verbose
3094
3124
3095 Examples:
3125 Examples:
3096
3126
3097 - compare a file in the current working directory to its parent::
3127 - compare a file in the current working directory to its parent::
3098
3128
3099 hg diff foo.c
3129 hg diff foo.c
3100
3130
3101 - compare two historical versions of a directory, with rename info::
3131 - compare two historical versions of a directory, with rename info::
3102
3132
3103 hg diff --git -r 1.0:1.2 lib/
3133 hg diff --git -r 1.0:1.2 lib/
3104
3134
3105 - get change stats relative to the last change on some date::
3135 - get change stats relative to the last change on some date::
3106
3136
3107 hg diff --stat -r "date('may 2')"
3137 hg diff --stat -r "date('may 2')"
3108
3138
3109 - diff all newly-added files that contain a keyword::
3139 - diff all newly-added files that contain a keyword::
3110
3140
3111 hg diff "set:added() and grep(GNU)"
3141 hg diff "set:added() and grep(GNU)"
3112
3142
3113 - compare a revision and its parents::
3143 - compare a revision and its parents::
3114
3144
3115 hg diff -c 9353 # compare against first parent
3145 hg diff -c 9353 # compare against first parent
3116 hg diff -r 9353^:9353 # same using revset syntax
3146 hg diff -r 9353^:9353 # same using revset syntax
3117 hg diff -r 9353^2:9353 # compare against the second parent
3147 hg diff -r 9353^2:9353 # compare against the second parent
3118
3148
3119 Returns 0 on success.
3149 Returns 0 on success.
3120 """
3150 """
3121
3151
3122 revs = opts.get('rev')
3152 revs = opts.get('rev')
3123 change = opts.get('change')
3153 change = opts.get('change')
3124 stat = opts.get('stat')
3154 stat = opts.get('stat')
3125 reverse = opts.get('reverse')
3155 reverse = opts.get('reverse')
3126
3156
3127 if revs and change:
3157 if revs and change:
3128 msg = _('cannot specify --rev and --change at the same time')
3158 msg = _('cannot specify --rev and --change at the same time')
3129 raise util.Abort(msg)
3159 raise util.Abort(msg)
3130 elif change:
3160 elif change:
3131 node2 = scmutil.revsingle(repo, change, None).node()
3161 node2 = scmutil.revsingle(repo, change, None).node()
3132 node1 = repo[node2].p1().node()
3162 node1 = repo[node2].p1().node()
3133 else:
3163 else:
3134 node1, node2 = scmutil.revpair(repo, revs)
3164 node1, node2 = scmutil.revpair(repo, revs)
3135
3165
3136 if reverse:
3166 if reverse:
3137 node1, node2 = node2, node1
3167 node1, node2 = node2, node1
3138
3168
3139 diffopts = patch.diffallopts(ui, opts)
3169 diffopts = patch.diffallopts(ui, opts)
3140 m = scmutil.match(repo[node2], pats, opts)
3170 m = scmutil.match(repo[node2], pats, opts)
3141 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
3171 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
3142 listsubrepos=opts.get('subrepos'))
3172 listsubrepos=opts.get('subrepos'))
3143
3173
3144 @command('^export',
3174 @command('^export',
3145 [('o', 'output', '',
3175 [('o', 'output', '',
3146 _('print output to file with formatted name'), _('FORMAT')),
3176 _('print output to file with formatted name'), _('FORMAT')),
3147 ('', 'switch-parent', None, _('diff against the second parent')),
3177 ('', 'switch-parent', None, _('diff against the second parent')),
3148 ('r', 'rev', [], _('revisions to export'), _('REV')),
3178 ('r', 'rev', [], _('revisions to export'), _('REV')),
3149 ] + diffopts,
3179 ] + diffopts,
3150 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
3180 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
3151 def export(ui, repo, *changesets, **opts):
3181 def export(ui, repo, *changesets, **opts):
3152 """dump the header and diffs for one or more changesets
3182 """dump the header and diffs for one or more changesets
3153
3183
3154 Print the changeset header and diffs for one or more revisions.
3184 Print the changeset header and diffs for one or more revisions.
3155 If no revision is given, the parent of the working directory is used.
3185 If no revision is given, the parent of the working directory is used.
3156
3186
3157 The information shown in the changeset header is: author, date,
3187 The information shown in the changeset header is: author, date,
3158 branch name (if non-default), changeset hash, parent(s) and commit
3188 branch name (if non-default), changeset hash, parent(s) and commit
3159 comment.
3189 comment.
3160
3190
3161 .. note::
3191 .. note::
3162
3192
3163 export may generate unexpected diff output for merge
3193 export may generate unexpected diff output for merge
3164 changesets, as it will compare the merge changeset against its
3194 changesets, as it will compare the merge changeset against its
3165 first parent only.
3195 first parent only.
3166
3196
3167 Output may be to a file, in which case the name of the file is
3197 Output may be to a file, in which case the name of the file is
3168 given using a format string. The formatting rules are as follows:
3198 given using a format string. The formatting rules are as follows:
3169
3199
3170 :``%%``: literal "%" character
3200 :``%%``: literal "%" character
3171 :``%H``: changeset hash (40 hexadecimal digits)
3201 :``%H``: changeset hash (40 hexadecimal digits)
3172 :``%N``: number of patches being generated
3202 :``%N``: number of patches being generated
3173 :``%R``: changeset revision number
3203 :``%R``: changeset revision number
3174 :``%b``: basename of the exporting repository
3204 :``%b``: basename of the exporting repository
3175 :``%h``: short-form changeset hash (12 hexadecimal digits)
3205 :``%h``: short-form changeset hash (12 hexadecimal digits)
3176 :``%m``: first line of the commit message (only alphanumeric characters)
3206 :``%m``: first line of the commit message (only alphanumeric characters)
3177 :``%n``: zero-padded sequence number, starting at 1
3207 :``%n``: zero-padded sequence number, starting at 1
3178 :``%r``: zero-padded changeset revision number
3208 :``%r``: zero-padded changeset revision number
3179
3209
3180 Without the -a/--text option, export will avoid generating diffs
3210 Without the -a/--text option, export will avoid generating diffs
3181 of files it detects as binary. With -a, export will generate a
3211 of files it detects as binary. With -a, export will generate a
3182 diff anyway, probably with undesirable results.
3212 diff anyway, probably with undesirable results.
3183
3213
3184 Use the -g/--git option to generate diffs in the git extended diff
3214 Use the -g/--git option to generate diffs in the git extended diff
3185 format. See :hg:`help diffs` for more information.
3215 format. See :hg:`help diffs` for more information.
3186
3216
3187 With the --switch-parent option, the diff will be against the
3217 With the --switch-parent option, the diff will be against the
3188 second parent. It can be useful to review a merge.
3218 second parent. It can be useful to review a merge.
3189
3219
3190 .. container:: verbose
3220 .. container:: verbose
3191
3221
3192 Examples:
3222 Examples:
3193
3223
3194 - use export and import to transplant a bugfix to the current
3224 - use export and import to transplant a bugfix to the current
3195 branch::
3225 branch::
3196
3226
3197 hg export -r 9353 | hg import -
3227 hg export -r 9353 | hg import -
3198
3228
3199 - export all the changesets between two revisions to a file with
3229 - export all the changesets between two revisions to a file with
3200 rename information::
3230 rename information::
3201
3231
3202 hg export --git -r 123:150 > changes.txt
3232 hg export --git -r 123:150 > changes.txt
3203
3233
3204 - split outgoing changes into a series of patches with
3234 - split outgoing changes into a series of patches with
3205 descriptive names::
3235 descriptive names::
3206
3236
3207 hg export -r "outgoing()" -o "%n-%m.patch"
3237 hg export -r "outgoing()" -o "%n-%m.patch"
3208
3238
3209 Returns 0 on success.
3239 Returns 0 on success.
3210 """
3240 """
3211 changesets += tuple(opts.get('rev', []))
3241 changesets += tuple(opts.get('rev', []))
3212 if not changesets:
3242 if not changesets:
3213 changesets = ['.']
3243 changesets = ['.']
3214 revs = scmutil.revrange(repo, changesets)
3244 revs = scmutil.revrange(repo, changesets)
3215 if not revs:
3245 if not revs:
3216 raise util.Abort(_("export requires at least one changeset"))
3246 raise util.Abort(_("export requires at least one changeset"))
3217 if len(revs) > 1:
3247 if len(revs) > 1:
3218 ui.note(_('exporting patches:\n'))
3248 ui.note(_('exporting patches:\n'))
3219 else:
3249 else:
3220 ui.note(_('exporting patch:\n'))
3250 ui.note(_('exporting patch:\n'))
3221 cmdutil.export(repo, revs, template=opts.get('output'),
3251 cmdutil.export(repo, revs, template=opts.get('output'),
3222 switch_parent=opts.get('switch_parent'),
3252 switch_parent=opts.get('switch_parent'),
3223 opts=patch.diffallopts(ui, opts))
3253 opts=patch.diffallopts(ui, opts))
3224
3254
3225 @command('files',
3255 @command('files',
3226 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3256 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3227 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3257 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3228 ] + walkopts + formatteropts + subrepoopts,
3258 ] + walkopts + formatteropts + subrepoopts,
3229 _('[OPTION]... [PATTERN]...'))
3259 _('[OPTION]... [PATTERN]...'))
3230 def files(ui, repo, *pats, **opts):
3260 def files(ui, repo, *pats, **opts):
3231 """list tracked files
3261 """list tracked files
3232
3262
3233 Print files under Mercurial control in the working directory or
3263 Print files under Mercurial control in the working directory or
3234 specified revision whose names match the given patterns (excluding
3264 specified revision whose names match the given patterns (excluding
3235 removed files).
3265 removed files).
3236
3266
3237 If no patterns are given to match, this command prints the names
3267 If no patterns are given to match, this command prints the names
3238 of all files under Mercurial control in the working directory.
3268 of all files under Mercurial control in the working directory.
3239
3269
3240 .. container:: verbose
3270 .. container:: verbose
3241
3271
3242 Examples:
3272 Examples:
3243
3273
3244 - list all files under the current directory::
3274 - list all files under the current directory::
3245
3275
3246 hg files .
3276 hg files .
3247
3277
3248 - shows sizes and flags for current revision::
3278 - shows sizes and flags for current revision::
3249
3279
3250 hg files -vr .
3280 hg files -vr .
3251
3281
3252 - list all files named README::
3282 - list all files named README::
3253
3283
3254 hg files -I "**/README"
3284 hg files -I "**/README"
3255
3285
3256 - list all binary files::
3286 - list all binary files::
3257
3287
3258 hg files "set:binary()"
3288 hg files "set:binary()"
3259
3289
3260 - find files containing a regular expression::
3290 - find files containing a regular expression::
3261
3291
3262 hg files "set:grep('bob')"
3292 hg files "set:grep('bob')"
3263
3293
3264 - search tracked file contents with xargs and grep::
3294 - search tracked file contents with xargs and grep::
3265
3295
3266 hg files -0 | xargs -0 grep foo
3296 hg files -0 | xargs -0 grep foo
3267
3297
3268 See :hg:`help patterns` and :hg:`help filesets` for more information
3298 See :hg:`help patterns` and :hg:`help filesets` for more information
3269 on specifying file patterns.
3299 on specifying file patterns.
3270
3300
3271 Returns 0 if a match is found, 1 otherwise.
3301 Returns 0 if a match is found, 1 otherwise.
3272
3302
3273 """
3303 """
3274 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3304 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3275
3305
3276 end = '\n'
3306 end = '\n'
3277 if opts.get('print0'):
3307 if opts.get('print0'):
3278 end = '\0'
3308 end = '\0'
3279 fm = ui.formatter('files', opts)
3309 fm = ui.formatter('files', opts)
3280 fmt = '%s' + end
3310 fmt = '%s' + end
3281
3311
3282 m = scmutil.match(ctx, pats, opts)
3312 m = scmutil.match(ctx, pats, opts)
3283 ret = cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
3313 ret = cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
3284
3314
3285 fm.end()
3315 fm.end()
3286
3316
3287 return ret
3317 return ret
3288
3318
3289 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
3319 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
3290 def forget(ui, repo, *pats, **opts):
3320 def forget(ui, repo, *pats, **opts):
3291 """forget the specified files on the next commit
3321 """forget the specified files on the next commit
3292
3322
3293 Mark the specified files so they will no longer be tracked
3323 Mark the specified files so they will no longer be tracked
3294 after the next commit.
3324 after the next commit.
3295
3325
3296 This only removes files from the current branch, not from the
3326 This only removes files from the current branch, not from the
3297 entire project history, and it does not delete them from the
3327 entire project history, and it does not delete them from the
3298 working directory.
3328 working directory.
3299
3329
3300 To undo a forget before the next commit, see :hg:`add`.
3330 To undo a forget before the next commit, see :hg:`add`.
3301
3331
3302 .. container:: verbose
3332 .. container:: verbose
3303
3333
3304 Examples:
3334 Examples:
3305
3335
3306 - forget newly-added binary files::
3336 - forget newly-added binary files::
3307
3337
3308 hg forget "set:added() and binary()"
3338 hg forget "set:added() and binary()"
3309
3339
3310 - forget files that would be excluded by .hgignore::
3340 - forget files that would be excluded by .hgignore::
3311
3341
3312 hg forget "set:hgignore()"
3342 hg forget "set:hgignore()"
3313
3343
3314 Returns 0 on success.
3344 Returns 0 on success.
3315 """
3345 """
3316
3346
3317 if not pats:
3347 if not pats:
3318 raise util.Abort(_('no files specified'))
3348 raise util.Abort(_('no files specified'))
3319
3349
3320 m = scmutil.match(repo[None], pats, opts)
3350 m = scmutil.match(repo[None], pats, opts)
3321 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3351 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3322 return rejected and 1 or 0
3352 return rejected and 1 or 0
3323
3353
3324 @command(
3354 @command(
3325 'graft',
3355 'graft',
3326 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3356 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3327 ('c', 'continue', False, _('resume interrupted graft')),
3357 ('c', 'continue', False, _('resume interrupted graft')),
3328 ('e', 'edit', False, _('invoke editor on commit messages')),
3358 ('e', 'edit', False, _('invoke editor on commit messages')),
3329 ('', 'log', None, _('append graft info to log message')),
3359 ('', 'log', None, _('append graft info to log message')),
3330 ('f', 'force', False, _('force graft')),
3360 ('f', 'force', False, _('force graft')),
3331 ('D', 'currentdate', False,
3361 ('D', 'currentdate', False,
3332 _('record the current date as commit date')),
3362 _('record the current date as commit date')),
3333 ('U', 'currentuser', False,
3363 ('U', 'currentuser', False,
3334 _('record the current user as committer'), _('DATE'))]
3364 _('record the current user as committer'), _('DATE'))]
3335 + commitopts2 + mergetoolopts + dryrunopts,
3365 + commitopts2 + mergetoolopts + dryrunopts,
3336 _('[OPTION]... [-r] REV...'))
3366 _('[OPTION]... [-r] REV...'))
3337 def graft(ui, repo, *revs, **opts):
3367 def graft(ui, repo, *revs, **opts):
3338 '''copy changes from other branches onto the current branch
3368 '''copy changes from other branches onto the current branch
3339
3369
3340 This command uses Mercurial's merge logic to copy individual
3370 This command uses Mercurial's merge logic to copy individual
3341 changes from other branches without merging branches in the
3371 changes from other branches without merging branches in the
3342 history graph. This is sometimes known as 'backporting' or
3372 history graph. This is sometimes known as 'backporting' or
3343 'cherry-picking'. By default, graft will copy user, date, and
3373 'cherry-picking'. By default, graft will copy user, date, and
3344 description from the source changesets.
3374 description from the source changesets.
3345
3375
3346 Changesets that are ancestors of the current revision, that have
3376 Changesets that are ancestors of the current revision, that have
3347 already been grafted, or that are merges will be skipped.
3377 already been grafted, or that are merges will be skipped.
3348
3378
3349 If --log is specified, log messages will have a comment appended
3379 If --log is specified, log messages will have a comment appended
3350 of the form::
3380 of the form::
3351
3381
3352 (grafted from CHANGESETHASH)
3382 (grafted from CHANGESETHASH)
3353
3383
3354 If --force is specified, revisions will be grafted even if they
3384 If --force is specified, revisions will be grafted even if they
3355 are already ancestors of or have been grafted to the destination.
3385 are already ancestors of or have been grafted to the destination.
3356 This is useful when the revisions have since been backed out.
3386 This is useful when the revisions have since been backed out.
3357
3387
3358 If a graft merge results in conflicts, the graft process is
3388 If a graft merge results in conflicts, the graft process is
3359 interrupted so that the current merge can be manually resolved.
3389 interrupted so that the current merge can be manually resolved.
3360 Once all conflicts are addressed, the graft process can be
3390 Once all conflicts are addressed, the graft process can be
3361 continued with the -c/--continue option.
3391 continued with the -c/--continue option.
3362
3392
3363 .. note::
3393 .. note::
3364
3394
3365 The -c/--continue option does not reapply earlier options, except
3395 The -c/--continue option does not reapply earlier options, except
3366 for --force.
3396 for --force.
3367
3397
3368 .. container:: verbose
3398 .. container:: verbose
3369
3399
3370 Examples:
3400 Examples:
3371
3401
3372 - copy a single change to the stable branch and edit its description::
3402 - copy a single change to the stable branch and edit its description::
3373
3403
3374 hg update stable
3404 hg update stable
3375 hg graft --edit 9393
3405 hg graft --edit 9393
3376
3406
3377 - graft a range of changesets with one exception, updating dates::
3407 - graft a range of changesets with one exception, updating dates::
3378
3408
3379 hg graft -D "2085::2093 and not 2091"
3409 hg graft -D "2085::2093 and not 2091"
3380
3410
3381 - continue a graft after resolving conflicts::
3411 - continue a graft after resolving conflicts::
3382
3412
3383 hg graft -c
3413 hg graft -c
3384
3414
3385 - show the source of a grafted changeset::
3415 - show the source of a grafted changeset::
3386
3416
3387 hg log --debug -r .
3417 hg log --debug -r .
3388
3418
3389 See :hg:`help revisions` and :hg:`help revsets` for more about
3419 See :hg:`help revisions` and :hg:`help revsets` for more about
3390 specifying revisions.
3420 specifying revisions.
3391
3421
3392 Returns 0 on successful completion.
3422 Returns 0 on successful completion.
3393 '''
3423 '''
3394
3424
3395 revs = list(revs)
3425 revs = list(revs)
3396 revs.extend(opts['rev'])
3426 revs.extend(opts['rev'])
3397
3427
3398 if not opts.get('user') and opts.get('currentuser'):
3428 if not opts.get('user') and opts.get('currentuser'):
3399 opts['user'] = ui.username()
3429 opts['user'] = ui.username()
3400 if not opts.get('date') and opts.get('currentdate'):
3430 if not opts.get('date') and opts.get('currentdate'):
3401 opts['date'] = "%d %d" % util.makedate()
3431 opts['date'] = "%d %d" % util.makedate()
3402
3432
3403 editor = cmdutil.getcommiteditor(editform='graft', **opts)
3433 editor = cmdutil.getcommiteditor(editform='graft', **opts)
3404
3434
3405 cont = False
3435 cont = False
3406 if opts['continue']:
3436 if opts['continue']:
3407 cont = True
3437 cont = True
3408 if revs:
3438 if revs:
3409 raise util.Abort(_("can't specify --continue and revisions"))
3439 raise util.Abort(_("can't specify --continue and revisions"))
3410 # read in unfinished revisions
3440 # read in unfinished revisions
3411 try:
3441 try:
3412 nodes = repo.vfs.read('graftstate').splitlines()
3442 nodes = repo.vfs.read('graftstate').splitlines()
3413 revs = [repo[node].rev() for node in nodes]
3443 revs = [repo[node].rev() for node in nodes]
3414 except IOError, inst:
3444 except IOError, inst:
3415 if inst.errno != errno.ENOENT:
3445 if inst.errno != errno.ENOENT:
3416 raise
3446 raise
3417 raise util.Abort(_("no graft state found, can't continue"))
3447 raise util.Abort(_("no graft state found, can't continue"))
3418 else:
3448 else:
3419 cmdutil.checkunfinished(repo)
3449 cmdutil.checkunfinished(repo)
3420 cmdutil.bailifchanged(repo)
3450 cmdutil.bailifchanged(repo)
3421 if not revs:
3451 if not revs:
3422 raise util.Abort(_('no revisions specified'))
3452 raise util.Abort(_('no revisions specified'))
3423 revs = scmutil.revrange(repo, revs)
3453 revs = scmutil.revrange(repo, revs)
3424
3454
3425 skipped = set()
3455 skipped = set()
3426 # check for merges
3456 # check for merges
3427 for rev in repo.revs('%ld and merge()', revs):
3457 for rev in repo.revs('%ld and merge()', revs):
3428 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3458 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3429 skipped.add(rev)
3459 skipped.add(rev)
3430 revs = [r for r in revs if r not in skipped]
3460 revs = [r for r in revs if r not in skipped]
3431 if not revs:
3461 if not revs:
3432 return -1
3462 return -1
3433
3463
3434 # Don't check in the --continue case, in effect retaining --force across
3464 # Don't check in the --continue case, in effect retaining --force across
3435 # --continues. That's because without --force, any revisions we decided to
3465 # --continues. That's because without --force, any revisions we decided to
3436 # skip would have been filtered out here, so they wouldn't have made their
3466 # skip would have been filtered out here, so they wouldn't have made their
3437 # way to the graftstate. With --force, any revisions we would have otherwise
3467 # way to the graftstate. With --force, any revisions we would have otherwise
3438 # skipped would not have been filtered out, and if they hadn't been applied
3468 # skipped would not have been filtered out, and if they hadn't been applied
3439 # already, they'd have been in the graftstate.
3469 # already, they'd have been in the graftstate.
3440 if not (cont or opts.get('force')):
3470 if not (cont or opts.get('force')):
3441 # check for ancestors of dest branch
3471 # check for ancestors of dest branch
3442 crev = repo['.'].rev()
3472 crev = repo['.'].rev()
3443 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3473 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3444 # Cannot use x.remove(y) on smart set, this has to be a list.
3474 # Cannot use x.remove(y) on smart set, this has to be a list.
3445 # XXX make this lazy in the future
3475 # XXX make this lazy in the future
3446 revs = list(revs)
3476 revs = list(revs)
3447 # don't mutate while iterating, create a copy
3477 # don't mutate while iterating, create a copy
3448 for rev in list(revs):
3478 for rev in list(revs):
3449 if rev in ancestors:
3479 if rev in ancestors:
3450 ui.warn(_('skipping ancestor revision %d:%s\n') %
3480 ui.warn(_('skipping ancestor revision %d:%s\n') %
3451 (rev, repo[rev]))
3481 (rev, repo[rev]))
3452 # XXX remove on list is slow
3482 # XXX remove on list is slow
3453 revs.remove(rev)
3483 revs.remove(rev)
3454 if not revs:
3484 if not revs:
3455 return -1
3485 return -1
3456
3486
3457 # analyze revs for earlier grafts
3487 # analyze revs for earlier grafts
3458 ids = {}
3488 ids = {}
3459 for ctx in repo.set("%ld", revs):
3489 for ctx in repo.set("%ld", revs):
3460 ids[ctx.hex()] = ctx.rev()
3490 ids[ctx.hex()] = ctx.rev()
3461 n = ctx.extra().get('source')
3491 n = ctx.extra().get('source')
3462 if n:
3492 if n:
3463 ids[n] = ctx.rev()
3493 ids[n] = ctx.rev()
3464
3494
3465 # check ancestors for earlier grafts
3495 # check ancestors for earlier grafts
3466 ui.debug('scanning for duplicate grafts\n')
3496 ui.debug('scanning for duplicate grafts\n')
3467
3497
3468 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3498 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3469 ctx = repo[rev]
3499 ctx = repo[rev]
3470 n = ctx.extra().get('source')
3500 n = ctx.extra().get('source')
3471 if n in ids:
3501 if n in ids:
3472 try:
3502 try:
3473 r = repo[n].rev()
3503 r = repo[n].rev()
3474 except error.RepoLookupError:
3504 except error.RepoLookupError:
3475 r = None
3505 r = None
3476 if r in revs:
3506 if r in revs:
3477 ui.warn(_('skipping revision %d:%s '
3507 ui.warn(_('skipping revision %d:%s '
3478 '(already grafted to %d:%s)\n')
3508 '(already grafted to %d:%s)\n')
3479 % (r, repo[r], rev, ctx))
3509 % (r, repo[r], rev, ctx))
3480 revs.remove(r)
3510 revs.remove(r)
3481 elif ids[n] in revs:
3511 elif ids[n] in revs:
3482 if r is None:
3512 if r is None:
3483 ui.warn(_('skipping already grafted revision %d:%s '
3513 ui.warn(_('skipping already grafted revision %d:%s '
3484 '(%d:%s also has unknown origin %s)\n')
3514 '(%d:%s also has unknown origin %s)\n')
3485 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
3515 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
3486 else:
3516 else:
3487 ui.warn(_('skipping already grafted revision %d:%s '
3517 ui.warn(_('skipping already grafted revision %d:%s '
3488 '(%d:%s also has origin %d:%s)\n')
3518 '(%d:%s also has origin %d:%s)\n')
3489 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
3519 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
3490 revs.remove(ids[n])
3520 revs.remove(ids[n])
3491 elif ctx.hex() in ids:
3521 elif ctx.hex() in ids:
3492 r = ids[ctx.hex()]
3522 r = ids[ctx.hex()]
3493 ui.warn(_('skipping already grafted revision %d:%s '
3523 ui.warn(_('skipping already grafted revision %d:%s '
3494 '(was grafted from %d:%s)\n') %
3524 '(was grafted from %d:%s)\n') %
3495 (r, repo[r], rev, ctx))
3525 (r, repo[r], rev, ctx))
3496 revs.remove(r)
3526 revs.remove(r)
3497 if not revs:
3527 if not revs:
3498 return -1
3528 return -1
3499
3529
3500 wlock = repo.wlock()
3530 wlock = repo.wlock()
3501 try:
3531 try:
3502 for pos, ctx in enumerate(repo.set("%ld", revs)):
3532 for pos, ctx in enumerate(repo.set("%ld", revs)):
3503 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
3533 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
3504 ctx.description().split('\n', 1)[0])
3534 ctx.description().split('\n', 1)[0])
3505 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3535 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3506 if names:
3536 if names:
3507 desc += ' (%s)' % ' '.join(names)
3537 desc += ' (%s)' % ' '.join(names)
3508 ui.status(_('grafting %s\n') % desc)
3538 ui.status(_('grafting %s\n') % desc)
3509 if opts.get('dry_run'):
3539 if opts.get('dry_run'):
3510 continue
3540 continue
3511
3541
3512 source = ctx.extra().get('source')
3542 source = ctx.extra().get('source')
3513 if not source:
3543 if not source:
3514 source = ctx.hex()
3544 source = ctx.hex()
3515 extra = {'source': source}
3545 extra = {'source': source}
3516 user = ctx.user()
3546 user = ctx.user()
3517 if opts.get('user'):
3547 if opts.get('user'):
3518 user = opts['user']
3548 user = opts['user']
3519 date = ctx.date()
3549 date = ctx.date()
3520 if opts.get('date'):
3550 if opts.get('date'):
3521 date = opts['date']
3551 date = opts['date']
3522 message = ctx.description()
3552 message = ctx.description()
3523 if opts.get('log'):
3553 if opts.get('log'):
3524 message += '\n(grafted from %s)' % ctx.hex()
3554 message += '\n(grafted from %s)' % ctx.hex()
3525
3555
3526 # we don't merge the first commit when continuing
3556 # we don't merge the first commit when continuing
3527 if not cont:
3557 if not cont:
3528 # perform the graft merge with p1(rev) as 'ancestor'
3558 # perform the graft merge with p1(rev) as 'ancestor'
3529 try:
3559 try:
3530 # ui.forcemerge is an internal variable, do not document
3560 # ui.forcemerge is an internal variable, do not document
3531 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
3561 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
3532 'graft')
3562 'graft')
3533 stats = mergemod.graft(repo, ctx, ctx.p1(),
3563 stats = mergemod.graft(repo, ctx, ctx.p1(),
3534 ['local', 'graft'])
3564 ['local', 'graft'])
3535 finally:
3565 finally:
3536 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
3566 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
3537 # report any conflicts
3567 # report any conflicts
3538 if stats and stats[3] > 0:
3568 if stats and stats[3] > 0:
3539 # write out state for --continue
3569 # write out state for --continue
3540 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3570 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3541 repo.vfs.write('graftstate', ''.join(nodelines))
3571 repo.vfs.write('graftstate', ''.join(nodelines))
3542 raise util.Abort(
3572 raise util.Abort(
3543 _("unresolved conflicts, can't continue"),
3573 _("unresolved conflicts, can't continue"),
3544 hint=_('use hg resolve and hg graft --continue'))
3574 hint=_('use hg resolve and hg graft --continue'))
3545 else:
3575 else:
3546 cont = False
3576 cont = False
3547
3577
3548 # commit
3578 # commit
3549 node = repo.commit(text=message, user=user,
3579 node = repo.commit(text=message, user=user,
3550 date=date, extra=extra, editor=editor)
3580 date=date, extra=extra, editor=editor)
3551 if node is None:
3581 if node is None:
3552 ui.warn(
3582 ui.warn(
3553 _('note: graft of %d:%s created no changes to commit\n') %
3583 _('note: graft of %d:%s created no changes to commit\n') %
3554 (ctx.rev(), ctx))
3584 (ctx.rev(), ctx))
3555 finally:
3585 finally:
3556 wlock.release()
3586 wlock.release()
3557
3587
3558 # remove state when we complete successfully
3588 # remove state when we complete successfully
3559 if not opts.get('dry_run'):
3589 if not opts.get('dry_run'):
3560 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3590 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3561
3591
3562 return 0
3592 return 0
3563
3593
3564 @command('grep',
3594 @command('grep',
3565 [('0', 'print0', None, _('end fields with NUL')),
3595 [('0', 'print0', None, _('end fields with NUL')),
3566 ('', 'all', None, _('print all revisions that match')),
3596 ('', 'all', None, _('print all revisions that match')),
3567 ('a', 'text', None, _('treat all files as text')),
3597 ('a', 'text', None, _('treat all files as text')),
3568 ('f', 'follow', None,
3598 ('f', 'follow', None,
3569 _('follow changeset history,'
3599 _('follow changeset history,'
3570 ' or file history across copies and renames')),
3600 ' or file history across copies and renames')),
3571 ('i', 'ignore-case', None, _('ignore case when matching')),
3601 ('i', 'ignore-case', None, _('ignore case when matching')),
3572 ('l', 'files-with-matches', None,
3602 ('l', 'files-with-matches', None,
3573 _('print only filenames and revisions that match')),
3603 _('print only filenames and revisions that match')),
3574 ('n', 'line-number', None, _('print matching line numbers')),
3604 ('n', 'line-number', None, _('print matching line numbers')),
3575 ('r', 'rev', [],
3605 ('r', 'rev', [],
3576 _('only search files changed within revision range'), _('REV')),
3606 _('only search files changed within revision range'), _('REV')),
3577 ('u', 'user', None, _('list the author (long with -v)')),
3607 ('u', 'user', None, _('list the author (long with -v)')),
3578 ('d', 'date', None, _('list the date (short with -q)')),
3608 ('d', 'date', None, _('list the date (short with -q)')),
3579 ] + walkopts,
3609 ] + walkopts,
3580 _('[OPTION]... PATTERN [FILE]...'),
3610 _('[OPTION]... PATTERN [FILE]...'),
3581 inferrepo=True)
3611 inferrepo=True)
3582 def grep(ui, repo, pattern, *pats, **opts):
3612 def grep(ui, repo, pattern, *pats, **opts):
3583 """search for a pattern in specified files and revisions
3613 """search for a pattern in specified files and revisions
3584
3614
3585 Search revisions of files for a regular expression.
3615 Search revisions of files for a regular expression.
3586
3616
3587 This command behaves differently than Unix grep. It only accepts
3617 This command behaves differently than Unix grep. It only accepts
3588 Python/Perl regexps. It searches repository history, not the
3618 Python/Perl regexps. It searches repository history, not the
3589 working directory. It always prints the revision number in which a
3619 working directory. It always prints the revision number in which a
3590 match appears.
3620 match appears.
3591
3621
3592 By default, grep only prints output for the first revision of a
3622 By default, grep only prints output for the first revision of a
3593 file in which it finds a match. To get it to print every revision
3623 file in which it finds a match. To get it to print every revision
3594 that contains a change in match status ("-" for a match that
3624 that contains a change in match status ("-" for a match that
3595 becomes a non-match, or "+" for a non-match that becomes a match),
3625 becomes a non-match, or "+" for a non-match that becomes a match),
3596 use the --all flag.
3626 use the --all flag.
3597
3627
3598 Returns 0 if a match is found, 1 otherwise.
3628 Returns 0 if a match is found, 1 otherwise.
3599 """
3629 """
3600 reflags = re.M
3630 reflags = re.M
3601 if opts.get('ignore_case'):
3631 if opts.get('ignore_case'):
3602 reflags |= re.I
3632 reflags |= re.I
3603 try:
3633 try:
3604 regexp = util.re.compile(pattern, reflags)
3634 regexp = util.re.compile(pattern, reflags)
3605 except re.error, inst:
3635 except re.error, inst:
3606 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3636 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3607 return 1
3637 return 1
3608 sep, eol = ':', '\n'
3638 sep, eol = ':', '\n'
3609 if opts.get('print0'):
3639 if opts.get('print0'):
3610 sep = eol = '\0'
3640 sep = eol = '\0'
3611
3641
3612 getfile = util.lrucachefunc(repo.file)
3642 getfile = util.lrucachefunc(repo.file)
3613
3643
3614 def matchlines(body):
3644 def matchlines(body):
3615 begin = 0
3645 begin = 0
3616 linenum = 0
3646 linenum = 0
3617 while begin < len(body):
3647 while begin < len(body):
3618 match = regexp.search(body, begin)
3648 match = regexp.search(body, begin)
3619 if not match:
3649 if not match:
3620 break
3650 break
3621 mstart, mend = match.span()
3651 mstart, mend = match.span()
3622 linenum += body.count('\n', begin, mstart) + 1
3652 linenum += body.count('\n', begin, mstart) + 1
3623 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3653 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3624 begin = body.find('\n', mend) + 1 or len(body) + 1
3654 begin = body.find('\n', mend) + 1 or len(body) + 1
3625 lend = begin - 1
3655 lend = begin - 1
3626 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3656 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3627
3657
3628 class linestate(object):
3658 class linestate(object):
3629 def __init__(self, line, linenum, colstart, colend):
3659 def __init__(self, line, linenum, colstart, colend):
3630 self.line = line
3660 self.line = line
3631 self.linenum = linenum
3661 self.linenum = linenum
3632 self.colstart = colstart
3662 self.colstart = colstart
3633 self.colend = colend
3663 self.colend = colend
3634
3664
3635 def __hash__(self):
3665 def __hash__(self):
3636 return hash((self.linenum, self.line))
3666 return hash((self.linenum, self.line))
3637
3667
3638 def __eq__(self, other):
3668 def __eq__(self, other):
3639 return self.line == other.line
3669 return self.line == other.line
3640
3670
3641 def __iter__(self):
3671 def __iter__(self):
3642 yield (self.line[:self.colstart], '')
3672 yield (self.line[:self.colstart], '')
3643 yield (self.line[self.colstart:self.colend], 'grep.match')
3673 yield (self.line[self.colstart:self.colend], 'grep.match')
3644 rest = self.line[self.colend:]
3674 rest = self.line[self.colend:]
3645 while rest != '':
3675 while rest != '':
3646 match = regexp.search(rest)
3676 match = regexp.search(rest)
3647 if not match:
3677 if not match:
3648 yield (rest, '')
3678 yield (rest, '')
3649 break
3679 break
3650 mstart, mend = match.span()
3680 mstart, mend = match.span()
3651 yield (rest[:mstart], '')
3681 yield (rest[:mstart], '')
3652 yield (rest[mstart:mend], 'grep.match')
3682 yield (rest[mstart:mend], 'grep.match')
3653 rest = rest[mend:]
3683 rest = rest[mend:]
3654
3684
3655 matches = {}
3685 matches = {}
3656 copies = {}
3686 copies = {}
3657 def grepbody(fn, rev, body):
3687 def grepbody(fn, rev, body):
3658 matches[rev].setdefault(fn, [])
3688 matches[rev].setdefault(fn, [])
3659 m = matches[rev][fn]
3689 m = matches[rev][fn]
3660 for lnum, cstart, cend, line in matchlines(body):
3690 for lnum, cstart, cend, line in matchlines(body):
3661 s = linestate(line, lnum, cstart, cend)
3691 s = linestate(line, lnum, cstart, cend)
3662 m.append(s)
3692 m.append(s)
3663
3693
3664 def difflinestates(a, b):
3694 def difflinestates(a, b):
3665 sm = difflib.SequenceMatcher(None, a, b)
3695 sm = difflib.SequenceMatcher(None, a, b)
3666 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3696 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3667 if tag == 'insert':
3697 if tag == 'insert':
3668 for i in xrange(blo, bhi):
3698 for i in xrange(blo, bhi):
3669 yield ('+', b[i])
3699 yield ('+', b[i])
3670 elif tag == 'delete':
3700 elif tag == 'delete':
3671 for i in xrange(alo, ahi):
3701 for i in xrange(alo, ahi):
3672 yield ('-', a[i])
3702 yield ('-', a[i])
3673 elif tag == 'replace':
3703 elif tag == 'replace':
3674 for i in xrange(alo, ahi):
3704 for i in xrange(alo, ahi):
3675 yield ('-', a[i])
3705 yield ('-', a[i])
3676 for i in xrange(blo, bhi):
3706 for i in xrange(blo, bhi):
3677 yield ('+', b[i])
3707 yield ('+', b[i])
3678
3708
3679 def display(fn, ctx, pstates, states):
3709 def display(fn, ctx, pstates, states):
3680 rev = ctx.rev()
3710 rev = ctx.rev()
3681 if ui.quiet:
3711 if ui.quiet:
3682 datefunc = util.shortdate
3712 datefunc = util.shortdate
3683 else:
3713 else:
3684 datefunc = util.datestr
3714 datefunc = util.datestr
3685 found = False
3715 found = False
3686 @util.cachefunc
3716 @util.cachefunc
3687 def binary():
3717 def binary():
3688 flog = getfile(fn)
3718 flog = getfile(fn)
3689 return util.binary(flog.read(ctx.filenode(fn)))
3719 return util.binary(flog.read(ctx.filenode(fn)))
3690
3720
3691 if opts.get('all'):
3721 if opts.get('all'):
3692 iter = difflinestates(pstates, states)
3722 iter = difflinestates(pstates, states)
3693 else:
3723 else:
3694 iter = [('', l) for l in states]
3724 iter = [('', l) for l in states]
3695 for change, l in iter:
3725 for change, l in iter:
3696 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3726 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3697
3727
3698 if opts.get('line_number'):
3728 if opts.get('line_number'):
3699 cols.append((str(l.linenum), 'grep.linenumber'))
3729 cols.append((str(l.linenum), 'grep.linenumber'))
3700 if opts.get('all'):
3730 if opts.get('all'):
3701 cols.append((change, 'grep.change'))
3731 cols.append((change, 'grep.change'))
3702 if opts.get('user'):
3732 if opts.get('user'):
3703 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3733 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3704 if opts.get('date'):
3734 if opts.get('date'):
3705 cols.append((datefunc(ctx.date()), 'grep.date'))
3735 cols.append((datefunc(ctx.date()), 'grep.date'))
3706 for col, label in cols[:-1]:
3736 for col, label in cols[:-1]:
3707 ui.write(col, label=label)
3737 ui.write(col, label=label)
3708 ui.write(sep, label='grep.sep')
3738 ui.write(sep, label='grep.sep')
3709 ui.write(cols[-1][0], label=cols[-1][1])
3739 ui.write(cols[-1][0], label=cols[-1][1])
3710 if not opts.get('files_with_matches'):
3740 if not opts.get('files_with_matches'):
3711 ui.write(sep, label='grep.sep')
3741 ui.write(sep, label='grep.sep')
3712 if not opts.get('text') and binary():
3742 if not opts.get('text') and binary():
3713 ui.write(" Binary file matches")
3743 ui.write(" Binary file matches")
3714 else:
3744 else:
3715 for s, label in l:
3745 for s, label in l:
3716 ui.write(s, label=label)
3746 ui.write(s, label=label)
3717 ui.write(eol)
3747 ui.write(eol)
3718 found = True
3748 found = True
3719 if opts.get('files_with_matches'):
3749 if opts.get('files_with_matches'):
3720 break
3750 break
3721 return found
3751 return found
3722
3752
3723 skip = {}
3753 skip = {}
3724 revfiles = {}
3754 revfiles = {}
3725 matchfn = scmutil.match(repo[None], pats, opts)
3755 matchfn = scmutil.match(repo[None], pats, opts)
3726 found = False
3756 found = False
3727 follow = opts.get('follow')
3757 follow = opts.get('follow')
3728
3758
3729 def prep(ctx, fns):
3759 def prep(ctx, fns):
3730 rev = ctx.rev()
3760 rev = ctx.rev()
3731 pctx = ctx.p1()
3761 pctx = ctx.p1()
3732 parent = pctx.rev()
3762 parent = pctx.rev()
3733 matches.setdefault(rev, {})
3763 matches.setdefault(rev, {})
3734 matches.setdefault(parent, {})
3764 matches.setdefault(parent, {})
3735 files = revfiles.setdefault(rev, [])
3765 files = revfiles.setdefault(rev, [])
3736 for fn in fns:
3766 for fn in fns:
3737 flog = getfile(fn)
3767 flog = getfile(fn)
3738 try:
3768 try:
3739 fnode = ctx.filenode(fn)
3769 fnode = ctx.filenode(fn)
3740 except error.LookupError:
3770 except error.LookupError:
3741 continue
3771 continue
3742
3772
3743 copied = flog.renamed(fnode)
3773 copied = flog.renamed(fnode)
3744 copy = follow and copied and copied[0]
3774 copy = follow and copied and copied[0]
3745 if copy:
3775 if copy:
3746 copies.setdefault(rev, {})[fn] = copy
3776 copies.setdefault(rev, {})[fn] = copy
3747 if fn in skip:
3777 if fn in skip:
3748 if copy:
3778 if copy:
3749 skip[copy] = True
3779 skip[copy] = True
3750 continue
3780 continue
3751 files.append(fn)
3781 files.append(fn)
3752
3782
3753 if fn not in matches[rev]:
3783 if fn not in matches[rev]:
3754 grepbody(fn, rev, flog.read(fnode))
3784 grepbody(fn, rev, flog.read(fnode))
3755
3785
3756 pfn = copy or fn
3786 pfn = copy or fn
3757 if pfn not in matches[parent]:
3787 if pfn not in matches[parent]:
3758 try:
3788 try:
3759 fnode = pctx.filenode(pfn)
3789 fnode = pctx.filenode(pfn)
3760 grepbody(pfn, parent, flog.read(fnode))
3790 grepbody(pfn, parent, flog.read(fnode))
3761 except error.LookupError:
3791 except error.LookupError:
3762 pass
3792 pass
3763
3793
3764 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3794 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3765 rev = ctx.rev()
3795 rev = ctx.rev()
3766 parent = ctx.p1().rev()
3796 parent = ctx.p1().rev()
3767 for fn in sorted(revfiles.get(rev, [])):
3797 for fn in sorted(revfiles.get(rev, [])):
3768 states = matches[rev][fn]
3798 states = matches[rev][fn]
3769 copy = copies.get(rev, {}).get(fn)
3799 copy = copies.get(rev, {}).get(fn)
3770 if fn in skip:
3800 if fn in skip:
3771 if copy:
3801 if copy:
3772 skip[copy] = True
3802 skip[copy] = True
3773 continue
3803 continue
3774 pstates = matches.get(parent, {}).get(copy or fn, [])
3804 pstates = matches.get(parent, {}).get(copy or fn, [])
3775 if pstates or states:
3805 if pstates or states:
3776 r = display(fn, ctx, pstates, states)
3806 r = display(fn, ctx, pstates, states)
3777 found = found or r
3807 found = found or r
3778 if r and not opts.get('all'):
3808 if r and not opts.get('all'):
3779 skip[fn] = True
3809 skip[fn] = True
3780 if copy:
3810 if copy:
3781 skip[copy] = True
3811 skip[copy] = True
3782 del matches[rev]
3812 del matches[rev]
3783 del revfiles[rev]
3813 del revfiles[rev]
3784
3814
3785 return not found
3815 return not found
3786
3816
3787 @command('heads',
3817 @command('heads',
3788 [('r', 'rev', '',
3818 [('r', 'rev', '',
3789 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3819 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3790 ('t', 'topo', False, _('show topological heads only')),
3820 ('t', 'topo', False, _('show topological heads only')),
3791 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3821 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3792 ('c', 'closed', False, _('show normal and closed branch heads')),
3822 ('c', 'closed', False, _('show normal and closed branch heads')),
3793 ] + templateopts,
3823 ] + templateopts,
3794 _('[-ct] [-r STARTREV] [REV]...'))
3824 _('[-ct] [-r STARTREV] [REV]...'))
3795 def heads(ui, repo, *branchrevs, **opts):
3825 def heads(ui, repo, *branchrevs, **opts):
3796 """show branch heads
3826 """show branch heads
3797
3827
3798 With no arguments, show all open branch heads in the repository.
3828 With no arguments, show all open branch heads in the repository.
3799 Branch heads are changesets that have no descendants on the
3829 Branch heads are changesets that have no descendants on the
3800 same branch. They are where development generally takes place and
3830 same branch. They are where development generally takes place and
3801 are the usual targets for update and merge operations.
3831 are the usual targets for update and merge operations.
3802
3832
3803 If one or more REVs are given, only open branch heads on the
3833 If one or more REVs are given, only open branch heads on the
3804 branches associated with the specified changesets are shown. This
3834 branches associated with the specified changesets are shown. This
3805 means that you can use :hg:`heads .` to see the heads on the
3835 means that you can use :hg:`heads .` to see the heads on the
3806 currently checked-out branch.
3836 currently checked-out branch.
3807
3837
3808 If -c/--closed is specified, also show branch heads marked closed
3838 If -c/--closed is specified, also show branch heads marked closed
3809 (see :hg:`commit --close-branch`).
3839 (see :hg:`commit --close-branch`).
3810
3840
3811 If STARTREV is specified, only those heads that are descendants of
3841 If STARTREV is specified, only those heads that are descendants of
3812 STARTREV will be displayed.
3842 STARTREV will be displayed.
3813
3843
3814 If -t/--topo is specified, named branch mechanics will be ignored and only
3844 If -t/--topo is specified, named branch mechanics will be ignored and only
3815 topological heads (changesets with no children) will be shown.
3845 topological heads (changesets with no children) will be shown.
3816
3846
3817 Returns 0 if matching heads are found, 1 if not.
3847 Returns 0 if matching heads are found, 1 if not.
3818 """
3848 """
3819
3849
3820 start = None
3850 start = None
3821 if 'rev' in opts:
3851 if 'rev' in opts:
3822 start = scmutil.revsingle(repo, opts['rev'], None).node()
3852 start = scmutil.revsingle(repo, opts['rev'], None).node()
3823
3853
3824 if opts.get('topo'):
3854 if opts.get('topo'):
3825 heads = [repo[h] for h in repo.heads(start)]
3855 heads = [repo[h] for h in repo.heads(start)]
3826 else:
3856 else:
3827 heads = []
3857 heads = []
3828 for branch in repo.branchmap():
3858 for branch in repo.branchmap():
3829 heads += repo.branchheads(branch, start, opts.get('closed'))
3859 heads += repo.branchheads(branch, start, opts.get('closed'))
3830 heads = [repo[h] for h in heads]
3860 heads = [repo[h] for h in heads]
3831
3861
3832 if branchrevs:
3862 if branchrevs:
3833 branches = set(repo[br].branch() for br in branchrevs)
3863 branches = set(repo[br].branch() for br in branchrevs)
3834 heads = [h for h in heads if h.branch() in branches]
3864 heads = [h for h in heads if h.branch() in branches]
3835
3865
3836 if opts.get('active') and branchrevs:
3866 if opts.get('active') and branchrevs:
3837 dagheads = repo.heads(start)
3867 dagheads = repo.heads(start)
3838 heads = [h for h in heads if h.node() in dagheads]
3868 heads = [h for h in heads if h.node() in dagheads]
3839
3869
3840 if branchrevs:
3870 if branchrevs:
3841 haveheads = set(h.branch() for h in heads)
3871 haveheads = set(h.branch() for h in heads)
3842 if branches - haveheads:
3872 if branches - haveheads:
3843 headless = ', '.join(b for b in branches - haveheads)
3873 headless = ', '.join(b for b in branches - haveheads)
3844 msg = _('no open branch heads found on branches %s')
3874 msg = _('no open branch heads found on branches %s')
3845 if opts.get('rev'):
3875 if opts.get('rev'):
3846 msg += _(' (started at %s)') % opts['rev']
3876 msg += _(' (started at %s)') % opts['rev']
3847 ui.warn((msg + '\n') % headless)
3877 ui.warn((msg + '\n') % headless)
3848
3878
3849 if not heads:
3879 if not heads:
3850 return 1
3880 return 1
3851
3881
3852 heads = sorted(heads, key=lambda x: -x.rev())
3882 heads = sorted(heads, key=lambda x: -x.rev())
3853 displayer = cmdutil.show_changeset(ui, repo, opts)
3883 displayer = cmdutil.show_changeset(ui, repo, opts)
3854 for ctx in heads:
3884 for ctx in heads:
3855 displayer.show(ctx)
3885 displayer.show(ctx)
3856 displayer.close()
3886 displayer.close()
3857
3887
3858 @command('help',
3888 @command('help',
3859 [('e', 'extension', None, _('show only help for extensions')),
3889 [('e', 'extension', None, _('show only help for extensions')),
3860 ('c', 'command', None, _('show only help for commands')),
3890 ('c', 'command', None, _('show only help for commands')),
3861 ('k', 'keyword', '', _('show topics matching keyword')),
3891 ('k', 'keyword', '', _('show topics matching keyword')),
3862 ],
3892 ],
3863 _('[-ec] [TOPIC]'),
3893 _('[-ec] [TOPIC]'),
3864 norepo=True)
3894 norepo=True)
3865 def help_(ui, name=None, **opts):
3895 def help_(ui, name=None, **opts):
3866 """show help for a given topic or a help overview
3896 """show help for a given topic or a help overview
3867
3897
3868 With no arguments, print a list of commands with short help messages.
3898 With no arguments, print a list of commands with short help messages.
3869
3899
3870 Given a topic, extension, or command name, print help for that
3900 Given a topic, extension, or command name, print help for that
3871 topic.
3901 topic.
3872
3902
3873 Returns 0 if successful.
3903 Returns 0 if successful.
3874 """
3904 """
3875
3905
3876 textwidth = min(ui.termwidth(), 80) - 2
3906 textwidth = min(ui.termwidth(), 80) - 2
3877
3907
3878 keep = []
3908 keep = []
3879 if ui.verbose:
3909 if ui.verbose:
3880 keep.append('verbose')
3910 keep.append('verbose')
3881 if sys.platform.startswith('win'):
3911 if sys.platform.startswith('win'):
3882 keep.append('windows')
3912 keep.append('windows')
3883 elif sys.platform == 'OpenVMS':
3913 elif sys.platform == 'OpenVMS':
3884 keep.append('vms')
3914 keep.append('vms')
3885 elif sys.platform == 'plan9':
3915 elif sys.platform == 'plan9':
3886 keep.append('plan9')
3916 keep.append('plan9')
3887 else:
3917 else:
3888 keep.append('unix')
3918 keep.append('unix')
3889 keep.append(sys.platform.lower())
3919 keep.append(sys.platform.lower())
3890
3920
3891 section = None
3921 section = None
3892 if name and '.' in name:
3922 if name and '.' in name:
3893 name, section = name.split('.', 1)
3923 name, section = name.split('.', 1)
3894
3924
3895 text = help.help_(ui, name, **opts)
3925 text = help.help_(ui, name, **opts)
3896
3926
3897 formatted, pruned = minirst.format(text, textwidth, keep=keep,
3927 formatted, pruned = minirst.format(text, textwidth, keep=keep,
3898 section=section)
3928 section=section)
3899 if section and not formatted:
3929 if section and not formatted:
3900 raise util.Abort(_("help section not found"))
3930 raise util.Abort(_("help section not found"))
3901
3931
3902 if 'verbose' in pruned:
3932 if 'verbose' in pruned:
3903 keep.append('omitted')
3933 keep.append('omitted')
3904 else:
3934 else:
3905 keep.append('notomitted')
3935 keep.append('notomitted')
3906 formatted, pruned = minirst.format(text, textwidth, keep=keep,
3936 formatted, pruned = minirst.format(text, textwidth, keep=keep,
3907 section=section)
3937 section=section)
3908 ui.write(formatted)
3938 ui.write(formatted)
3909
3939
3910
3940
3911 @command('identify|id',
3941 @command('identify|id',
3912 [('r', 'rev', '',
3942 [('r', 'rev', '',
3913 _('identify the specified revision'), _('REV')),
3943 _('identify the specified revision'), _('REV')),
3914 ('n', 'num', None, _('show local revision number')),
3944 ('n', 'num', None, _('show local revision number')),
3915 ('i', 'id', None, _('show global revision id')),
3945 ('i', 'id', None, _('show global revision id')),
3916 ('b', 'branch', None, _('show branch')),
3946 ('b', 'branch', None, _('show branch')),
3917 ('t', 'tags', None, _('show tags')),
3947 ('t', 'tags', None, _('show tags')),
3918 ('B', 'bookmarks', None, _('show bookmarks')),
3948 ('B', 'bookmarks', None, _('show bookmarks')),
3919 ] + remoteopts,
3949 ] + remoteopts,
3920 _('[-nibtB] [-r REV] [SOURCE]'),
3950 _('[-nibtB] [-r REV] [SOURCE]'),
3921 optionalrepo=True)
3951 optionalrepo=True)
3922 def identify(ui, repo, source=None, rev=None,
3952 def identify(ui, repo, source=None, rev=None,
3923 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3953 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3924 """identify the working directory or specified revision
3954 """identify the working directory or specified revision
3925
3955
3926 Print a summary identifying the repository state at REV using one or
3956 Print a summary identifying the repository state at REV using one or
3927 two parent hash identifiers, followed by a "+" if the working
3957 two parent hash identifiers, followed by a "+" if the working
3928 directory has uncommitted changes, the branch name (if not default),
3958 directory has uncommitted changes, the branch name (if not default),
3929 a list of tags, and a list of bookmarks.
3959 a list of tags, and a list of bookmarks.
3930
3960
3931 When REV is not given, print a summary of the current state of the
3961 When REV is not given, print a summary of the current state of the
3932 repository.
3962 repository.
3933
3963
3934 Specifying a path to a repository root or Mercurial bundle will
3964 Specifying a path to a repository root or Mercurial bundle will
3935 cause lookup to operate on that repository/bundle.
3965 cause lookup to operate on that repository/bundle.
3936
3966
3937 .. container:: verbose
3967 .. container:: verbose
3938
3968
3939 Examples:
3969 Examples:
3940
3970
3941 - generate a build identifier for the working directory::
3971 - generate a build identifier for the working directory::
3942
3972
3943 hg id --id > build-id.dat
3973 hg id --id > build-id.dat
3944
3974
3945 - find the revision corresponding to a tag::
3975 - find the revision corresponding to a tag::
3946
3976
3947 hg id -n -r 1.3
3977 hg id -n -r 1.3
3948
3978
3949 - check the most recent revision of a remote repository::
3979 - check the most recent revision of a remote repository::
3950
3980
3951 hg id -r tip http://selenic.com/hg/
3981 hg id -r tip http://selenic.com/hg/
3952
3982
3953 Returns 0 if successful.
3983 Returns 0 if successful.
3954 """
3984 """
3955
3985
3956 if not repo and not source:
3986 if not repo and not source:
3957 raise util.Abort(_("there is no Mercurial repository here "
3987 raise util.Abort(_("there is no Mercurial repository here "
3958 "(.hg not found)"))
3988 "(.hg not found)"))
3959
3989
3960 if ui.debugflag:
3990 if ui.debugflag:
3961 hexfunc = hex
3991 hexfunc = hex
3962 else:
3992 else:
3963 hexfunc = short
3993 hexfunc = short
3964 default = not (num or id or branch or tags or bookmarks)
3994 default = not (num or id or branch or tags or bookmarks)
3965 output = []
3995 output = []
3966 revs = []
3996 revs = []
3967
3997
3968 if source:
3998 if source:
3969 source, branches = hg.parseurl(ui.expandpath(source))
3999 source, branches = hg.parseurl(ui.expandpath(source))
3970 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
4000 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3971 repo = peer.local()
4001 repo = peer.local()
3972 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
4002 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3973
4003
3974 if not repo:
4004 if not repo:
3975 if num or branch or tags:
4005 if num or branch or tags:
3976 raise util.Abort(
4006 raise util.Abort(
3977 _("can't query remote revision number, branch, or tags"))
4007 _("can't query remote revision number, branch, or tags"))
3978 if not rev and revs:
4008 if not rev and revs:
3979 rev = revs[0]
4009 rev = revs[0]
3980 if not rev:
4010 if not rev:
3981 rev = "tip"
4011 rev = "tip"
3982
4012
3983 remoterev = peer.lookup(rev)
4013 remoterev = peer.lookup(rev)
3984 if default or id:
4014 if default or id:
3985 output = [hexfunc(remoterev)]
4015 output = [hexfunc(remoterev)]
3986
4016
3987 def getbms():
4017 def getbms():
3988 bms = []
4018 bms = []
3989
4019
3990 if 'bookmarks' in peer.listkeys('namespaces'):
4020 if 'bookmarks' in peer.listkeys('namespaces'):
3991 hexremoterev = hex(remoterev)
4021 hexremoterev = hex(remoterev)
3992 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
4022 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3993 if bmr == hexremoterev]
4023 if bmr == hexremoterev]
3994
4024
3995 return sorted(bms)
4025 return sorted(bms)
3996
4026
3997 if bookmarks:
4027 if bookmarks:
3998 output.extend(getbms())
4028 output.extend(getbms())
3999 elif default and not ui.quiet:
4029 elif default and not ui.quiet:
4000 # multiple bookmarks for a single parent separated by '/'
4030 # multiple bookmarks for a single parent separated by '/'
4001 bm = '/'.join(getbms())
4031 bm = '/'.join(getbms())
4002 if bm:
4032 if bm:
4003 output.append(bm)
4033 output.append(bm)
4004 else:
4034 else:
4005 if not rev:
4035 if not rev:
4006 ctx = repo[None]
4036 ctx = repo[None]
4007 parents = ctx.parents()
4037 parents = ctx.parents()
4008 changed = ""
4038 changed = ""
4009 if default or id or num:
4039 if default or id or num:
4010 if (util.any(repo.status())
4040 if (util.any(repo.status())
4011 or util.any(ctx.sub(s).dirty() for s in ctx.substate)):
4041 or util.any(ctx.sub(s).dirty() for s in ctx.substate)):
4012 changed = '+'
4042 changed = '+'
4013 if default or id:
4043 if default or id:
4014 output = ["%s%s" %
4044 output = ["%s%s" %
4015 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
4045 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
4016 if num:
4046 if num:
4017 output.append("%s%s" %
4047 output.append("%s%s" %
4018 ('+'.join([str(p.rev()) for p in parents]), changed))
4048 ('+'.join([str(p.rev()) for p in parents]), changed))
4019 else:
4049 else:
4020 ctx = scmutil.revsingle(repo, rev)
4050 ctx = scmutil.revsingle(repo, rev)
4021 if default or id:
4051 if default or id:
4022 output = [hexfunc(ctx.node())]
4052 output = [hexfunc(ctx.node())]
4023 if num:
4053 if num:
4024 output.append(str(ctx.rev()))
4054 output.append(str(ctx.rev()))
4025
4055
4026 if default and not ui.quiet:
4056 if default and not ui.quiet:
4027 b = ctx.branch()
4057 b = ctx.branch()
4028 if b != 'default':
4058 if b != 'default':
4029 output.append("(%s)" % b)
4059 output.append("(%s)" % b)
4030
4060
4031 # multiple tags for a single parent separated by '/'
4061 # multiple tags for a single parent separated by '/'
4032 t = '/'.join(ctx.tags())
4062 t = '/'.join(ctx.tags())
4033 if t:
4063 if t:
4034 output.append(t)
4064 output.append(t)
4035
4065
4036 # multiple bookmarks for a single parent separated by '/'
4066 # multiple bookmarks for a single parent separated by '/'
4037 bm = '/'.join(ctx.bookmarks())
4067 bm = '/'.join(ctx.bookmarks())
4038 if bm:
4068 if bm:
4039 output.append(bm)
4069 output.append(bm)
4040 else:
4070 else:
4041 if branch:
4071 if branch:
4042 output.append(ctx.branch())
4072 output.append(ctx.branch())
4043
4073
4044 if tags:
4074 if tags:
4045 output.extend(ctx.tags())
4075 output.extend(ctx.tags())
4046
4076
4047 if bookmarks:
4077 if bookmarks:
4048 output.extend(ctx.bookmarks())
4078 output.extend(ctx.bookmarks())
4049
4079
4050 ui.write("%s\n" % ' '.join(output))
4080 ui.write("%s\n" % ' '.join(output))
4051
4081
4052 @command('import|patch',
4082 @command('import|patch',
4053 [('p', 'strip', 1,
4083 [('p', 'strip', 1,
4054 _('directory strip option for patch. This has the same '
4084 _('directory strip option for patch. This has the same '
4055 'meaning as the corresponding patch option'), _('NUM')),
4085 'meaning as the corresponding patch option'), _('NUM')),
4056 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
4086 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
4057 ('e', 'edit', False, _('invoke editor on commit messages')),
4087 ('e', 'edit', False, _('invoke editor on commit messages')),
4058 ('f', 'force', None,
4088 ('f', 'force', None,
4059 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
4089 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
4060 ('', 'no-commit', None,
4090 ('', 'no-commit', None,
4061 _("don't commit, just update the working directory")),
4091 _("don't commit, just update the working directory")),
4062 ('', 'bypass', None,
4092 ('', 'bypass', None,
4063 _("apply patch without touching the working directory")),
4093 _("apply patch without touching the working directory")),
4064 ('', 'partial', None,
4094 ('', 'partial', None,
4065 _('commit even if some hunks fail')),
4095 _('commit even if some hunks fail')),
4066 ('', 'exact', None,
4096 ('', 'exact', None,
4067 _('apply patch to the nodes from which it was generated')),
4097 _('apply patch to the nodes from which it was generated')),
4068 ('', 'prefix', '',
4098 ('', 'prefix', '',
4069 _('apply patch to subdirectory'), _('DIR')),
4099 _('apply patch to subdirectory'), _('DIR')),
4070 ('', 'import-branch', None,
4100 ('', 'import-branch', None,
4071 _('use any branch information in patch (implied by --exact)'))] +
4101 _('use any branch information in patch (implied by --exact)'))] +
4072 commitopts + commitopts2 + similarityopts,
4102 commitopts + commitopts2 + similarityopts,
4073 _('[OPTION]... PATCH...'))
4103 _('[OPTION]... PATCH...'))
4074 def import_(ui, repo, patch1=None, *patches, **opts):
4104 def import_(ui, repo, patch1=None, *patches, **opts):
4075 """import an ordered set of patches
4105 """import an ordered set of patches
4076
4106
4077 Import a list of patches and commit them individually (unless
4107 Import a list of patches and commit them individually (unless
4078 --no-commit is specified).
4108 --no-commit is specified).
4079
4109
4080 Because import first applies changes to the working directory,
4110 Because import first applies changes to the working directory,
4081 import will abort if there are outstanding changes.
4111 import will abort if there are outstanding changes.
4082
4112
4083 You can import a patch straight from a mail message. Even patches
4113 You can import a patch straight from a mail message. Even patches
4084 as attachments work (to use the body part, it must have type
4114 as attachments work (to use the body part, it must have type
4085 text/plain or text/x-patch). From and Subject headers of email
4115 text/plain or text/x-patch). From and Subject headers of email
4086 message are used as default committer and commit message. All
4116 message are used as default committer and commit message. All
4087 text/plain body parts before first diff are added to commit
4117 text/plain body parts before first diff are added to commit
4088 message.
4118 message.
4089
4119
4090 If the imported patch was generated by :hg:`export`, user and
4120 If the imported patch was generated by :hg:`export`, user and
4091 description from patch override values from message headers and
4121 description from patch override values from message headers and
4092 body. Values given on command line with -m/--message and -u/--user
4122 body. Values given on command line with -m/--message and -u/--user
4093 override these.
4123 override these.
4094
4124
4095 If --exact is specified, import will set the working directory to
4125 If --exact is specified, import will set the working directory to
4096 the parent of each patch before applying it, and will abort if the
4126 the parent of each patch before applying it, and will abort if the
4097 resulting changeset has a different ID than the one recorded in
4127 resulting changeset has a different ID than the one recorded in
4098 the patch. This may happen due to character set problems or other
4128 the patch. This may happen due to character set problems or other
4099 deficiencies in the text patch format.
4129 deficiencies in the text patch format.
4100
4130
4101 Use --bypass to apply and commit patches directly to the
4131 Use --bypass to apply and commit patches directly to the
4102 repository, not touching the working directory. Without --exact,
4132 repository, not touching the working directory. Without --exact,
4103 patches will be applied on top of the working directory parent
4133 patches will be applied on top of the working directory parent
4104 revision.
4134 revision.
4105
4135
4106 With -s/--similarity, hg will attempt to discover renames and
4136 With -s/--similarity, hg will attempt to discover renames and
4107 copies in the patch in the same way as :hg:`addremove`.
4137 copies in the patch in the same way as :hg:`addremove`.
4108
4138
4109 Use --partial to ensure a changeset will be created from the patch
4139 Use --partial to ensure a changeset will be created from the patch
4110 even if some hunks fail to apply. Hunks that fail to apply will be
4140 even if some hunks fail to apply. Hunks that fail to apply will be
4111 written to a <target-file>.rej file. Conflicts can then be resolved
4141 written to a <target-file>.rej file. Conflicts can then be resolved
4112 by hand before :hg:`commit --amend` is run to update the created
4142 by hand before :hg:`commit --amend` is run to update the created
4113 changeset. This flag exists to let people import patches that
4143 changeset. This flag exists to let people import patches that
4114 partially apply without losing the associated metadata (author,
4144 partially apply without losing the associated metadata (author,
4115 date, description, ...). Note that when none of the hunk applies
4145 date, description, ...). Note that when none of the hunk applies
4116 cleanly, :hg:`import --partial` will create an empty changeset,
4146 cleanly, :hg:`import --partial` will create an empty changeset,
4117 importing only the patch metadata.
4147 importing only the patch metadata.
4118
4148
4119 To read a patch from standard input, use "-" as the patch name. If
4149 To read a patch from standard input, use "-" as the patch name. If
4120 a URL is specified, the patch will be downloaded from it.
4150 a URL is specified, the patch will be downloaded from it.
4121 See :hg:`help dates` for a list of formats valid for -d/--date.
4151 See :hg:`help dates` for a list of formats valid for -d/--date.
4122
4152
4123 .. container:: verbose
4153 .. container:: verbose
4124
4154
4125 Examples:
4155 Examples:
4126
4156
4127 - import a traditional patch from a website and detect renames::
4157 - import a traditional patch from a website and detect renames::
4128
4158
4129 hg import -s 80 http://example.com/bugfix.patch
4159 hg import -s 80 http://example.com/bugfix.patch
4130
4160
4131 - import a changeset from an hgweb server::
4161 - import a changeset from an hgweb server::
4132
4162
4133 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
4163 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
4134
4164
4135 - import all the patches in an Unix-style mbox::
4165 - import all the patches in an Unix-style mbox::
4136
4166
4137 hg import incoming-patches.mbox
4167 hg import incoming-patches.mbox
4138
4168
4139 - attempt to exactly restore an exported changeset (not always
4169 - attempt to exactly restore an exported changeset (not always
4140 possible)::
4170 possible)::
4141
4171
4142 hg import --exact proposed-fix.patch
4172 hg import --exact proposed-fix.patch
4143
4173
4144 Returns 0 on success, 1 on partial success (see --partial).
4174 Returns 0 on success, 1 on partial success (see --partial).
4145 """
4175 """
4146
4176
4147 if not patch1:
4177 if not patch1:
4148 raise util.Abort(_('need at least one patch to import'))
4178 raise util.Abort(_('need at least one patch to import'))
4149
4179
4150 patches = (patch1,) + patches
4180 patches = (patch1,) + patches
4151
4181
4152 date = opts.get('date')
4182 date = opts.get('date')
4153 if date:
4183 if date:
4154 opts['date'] = util.parsedate(date)
4184 opts['date'] = util.parsedate(date)
4155
4185
4156 update = not opts.get('bypass')
4186 update = not opts.get('bypass')
4157 if not update and opts.get('no_commit'):
4187 if not update and opts.get('no_commit'):
4158 raise util.Abort(_('cannot use --no-commit with --bypass'))
4188 raise util.Abort(_('cannot use --no-commit with --bypass'))
4159 try:
4189 try:
4160 sim = float(opts.get('similarity') or 0)
4190 sim = float(opts.get('similarity') or 0)
4161 except ValueError:
4191 except ValueError:
4162 raise util.Abort(_('similarity must be a number'))
4192 raise util.Abort(_('similarity must be a number'))
4163 if sim < 0 or sim > 100:
4193 if sim < 0 or sim > 100:
4164 raise util.Abort(_('similarity must be between 0 and 100'))
4194 raise util.Abort(_('similarity must be between 0 and 100'))
4165 if sim and not update:
4195 if sim and not update:
4166 raise util.Abort(_('cannot use --similarity with --bypass'))
4196 raise util.Abort(_('cannot use --similarity with --bypass'))
4167 if opts.get('exact') and opts.get('edit'):
4197 if opts.get('exact') and opts.get('edit'):
4168 raise util.Abort(_('cannot use --exact with --edit'))
4198 raise util.Abort(_('cannot use --exact with --edit'))
4169 if opts.get('exact') and opts.get('prefix'):
4199 if opts.get('exact') and opts.get('prefix'):
4170 raise util.Abort(_('cannot use --exact with --prefix'))
4200 raise util.Abort(_('cannot use --exact with --prefix'))
4171
4201
4172 if update:
4202 if update:
4173 cmdutil.checkunfinished(repo)
4203 cmdutil.checkunfinished(repo)
4174 if (opts.get('exact') or not opts.get('force')) and update:
4204 if (opts.get('exact') or not opts.get('force')) and update:
4175 cmdutil.bailifchanged(repo)
4205 cmdutil.bailifchanged(repo)
4176
4206
4177 base = opts["base"]
4207 base = opts["base"]
4178 wlock = lock = tr = None
4208 wlock = lock = tr = None
4179 msgs = []
4209 msgs = []
4180 ret = 0
4210 ret = 0
4181
4211
4182
4212
4183 try:
4213 try:
4184 try:
4214 try:
4185 wlock = repo.wlock()
4215 wlock = repo.wlock()
4186 repo.dirstate.beginparentchange()
4216 repo.dirstate.beginparentchange()
4187 if not opts.get('no_commit'):
4217 if not opts.get('no_commit'):
4188 lock = repo.lock()
4218 lock = repo.lock()
4189 tr = repo.transaction('import')
4219 tr = repo.transaction('import')
4190 parents = repo.parents()
4220 parents = repo.parents()
4191 for patchurl in patches:
4221 for patchurl in patches:
4192 if patchurl == '-':
4222 if patchurl == '-':
4193 ui.status(_('applying patch from stdin\n'))
4223 ui.status(_('applying patch from stdin\n'))
4194 patchfile = ui.fin
4224 patchfile = ui.fin
4195 patchurl = 'stdin' # for error message
4225 patchurl = 'stdin' # for error message
4196 else:
4226 else:
4197 patchurl = os.path.join(base, patchurl)
4227 patchurl = os.path.join(base, patchurl)
4198 ui.status(_('applying %s\n') % patchurl)
4228 ui.status(_('applying %s\n') % patchurl)
4199 patchfile = hg.openpath(ui, patchurl)
4229 patchfile = hg.openpath(ui, patchurl)
4200
4230
4201 haspatch = False
4231 haspatch = False
4202 for hunk in patch.split(patchfile):
4232 for hunk in patch.split(patchfile):
4203 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
4233 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
4204 parents, opts,
4234 parents, opts,
4205 msgs, hg.clean)
4235 msgs, hg.clean)
4206 if msg:
4236 if msg:
4207 haspatch = True
4237 haspatch = True
4208 ui.note(msg + '\n')
4238 ui.note(msg + '\n')
4209 if update or opts.get('exact'):
4239 if update or opts.get('exact'):
4210 parents = repo.parents()
4240 parents = repo.parents()
4211 else:
4241 else:
4212 parents = [repo[node]]
4242 parents = [repo[node]]
4213 if rej:
4243 if rej:
4214 ui.write_err(_("patch applied partially\n"))
4244 ui.write_err(_("patch applied partially\n"))
4215 ui.write_err(_("(fix the .rej files and run "
4245 ui.write_err(_("(fix the .rej files and run "
4216 "`hg commit --amend`)\n"))
4246 "`hg commit --amend`)\n"))
4217 ret = 1
4247 ret = 1
4218 break
4248 break
4219
4249
4220 if not haspatch:
4250 if not haspatch:
4221 raise util.Abort(_('%s: no diffs found') % patchurl)
4251 raise util.Abort(_('%s: no diffs found') % patchurl)
4222
4252
4223 if tr:
4253 if tr:
4224 tr.close()
4254 tr.close()
4225 if msgs:
4255 if msgs:
4226 repo.savecommitmessage('\n* * *\n'.join(msgs))
4256 repo.savecommitmessage('\n* * *\n'.join(msgs))
4227 repo.dirstate.endparentchange()
4257 repo.dirstate.endparentchange()
4228 return ret
4258 return ret
4229 except: # re-raises
4259 except: # re-raises
4230 # wlock.release() indirectly calls dirstate.write(): since
4260 # wlock.release() indirectly calls dirstate.write(): since
4231 # we're crashing, we do not want to change the working dir
4261 # we're crashing, we do not want to change the working dir
4232 # parent after all, so make sure it writes nothing
4262 # parent after all, so make sure it writes nothing
4233 repo.dirstate.invalidate()
4263 repo.dirstate.invalidate()
4234 raise
4264 raise
4235 finally:
4265 finally:
4236 if tr:
4266 if tr:
4237 tr.release()
4267 tr.release()
4238 release(lock, wlock)
4268 release(lock, wlock)
4239
4269
4240 @command('incoming|in',
4270 @command('incoming|in',
4241 [('f', 'force', None,
4271 [('f', 'force', None,
4242 _('run even if remote repository is unrelated')),
4272 _('run even if remote repository is unrelated')),
4243 ('n', 'newest-first', None, _('show newest record first')),
4273 ('n', 'newest-first', None, _('show newest record first')),
4244 ('', 'bundle', '',
4274 ('', 'bundle', '',
4245 _('file to store the bundles into'), _('FILE')),
4275 _('file to store the bundles into'), _('FILE')),
4246 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4276 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4247 ('B', 'bookmarks', False, _("compare bookmarks")),
4277 ('B', 'bookmarks', False, _("compare bookmarks")),
4248 ('b', 'branch', [],
4278 ('b', 'branch', [],
4249 _('a specific branch you would like to pull'), _('BRANCH')),
4279 _('a specific branch you would like to pull'), _('BRANCH')),
4250 ] + logopts + remoteopts + subrepoopts,
4280 ] + logopts + remoteopts + subrepoopts,
4251 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
4281 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
4252 def incoming(ui, repo, source="default", **opts):
4282 def incoming(ui, repo, source="default", **opts):
4253 """show new changesets found in source
4283 """show new changesets found in source
4254
4284
4255 Show new changesets found in the specified path/URL or the default
4285 Show new changesets found in the specified path/URL or the default
4256 pull location. These are the changesets that would have been pulled
4286 pull location. These are the changesets that would have been pulled
4257 if a pull at the time you issued this command.
4287 if a pull at the time you issued this command.
4258
4288
4259 See pull for valid source format details.
4289 See pull for valid source format details.
4260
4290
4261 .. container:: verbose
4291 .. container:: verbose
4262
4292
4263 For remote repository, using --bundle avoids downloading the
4293 For remote repository, using --bundle avoids downloading the
4264 changesets twice if the incoming is followed by a pull.
4294 changesets twice if the incoming is followed by a pull.
4265
4295
4266 Examples:
4296 Examples:
4267
4297
4268 - show incoming changes with patches and full description::
4298 - show incoming changes with patches and full description::
4269
4299
4270 hg incoming -vp
4300 hg incoming -vp
4271
4301
4272 - show incoming changes excluding merges, store a bundle::
4302 - show incoming changes excluding merges, store a bundle::
4273
4303
4274 hg in -vpM --bundle incoming.hg
4304 hg in -vpM --bundle incoming.hg
4275 hg pull incoming.hg
4305 hg pull incoming.hg
4276
4306
4277 - briefly list changes inside a bundle::
4307 - briefly list changes inside a bundle::
4278
4308
4279 hg in changes.hg -T "{desc|firstline}\\n"
4309 hg in changes.hg -T "{desc|firstline}\\n"
4280
4310
4281 Returns 0 if there are incoming changes, 1 otherwise.
4311 Returns 0 if there are incoming changes, 1 otherwise.
4282 """
4312 """
4283 if opts.get('graph'):
4313 if opts.get('graph'):
4284 cmdutil.checkunsupportedgraphflags([], opts)
4314 cmdutil.checkunsupportedgraphflags([], opts)
4285 def display(other, chlist, displayer):
4315 def display(other, chlist, displayer):
4286 revdag = cmdutil.graphrevs(other, chlist, opts)
4316 revdag = cmdutil.graphrevs(other, chlist, opts)
4287 showparents = [ctx.node() for ctx in repo[None].parents()]
4317 showparents = [ctx.node() for ctx in repo[None].parents()]
4288 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4318 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4289 graphmod.asciiedges)
4319 graphmod.asciiedges)
4290
4320
4291 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4321 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4292 return 0
4322 return 0
4293
4323
4294 if opts.get('bundle') and opts.get('subrepos'):
4324 if opts.get('bundle') and opts.get('subrepos'):
4295 raise util.Abort(_('cannot combine --bundle and --subrepos'))
4325 raise util.Abort(_('cannot combine --bundle and --subrepos'))
4296
4326
4297 if opts.get('bookmarks'):
4327 if opts.get('bookmarks'):
4298 source, branches = hg.parseurl(ui.expandpath(source),
4328 source, branches = hg.parseurl(ui.expandpath(source),
4299 opts.get('branch'))
4329 opts.get('branch'))
4300 other = hg.peer(repo, opts, source)
4330 other = hg.peer(repo, opts, source)
4301 if 'bookmarks' not in other.listkeys('namespaces'):
4331 if 'bookmarks' not in other.listkeys('namespaces'):
4302 ui.warn(_("remote doesn't support bookmarks\n"))
4332 ui.warn(_("remote doesn't support bookmarks\n"))
4303 return 0
4333 return 0
4304 ui.status(_('comparing with %s\n') % util.hidepassword(source))
4334 ui.status(_('comparing with %s\n') % util.hidepassword(source))
4305 return bookmarks.incoming(ui, repo, other)
4335 return bookmarks.incoming(ui, repo, other)
4306
4336
4307 repo._subtoppath = ui.expandpath(source)
4337 repo._subtoppath = ui.expandpath(source)
4308 try:
4338 try:
4309 return hg.incoming(ui, repo, source, opts)
4339 return hg.incoming(ui, repo, source, opts)
4310 finally:
4340 finally:
4311 del repo._subtoppath
4341 del repo._subtoppath
4312
4342
4313
4343
4314 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
4344 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
4315 norepo=True)
4345 norepo=True)
4316 def init(ui, dest=".", **opts):
4346 def init(ui, dest=".", **opts):
4317 """create a new repository in the given directory
4347 """create a new repository in the given directory
4318
4348
4319 Initialize a new repository in the given directory. If the given
4349 Initialize a new repository in the given directory. If the given
4320 directory does not exist, it will be created.
4350 directory does not exist, it will be created.
4321
4351
4322 If no directory is given, the current directory is used.
4352 If no directory is given, the current directory is used.
4323
4353
4324 It is possible to specify an ``ssh://`` URL as the destination.
4354 It is possible to specify an ``ssh://`` URL as the destination.
4325 See :hg:`help urls` for more information.
4355 See :hg:`help urls` for more information.
4326
4356
4327 Returns 0 on success.
4357 Returns 0 on success.
4328 """
4358 """
4329 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4359 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4330
4360
4331 @command('locate',
4361 @command('locate',
4332 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
4362 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
4333 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4363 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4334 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
4364 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
4335 ] + walkopts,
4365 ] + walkopts,
4336 _('[OPTION]... [PATTERN]...'))
4366 _('[OPTION]... [PATTERN]...'))
4337 def locate(ui, repo, *pats, **opts):
4367 def locate(ui, repo, *pats, **opts):
4338 """locate files matching specific patterns (DEPRECATED)
4368 """locate files matching specific patterns (DEPRECATED)
4339
4369
4340 Print files under Mercurial control in the working directory whose
4370 Print files under Mercurial control in the working directory whose
4341 names match the given patterns.
4371 names match the given patterns.
4342
4372
4343 By default, this command searches all directories in the working
4373 By default, this command searches all directories in the working
4344 directory. To search just the current directory and its
4374 directory. To search just the current directory and its
4345 subdirectories, use "--include .".
4375 subdirectories, use "--include .".
4346
4376
4347 If no patterns are given to match, this command prints the names
4377 If no patterns are given to match, this command prints the names
4348 of all files under Mercurial control in the working directory.
4378 of all files under Mercurial control in the working directory.
4349
4379
4350 If you want to feed the output of this command into the "xargs"
4380 If you want to feed the output of this command into the "xargs"
4351 command, use the -0 option to both this command and "xargs". This
4381 command, use the -0 option to both this command and "xargs". This
4352 will avoid the problem of "xargs" treating single filenames that
4382 will avoid the problem of "xargs" treating single filenames that
4353 contain whitespace as multiple filenames.
4383 contain whitespace as multiple filenames.
4354
4384
4355 See :hg:`help files` for a more versatile command.
4385 See :hg:`help files` for a more versatile command.
4356
4386
4357 Returns 0 if a match is found, 1 otherwise.
4387 Returns 0 if a match is found, 1 otherwise.
4358 """
4388 """
4359 if opts.get('print0'):
4389 if opts.get('print0'):
4360 end = '\0'
4390 end = '\0'
4361 else:
4391 else:
4362 end = '\n'
4392 end = '\n'
4363 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
4393 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
4364
4394
4365 ret = 1
4395 ret = 1
4366 ctx = repo[rev]
4396 ctx = repo[rev]
4367 m = scmutil.match(ctx, pats, opts, default='relglob')
4397 m = scmutil.match(ctx, pats, opts, default='relglob')
4368 m.bad = lambda x, y: False
4398 m.bad = lambda x, y: False
4369
4399
4370 for abs in ctx.matches(m):
4400 for abs in ctx.matches(m):
4371 if opts.get('fullpath'):
4401 if opts.get('fullpath'):
4372 ui.write(repo.wjoin(abs), end)
4402 ui.write(repo.wjoin(abs), end)
4373 else:
4403 else:
4374 ui.write(((pats and m.rel(abs)) or abs), end)
4404 ui.write(((pats and m.rel(abs)) or abs), end)
4375 ret = 0
4405 ret = 0
4376
4406
4377 return ret
4407 return ret
4378
4408
4379 @command('^log|history',
4409 @command('^log|history',
4380 [('f', 'follow', None,
4410 [('f', 'follow', None,
4381 _('follow changeset history, or file history across copies and renames')),
4411 _('follow changeset history, or file history across copies and renames')),
4382 ('', 'follow-first', None,
4412 ('', 'follow-first', None,
4383 _('only follow the first parent of merge changesets (DEPRECATED)')),
4413 _('only follow the first parent of merge changesets (DEPRECATED)')),
4384 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
4414 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
4385 ('C', 'copies', None, _('show copied files')),
4415 ('C', 'copies', None, _('show copied files')),
4386 ('k', 'keyword', [],
4416 ('k', 'keyword', [],
4387 _('do case-insensitive search for a given text'), _('TEXT')),
4417 _('do case-insensitive search for a given text'), _('TEXT')),
4388 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
4418 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
4389 ('', 'removed', None, _('include revisions where files were removed')),
4419 ('', 'removed', None, _('include revisions where files were removed')),
4390 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4420 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4391 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4421 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4392 ('', 'only-branch', [],
4422 ('', 'only-branch', [],
4393 _('show only changesets within the given named branch (DEPRECATED)'),
4423 _('show only changesets within the given named branch (DEPRECATED)'),
4394 _('BRANCH')),
4424 _('BRANCH')),
4395 ('b', 'branch', [],
4425 ('b', 'branch', [],
4396 _('show changesets within the given named branch'), _('BRANCH')),
4426 _('show changesets within the given named branch'), _('BRANCH')),
4397 ('P', 'prune', [],
4427 ('P', 'prune', [],
4398 _('do not display revision or any of its ancestors'), _('REV')),
4428 _('do not display revision or any of its ancestors'), _('REV')),
4399 ] + logopts + walkopts,
4429 ] + logopts + walkopts,
4400 _('[OPTION]... [FILE]'),
4430 _('[OPTION]... [FILE]'),
4401 inferrepo=True)
4431 inferrepo=True)
4402 def log(ui, repo, *pats, **opts):
4432 def log(ui, repo, *pats, **opts):
4403 """show revision history of entire repository or files
4433 """show revision history of entire repository or files
4404
4434
4405 Print the revision history of the specified files or the entire
4435 Print the revision history of the specified files or the entire
4406 project.
4436 project.
4407
4437
4408 If no revision range is specified, the default is ``tip:0`` unless
4438 If no revision range is specified, the default is ``tip:0`` unless
4409 --follow is set, in which case the working directory parent is
4439 --follow is set, in which case the working directory parent is
4410 used as the starting revision.
4440 used as the starting revision.
4411
4441
4412 File history is shown without following rename or copy history of
4442 File history is shown without following rename or copy history of
4413 files. Use -f/--follow with a filename to follow history across
4443 files. Use -f/--follow with a filename to follow history across
4414 renames and copies. --follow without a filename will only show
4444 renames and copies. --follow without a filename will only show
4415 ancestors or descendants of the starting revision.
4445 ancestors or descendants of the starting revision.
4416
4446
4417 By default this command prints revision number and changeset id,
4447 By default this command prints revision number and changeset id,
4418 tags, non-trivial parents, user, date and time, and a summary for
4448 tags, non-trivial parents, user, date and time, and a summary for
4419 each commit. When the -v/--verbose switch is used, the list of
4449 each commit. When the -v/--verbose switch is used, the list of
4420 changed files and full commit message are shown.
4450 changed files and full commit message are shown.
4421
4451
4422 With --graph the revisions are shown as an ASCII art DAG with the most
4452 With --graph the revisions are shown as an ASCII art DAG with the most
4423 recent changeset at the top.
4453 recent changeset at the top.
4424 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4454 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4425 and '+' represents a fork where the changeset from the lines below is a
4455 and '+' represents a fork where the changeset from the lines below is a
4426 parent of the 'o' merge on the same line.
4456 parent of the 'o' merge on the same line.
4427
4457
4428 .. note::
4458 .. note::
4429
4459
4430 log -p/--patch may generate unexpected diff output for merge
4460 log -p/--patch may generate unexpected diff output for merge
4431 changesets, as it will only compare the merge changeset against
4461 changesets, as it will only compare the merge changeset against
4432 its first parent. Also, only files different from BOTH parents
4462 its first parent. Also, only files different from BOTH parents
4433 will appear in files:.
4463 will appear in files:.
4434
4464
4435 .. note::
4465 .. note::
4436
4466
4437 for performance reasons, log FILE may omit duplicate changes
4467 for performance reasons, log FILE may omit duplicate changes
4438 made on branches and will not show removals or mode changes. To
4468 made on branches and will not show removals or mode changes. To
4439 see all such changes, use the --removed switch.
4469 see all such changes, use the --removed switch.
4440
4470
4441 .. container:: verbose
4471 .. container:: verbose
4442
4472
4443 Some examples:
4473 Some examples:
4444
4474
4445 - changesets with full descriptions and file lists::
4475 - changesets with full descriptions and file lists::
4446
4476
4447 hg log -v
4477 hg log -v
4448
4478
4449 - changesets ancestral to the working directory::
4479 - changesets ancestral to the working directory::
4450
4480
4451 hg log -f
4481 hg log -f
4452
4482
4453 - last 10 commits on the current branch::
4483 - last 10 commits on the current branch::
4454
4484
4455 hg log -l 10 -b .
4485 hg log -l 10 -b .
4456
4486
4457 - changesets showing all modifications of a file, including removals::
4487 - changesets showing all modifications of a file, including removals::
4458
4488
4459 hg log --removed file.c
4489 hg log --removed file.c
4460
4490
4461 - all changesets that touch a directory, with diffs, excluding merges::
4491 - all changesets that touch a directory, with diffs, excluding merges::
4462
4492
4463 hg log -Mp lib/
4493 hg log -Mp lib/
4464
4494
4465 - all revision numbers that match a keyword::
4495 - all revision numbers that match a keyword::
4466
4496
4467 hg log -k bug --template "{rev}\\n"
4497 hg log -k bug --template "{rev}\\n"
4468
4498
4469 - list available log templates::
4499 - list available log templates::
4470
4500
4471 hg log -T list
4501 hg log -T list
4472
4502
4473 - check if a given changeset is included in a tagged release::
4503 - check if a given changeset is included in a tagged release::
4474
4504
4475 hg log -r "a21ccf and ancestor(1.9)"
4505 hg log -r "a21ccf and ancestor(1.9)"
4476
4506
4477 - find all changesets by some user in a date range::
4507 - find all changesets by some user in a date range::
4478
4508
4479 hg log -k alice -d "may 2008 to jul 2008"
4509 hg log -k alice -d "may 2008 to jul 2008"
4480
4510
4481 - summary of all changesets after the last tag::
4511 - summary of all changesets after the last tag::
4482
4512
4483 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4513 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4484
4514
4485 See :hg:`help dates` for a list of formats valid for -d/--date.
4515 See :hg:`help dates` for a list of formats valid for -d/--date.
4486
4516
4487 See :hg:`help revisions` and :hg:`help revsets` for more about
4517 See :hg:`help revisions` and :hg:`help revsets` for more about
4488 specifying revisions.
4518 specifying revisions.
4489
4519
4490 See :hg:`help templates` for more about pre-packaged styles and
4520 See :hg:`help templates` for more about pre-packaged styles and
4491 specifying custom templates.
4521 specifying custom templates.
4492
4522
4493 Returns 0 on success.
4523 Returns 0 on success.
4494
4524
4495 """
4525 """
4496 if opts.get('follow') and opts.get('rev'):
4526 if opts.get('follow') and opts.get('rev'):
4497 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
4527 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
4498 del opts['follow']
4528 del opts['follow']
4499
4529
4500 if opts.get('graph'):
4530 if opts.get('graph'):
4501 return cmdutil.graphlog(ui, repo, *pats, **opts)
4531 return cmdutil.graphlog(ui, repo, *pats, **opts)
4502
4532
4503 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
4533 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
4504 limit = cmdutil.loglimit(opts)
4534 limit = cmdutil.loglimit(opts)
4505 count = 0
4535 count = 0
4506
4536
4507 getrenamed = None
4537 getrenamed = None
4508 if opts.get('copies'):
4538 if opts.get('copies'):
4509 endrev = None
4539 endrev = None
4510 if opts.get('rev'):
4540 if opts.get('rev'):
4511 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
4541 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
4512 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4542 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4513
4543
4514 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4544 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4515 for rev in revs:
4545 for rev in revs:
4516 if count == limit:
4546 if count == limit:
4517 break
4547 break
4518 ctx = repo[rev]
4548 ctx = repo[rev]
4519 copies = None
4549 copies = None
4520 if getrenamed is not None and rev:
4550 if getrenamed is not None and rev:
4521 copies = []
4551 copies = []
4522 for fn in ctx.files():
4552 for fn in ctx.files():
4523 rename = getrenamed(fn, rev)
4553 rename = getrenamed(fn, rev)
4524 if rename:
4554 if rename:
4525 copies.append((fn, rename[0]))
4555 copies.append((fn, rename[0]))
4526 if filematcher:
4556 if filematcher:
4527 revmatchfn = filematcher(ctx.rev())
4557 revmatchfn = filematcher(ctx.rev())
4528 else:
4558 else:
4529 revmatchfn = None
4559 revmatchfn = None
4530 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4560 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4531 if displayer.flush(rev):
4561 if displayer.flush(rev):
4532 count += 1
4562 count += 1
4533
4563
4534 displayer.close()
4564 displayer.close()
4535
4565
4536 @command('manifest',
4566 @command('manifest',
4537 [('r', 'rev', '', _('revision to display'), _('REV')),
4567 [('r', 'rev', '', _('revision to display'), _('REV')),
4538 ('', 'all', False, _("list files from all revisions"))]
4568 ('', 'all', False, _("list files from all revisions"))]
4539 + formatteropts,
4569 + formatteropts,
4540 _('[-r REV]'))
4570 _('[-r REV]'))
4541 def manifest(ui, repo, node=None, rev=None, **opts):
4571 def manifest(ui, repo, node=None, rev=None, **opts):
4542 """output the current or given revision of the project manifest
4572 """output the current or given revision of the project manifest
4543
4573
4544 Print a list of version controlled files for the given revision.
4574 Print a list of version controlled files for the given revision.
4545 If no revision is given, the first parent of the working directory
4575 If no revision is given, the first parent of the working directory
4546 is used, or the null revision if no revision is checked out.
4576 is used, or the null revision if no revision is checked out.
4547
4577
4548 With -v, print file permissions, symlink and executable bits.
4578 With -v, print file permissions, symlink and executable bits.
4549 With --debug, print file revision hashes.
4579 With --debug, print file revision hashes.
4550
4580
4551 If option --all is specified, the list of all files from all revisions
4581 If option --all is specified, the list of all files from all revisions
4552 is printed. This includes deleted and renamed files.
4582 is printed. This includes deleted and renamed files.
4553
4583
4554 Returns 0 on success.
4584 Returns 0 on success.
4555 """
4585 """
4556
4586
4557 fm = ui.formatter('manifest', opts)
4587 fm = ui.formatter('manifest', opts)
4558
4588
4559 if opts.get('all'):
4589 if opts.get('all'):
4560 if rev or node:
4590 if rev or node:
4561 raise util.Abort(_("can't specify a revision with --all"))
4591 raise util.Abort(_("can't specify a revision with --all"))
4562
4592
4563 res = []
4593 res = []
4564 prefix = "data/"
4594 prefix = "data/"
4565 suffix = ".i"
4595 suffix = ".i"
4566 plen = len(prefix)
4596 plen = len(prefix)
4567 slen = len(suffix)
4597 slen = len(suffix)
4568 lock = repo.lock()
4598 lock = repo.lock()
4569 try:
4599 try:
4570 for fn, b, size in repo.store.datafiles():
4600 for fn, b, size in repo.store.datafiles():
4571 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4601 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4572 res.append(fn[plen:-slen])
4602 res.append(fn[plen:-slen])
4573 finally:
4603 finally:
4574 lock.release()
4604 lock.release()
4575 for f in res:
4605 for f in res:
4576 fm.startitem()
4606 fm.startitem()
4577 fm.write("path", '%s\n', f)
4607 fm.write("path", '%s\n', f)
4578 fm.end()
4608 fm.end()
4579 return
4609 return
4580
4610
4581 if rev and node:
4611 if rev and node:
4582 raise util.Abort(_("please specify just one revision"))
4612 raise util.Abort(_("please specify just one revision"))
4583
4613
4584 if not node:
4614 if not node:
4585 node = rev
4615 node = rev
4586
4616
4587 char = {'l': '@', 'x': '*', '': ''}
4617 char = {'l': '@', 'x': '*', '': ''}
4588 mode = {'l': '644', 'x': '755', '': '644'}
4618 mode = {'l': '644', 'x': '755', '': '644'}
4589 ctx = scmutil.revsingle(repo, node)
4619 ctx = scmutil.revsingle(repo, node)
4590 mf = ctx.manifest()
4620 mf = ctx.manifest()
4591 for f in ctx:
4621 for f in ctx:
4592 fm.startitem()
4622 fm.startitem()
4593 fl = ctx[f].flags()
4623 fl = ctx[f].flags()
4594 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4624 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4595 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4625 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4596 fm.write('path', '%s\n', f)
4626 fm.write('path', '%s\n', f)
4597 fm.end()
4627 fm.end()
4598
4628
4599 @command('^merge',
4629 @command('^merge',
4600 [('f', 'force', None,
4630 [('f', 'force', None,
4601 _('force a merge including outstanding changes (DEPRECATED)')),
4631 _('force a merge including outstanding changes (DEPRECATED)')),
4602 ('r', 'rev', '', _('revision to merge'), _('REV')),
4632 ('r', 'rev', '', _('revision to merge'), _('REV')),
4603 ('P', 'preview', None,
4633 ('P', 'preview', None,
4604 _('review revisions to merge (no merge is performed)'))
4634 _('review revisions to merge (no merge is performed)'))
4605 ] + mergetoolopts,
4635 ] + mergetoolopts,
4606 _('[-P] [-f] [[-r] REV]'))
4636 _('[-P] [-f] [[-r] REV]'))
4607 def merge(ui, repo, node=None, **opts):
4637 def merge(ui, repo, node=None, **opts):
4608 """merge another revision into working directory
4638 """merge another revision into working directory
4609
4639
4610 The current working directory is updated with all changes made in
4640 The current working directory is updated with all changes made in
4611 the requested revision since the last common predecessor revision.
4641 the requested revision since the last common predecessor revision.
4612
4642
4613 Files that changed between either parent are marked as changed for
4643 Files that changed between either parent are marked as changed for
4614 the next commit and a commit must be performed before any further
4644 the next commit and a commit must be performed before any further
4615 updates to the repository are allowed. The next commit will have
4645 updates to the repository are allowed. The next commit will have
4616 two parents.
4646 two parents.
4617
4647
4618 ``--tool`` can be used to specify the merge tool used for file
4648 ``--tool`` can be used to specify the merge tool used for file
4619 merges. It overrides the HGMERGE environment variable and your
4649 merges. It overrides the HGMERGE environment variable and your
4620 configuration files. See :hg:`help merge-tools` for options.
4650 configuration files. See :hg:`help merge-tools` for options.
4621
4651
4622 If no revision is specified, the working directory's parent is a
4652 If no revision is specified, the working directory's parent is a
4623 head revision, and the current branch contains exactly one other
4653 head revision, and the current branch contains exactly one other
4624 head, the other head is merged with by default. Otherwise, an
4654 head, the other head is merged with by default. Otherwise, an
4625 explicit revision with which to merge with must be provided.
4655 explicit revision with which to merge with must be provided.
4626
4656
4627 :hg:`resolve` must be used to resolve unresolved files.
4657 :hg:`resolve` must be used to resolve unresolved files.
4628
4658
4629 To undo an uncommitted merge, use :hg:`update --clean .` which
4659 To undo an uncommitted merge, use :hg:`update --clean .` which
4630 will check out a clean copy of the original merge parent, losing
4660 will check out a clean copy of the original merge parent, losing
4631 all changes.
4661 all changes.
4632
4662
4633 Returns 0 on success, 1 if there are unresolved files.
4663 Returns 0 on success, 1 if there are unresolved files.
4634 """
4664 """
4635
4665
4636 if opts.get('rev') and node:
4666 if opts.get('rev') and node:
4637 raise util.Abort(_("please specify just one revision"))
4667 raise util.Abort(_("please specify just one revision"))
4638 if not node:
4668 if not node:
4639 node = opts.get('rev')
4669 node = opts.get('rev')
4640
4670
4641 if node:
4671 if node:
4642 node = scmutil.revsingle(repo, node).node()
4672 node = scmutil.revsingle(repo, node).node()
4643
4673
4644 if not node and repo._bookmarkcurrent:
4674 if not node and repo._bookmarkcurrent:
4645 bmheads = repo.bookmarkheads(repo._bookmarkcurrent)
4675 bmheads = repo.bookmarkheads(repo._bookmarkcurrent)
4646 curhead = repo[repo._bookmarkcurrent].node()
4676 curhead = repo[repo._bookmarkcurrent].node()
4647 if len(bmheads) == 2:
4677 if len(bmheads) == 2:
4648 if curhead == bmheads[0]:
4678 if curhead == bmheads[0]:
4649 node = bmheads[1]
4679 node = bmheads[1]
4650 else:
4680 else:
4651 node = bmheads[0]
4681 node = bmheads[0]
4652 elif len(bmheads) > 2:
4682 elif len(bmheads) > 2:
4653 raise util.Abort(_("multiple matching bookmarks to merge - "
4683 raise util.Abort(_("multiple matching bookmarks to merge - "
4654 "please merge with an explicit rev or bookmark"),
4684 "please merge with an explicit rev or bookmark"),
4655 hint=_("run 'hg heads' to see all heads"))
4685 hint=_("run 'hg heads' to see all heads"))
4656 elif len(bmheads) <= 1:
4686 elif len(bmheads) <= 1:
4657 raise util.Abort(_("no matching bookmark to merge - "
4687 raise util.Abort(_("no matching bookmark to merge - "
4658 "please merge with an explicit rev or bookmark"),
4688 "please merge with an explicit rev or bookmark"),
4659 hint=_("run 'hg heads' to see all heads"))
4689 hint=_("run 'hg heads' to see all heads"))
4660
4690
4661 if not node and not repo._bookmarkcurrent:
4691 if not node and not repo._bookmarkcurrent:
4662 branch = repo[None].branch()
4692 branch = repo[None].branch()
4663 bheads = repo.branchheads(branch)
4693 bheads = repo.branchheads(branch)
4664 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
4694 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
4665
4695
4666 if len(nbhs) > 2:
4696 if len(nbhs) > 2:
4667 raise util.Abort(_("branch '%s' has %d heads - "
4697 raise util.Abort(_("branch '%s' has %d heads - "
4668 "please merge with an explicit rev")
4698 "please merge with an explicit rev")
4669 % (branch, len(bheads)),
4699 % (branch, len(bheads)),
4670 hint=_("run 'hg heads .' to see heads"))
4700 hint=_("run 'hg heads .' to see heads"))
4671
4701
4672 parent = repo.dirstate.p1()
4702 parent = repo.dirstate.p1()
4673 if len(nbhs) <= 1:
4703 if len(nbhs) <= 1:
4674 if len(bheads) > 1:
4704 if len(bheads) > 1:
4675 raise util.Abort(_("heads are bookmarked - "
4705 raise util.Abort(_("heads are bookmarked - "
4676 "please merge with an explicit rev"),
4706 "please merge with an explicit rev"),
4677 hint=_("run 'hg heads' to see all heads"))
4707 hint=_("run 'hg heads' to see all heads"))
4678 if len(repo.heads()) > 1:
4708 if len(repo.heads()) > 1:
4679 raise util.Abort(_("branch '%s' has one head - "
4709 raise util.Abort(_("branch '%s' has one head - "
4680 "please merge with an explicit rev")
4710 "please merge with an explicit rev")
4681 % branch,
4711 % branch,
4682 hint=_("run 'hg heads' to see all heads"))
4712 hint=_("run 'hg heads' to see all heads"))
4683 msg, hint = _('nothing to merge'), None
4713 msg, hint = _('nothing to merge'), None
4684 if parent != repo.lookup(branch):
4714 if parent != repo.lookup(branch):
4685 hint = _("use 'hg update' instead")
4715 hint = _("use 'hg update' instead")
4686 raise util.Abort(msg, hint=hint)
4716 raise util.Abort(msg, hint=hint)
4687
4717
4688 if parent not in bheads:
4718 if parent not in bheads:
4689 raise util.Abort(_('working directory not at a head revision'),
4719 raise util.Abort(_('working directory not at a head revision'),
4690 hint=_("use 'hg update' or merge with an "
4720 hint=_("use 'hg update' or merge with an "
4691 "explicit revision"))
4721 "explicit revision"))
4692 if parent == nbhs[0]:
4722 if parent == nbhs[0]:
4693 node = nbhs[-1]
4723 node = nbhs[-1]
4694 else:
4724 else:
4695 node = nbhs[0]
4725 node = nbhs[0]
4696
4726
4697 if opts.get('preview'):
4727 if opts.get('preview'):
4698 # find nodes that are ancestors of p2 but not of p1
4728 # find nodes that are ancestors of p2 but not of p1
4699 p1 = repo.lookup('.')
4729 p1 = repo.lookup('.')
4700 p2 = repo.lookup(node)
4730 p2 = repo.lookup(node)
4701 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4731 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4702
4732
4703 displayer = cmdutil.show_changeset(ui, repo, opts)
4733 displayer = cmdutil.show_changeset(ui, repo, opts)
4704 for node in nodes:
4734 for node in nodes:
4705 displayer.show(repo[node])
4735 displayer.show(repo[node])
4706 displayer.close()
4736 displayer.close()
4707 return 0
4737 return 0
4708
4738
4709 try:
4739 try:
4710 # ui.forcemerge is an internal variable, do not document
4740 # ui.forcemerge is an internal variable, do not document
4711 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
4741 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
4712 return hg.merge(repo, node, force=opts.get('force'))
4742 return hg.merge(repo, node, force=opts.get('force'))
4713 finally:
4743 finally:
4714 ui.setconfig('ui', 'forcemerge', '', 'merge')
4744 ui.setconfig('ui', 'forcemerge', '', 'merge')
4715
4745
4716 @command('outgoing|out',
4746 @command('outgoing|out',
4717 [('f', 'force', None, _('run even when the destination is unrelated')),
4747 [('f', 'force', None, _('run even when the destination is unrelated')),
4718 ('r', 'rev', [],
4748 ('r', 'rev', [],
4719 _('a changeset intended to be included in the destination'), _('REV')),
4749 _('a changeset intended to be included in the destination'), _('REV')),
4720 ('n', 'newest-first', None, _('show newest record first')),
4750 ('n', 'newest-first', None, _('show newest record first')),
4721 ('B', 'bookmarks', False, _('compare bookmarks')),
4751 ('B', 'bookmarks', False, _('compare bookmarks')),
4722 ('b', 'branch', [], _('a specific branch you would like to push'),
4752 ('b', 'branch', [], _('a specific branch you would like to push'),
4723 _('BRANCH')),
4753 _('BRANCH')),
4724 ] + logopts + remoteopts + subrepoopts,
4754 ] + logopts + remoteopts + subrepoopts,
4725 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4755 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4726 def outgoing(ui, repo, dest=None, **opts):
4756 def outgoing(ui, repo, dest=None, **opts):
4727 """show changesets not found in the destination
4757 """show changesets not found in the destination
4728
4758
4729 Show changesets not found in the specified destination repository
4759 Show changesets not found in the specified destination repository
4730 or the default push location. These are the changesets that would
4760 or the default push location. These are the changesets that would
4731 be pushed if a push was requested.
4761 be pushed if a push was requested.
4732
4762
4733 See pull for details of valid destination formats.
4763 See pull for details of valid destination formats.
4734
4764
4735 Returns 0 if there are outgoing changes, 1 otherwise.
4765 Returns 0 if there are outgoing changes, 1 otherwise.
4736 """
4766 """
4737 if opts.get('graph'):
4767 if opts.get('graph'):
4738 cmdutil.checkunsupportedgraphflags([], opts)
4768 cmdutil.checkunsupportedgraphflags([], opts)
4739 o, other = hg._outgoing(ui, repo, dest, opts)
4769 o, other = hg._outgoing(ui, repo, dest, opts)
4740 if not o:
4770 if not o:
4741 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4771 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4742 return
4772 return
4743
4773
4744 revdag = cmdutil.graphrevs(repo, o, opts)
4774 revdag = cmdutil.graphrevs(repo, o, opts)
4745 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4775 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4746 showparents = [ctx.node() for ctx in repo[None].parents()]
4776 showparents = [ctx.node() for ctx in repo[None].parents()]
4747 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4777 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4748 graphmod.asciiedges)
4778 graphmod.asciiedges)
4749 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4779 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4750 return 0
4780 return 0
4751
4781
4752 if opts.get('bookmarks'):
4782 if opts.get('bookmarks'):
4753 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4783 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4754 dest, branches = hg.parseurl(dest, opts.get('branch'))
4784 dest, branches = hg.parseurl(dest, opts.get('branch'))
4755 other = hg.peer(repo, opts, dest)
4785 other = hg.peer(repo, opts, dest)
4756 if 'bookmarks' not in other.listkeys('namespaces'):
4786 if 'bookmarks' not in other.listkeys('namespaces'):
4757 ui.warn(_("remote doesn't support bookmarks\n"))
4787 ui.warn(_("remote doesn't support bookmarks\n"))
4758 return 0
4788 return 0
4759 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4789 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4760 return bookmarks.outgoing(ui, repo, other)
4790 return bookmarks.outgoing(ui, repo, other)
4761
4791
4762 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4792 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4763 try:
4793 try:
4764 return hg.outgoing(ui, repo, dest, opts)
4794 return hg.outgoing(ui, repo, dest, opts)
4765 finally:
4795 finally:
4766 del repo._subtoppath
4796 del repo._subtoppath
4767
4797
4768 @command('parents',
4798 @command('parents',
4769 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4799 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4770 ] + templateopts,
4800 ] + templateopts,
4771 _('[-r REV] [FILE]'),
4801 _('[-r REV] [FILE]'),
4772 inferrepo=True)
4802 inferrepo=True)
4773 def parents(ui, repo, file_=None, **opts):
4803 def parents(ui, repo, file_=None, **opts):
4774 """show the parents of the working directory or revision (DEPRECATED)
4804 """show the parents of the working directory or revision (DEPRECATED)
4775
4805
4776 Print the working directory's parent revisions. If a revision is
4806 Print the working directory's parent revisions. If a revision is
4777 given via -r/--rev, the parent of that revision will be printed.
4807 given via -r/--rev, the parent of that revision will be printed.
4778 If a file argument is given, the revision in which the file was
4808 If a file argument is given, the revision in which the file was
4779 last changed (before the working directory revision or the
4809 last changed (before the working directory revision or the
4780 argument to --rev if given) is printed.
4810 argument to --rev if given) is printed.
4781
4811
4782 See :hg:`summary` and :hg:`help revsets` for related information.
4812 See :hg:`summary` and :hg:`help revsets` for related information.
4783
4813
4784 Returns 0 on success.
4814 Returns 0 on success.
4785 """
4815 """
4786
4816
4787 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4817 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4788
4818
4789 if file_:
4819 if file_:
4790 m = scmutil.match(ctx, (file_,), opts)
4820 m = scmutil.match(ctx, (file_,), opts)
4791 if m.anypats() or len(m.files()) != 1:
4821 if m.anypats() or len(m.files()) != 1:
4792 raise util.Abort(_('can only specify an explicit filename'))
4822 raise util.Abort(_('can only specify an explicit filename'))
4793 file_ = m.files()[0]
4823 file_ = m.files()[0]
4794 filenodes = []
4824 filenodes = []
4795 for cp in ctx.parents():
4825 for cp in ctx.parents():
4796 if not cp:
4826 if not cp:
4797 continue
4827 continue
4798 try:
4828 try:
4799 filenodes.append(cp.filenode(file_))
4829 filenodes.append(cp.filenode(file_))
4800 except error.LookupError:
4830 except error.LookupError:
4801 pass
4831 pass
4802 if not filenodes:
4832 if not filenodes:
4803 raise util.Abort(_("'%s' not found in manifest!") % file_)
4833 raise util.Abort(_("'%s' not found in manifest!") % file_)
4804 p = []
4834 p = []
4805 for fn in filenodes:
4835 for fn in filenodes:
4806 fctx = repo.filectx(file_, fileid=fn)
4836 fctx = repo.filectx(file_, fileid=fn)
4807 p.append(fctx.node())
4837 p.append(fctx.node())
4808 else:
4838 else:
4809 p = [cp.node() for cp in ctx.parents()]
4839 p = [cp.node() for cp in ctx.parents()]
4810
4840
4811 displayer = cmdutil.show_changeset(ui, repo, opts)
4841 displayer = cmdutil.show_changeset(ui, repo, opts)
4812 for n in p:
4842 for n in p:
4813 if n != nullid:
4843 if n != nullid:
4814 displayer.show(repo[n])
4844 displayer.show(repo[n])
4815 displayer.close()
4845 displayer.close()
4816
4846
4817 @command('paths', [], _('[NAME]'), optionalrepo=True)
4847 @command('paths', [], _('[NAME]'), optionalrepo=True)
4818 def paths(ui, repo, search=None):
4848 def paths(ui, repo, search=None):
4819 """show aliases for remote repositories
4849 """show aliases for remote repositories
4820
4850
4821 Show definition of symbolic path name NAME. If no name is given,
4851 Show definition of symbolic path name NAME. If no name is given,
4822 show definition of all available names.
4852 show definition of all available names.
4823
4853
4824 Option -q/--quiet suppresses all output when searching for NAME
4854 Option -q/--quiet suppresses all output when searching for NAME
4825 and shows only the path names when listing all definitions.
4855 and shows only the path names when listing all definitions.
4826
4856
4827 Path names are defined in the [paths] section of your
4857 Path names are defined in the [paths] section of your
4828 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4858 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4829 repository, ``.hg/hgrc`` is used, too.
4859 repository, ``.hg/hgrc`` is used, too.
4830
4860
4831 The path names ``default`` and ``default-push`` have a special
4861 The path names ``default`` and ``default-push`` have a special
4832 meaning. When performing a push or pull operation, they are used
4862 meaning. When performing a push or pull operation, they are used
4833 as fallbacks if no location is specified on the command-line.
4863 as fallbacks if no location is specified on the command-line.
4834 When ``default-push`` is set, it will be used for push and
4864 When ``default-push`` is set, it will be used for push and
4835 ``default`` will be used for pull; otherwise ``default`` is used
4865 ``default`` will be used for pull; otherwise ``default`` is used
4836 as the fallback for both. When cloning a repository, the clone
4866 as the fallback for both. When cloning a repository, the clone
4837 source is written as ``default`` in ``.hg/hgrc``. Note that
4867 source is written as ``default`` in ``.hg/hgrc``. Note that
4838 ``default`` and ``default-push`` apply to all inbound (e.g.
4868 ``default`` and ``default-push`` apply to all inbound (e.g.
4839 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4869 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4840 :hg:`bundle`) operations.
4870 :hg:`bundle`) operations.
4841
4871
4842 See :hg:`help urls` for more information.
4872 See :hg:`help urls` for more information.
4843
4873
4844 Returns 0 on success.
4874 Returns 0 on success.
4845 """
4875 """
4846 if search:
4876 if search:
4847 for name, path in sorted(ui.paths.iteritems()):
4877 for name, path in sorted(ui.paths.iteritems()):
4848 if name == search:
4878 if name == search:
4849 ui.status("%s\n" % util.hidepassword(path.loc))
4879 ui.status("%s\n" % util.hidepassword(path.loc))
4850 return
4880 return
4851 if not ui.quiet:
4881 if not ui.quiet:
4852 ui.warn(_("not found!\n"))
4882 ui.warn(_("not found!\n"))
4853 return 1
4883 return 1
4854 else:
4884 else:
4855 for name, path in sorted(ui.paths.iteritems()):
4885 for name, path in sorted(ui.paths.iteritems()):
4856 if ui.quiet:
4886 if ui.quiet:
4857 ui.write("%s\n" % name)
4887 ui.write("%s\n" % name)
4858 else:
4888 else:
4859 ui.write("%s = %s\n" % (name,
4889 ui.write("%s = %s\n" % (name,
4860 util.hidepassword(path.loc)))
4890 util.hidepassword(path.loc)))
4861
4891
4862 @command('phase',
4892 @command('phase',
4863 [('p', 'public', False, _('set changeset phase to public')),
4893 [('p', 'public', False, _('set changeset phase to public')),
4864 ('d', 'draft', False, _('set changeset phase to draft')),
4894 ('d', 'draft', False, _('set changeset phase to draft')),
4865 ('s', 'secret', False, _('set changeset phase to secret')),
4895 ('s', 'secret', False, _('set changeset phase to secret')),
4866 ('f', 'force', False, _('allow to move boundary backward')),
4896 ('f', 'force', False, _('allow to move boundary backward')),
4867 ('r', 'rev', [], _('target revision'), _('REV')),
4897 ('r', 'rev', [], _('target revision'), _('REV')),
4868 ],
4898 ],
4869 _('[-p|-d|-s] [-f] [-r] REV...'))
4899 _('[-p|-d|-s] [-f] [-r] REV...'))
4870 def phase(ui, repo, *revs, **opts):
4900 def phase(ui, repo, *revs, **opts):
4871 """set or show the current phase name
4901 """set or show the current phase name
4872
4902
4873 With no argument, show the phase name of specified revisions.
4903 With no argument, show the phase name of specified revisions.
4874
4904
4875 With one of -p/--public, -d/--draft or -s/--secret, change the
4905 With one of -p/--public, -d/--draft or -s/--secret, change the
4876 phase value of the specified revisions.
4906 phase value of the specified revisions.
4877
4907
4878 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
4908 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
4879 lower phase to an higher phase. Phases are ordered as follows::
4909 lower phase to an higher phase. Phases are ordered as follows::
4880
4910
4881 public < draft < secret
4911 public < draft < secret
4882
4912
4883 Returns 0 on success, 1 if no phases were changed or some could not
4913 Returns 0 on success, 1 if no phases were changed or some could not
4884 be changed.
4914 be changed.
4885 """
4915 """
4886 # search for a unique phase argument
4916 # search for a unique phase argument
4887 targetphase = None
4917 targetphase = None
4888 for idx, name in enumerate(phases.phasenames):
4918 for idx, name in enumerate(phases.phasenames):
4889 if opts[name]:
4919 if opts[name]:
4890 if targetphase is not None:
4920 if targetphase is not None:
4891 raise util.Abort(_('only one phase can be specified'))
4921 raise util.Abort(_('only one phase can be specified'))
4892 targetphase = idx
4922 targetphase = idx
4893
4923
4894 # look for specified revision
4924 # look for specified revision
4895 revs = list(revs)
4925 revs = list(revs)
4896 revs.extend(opts['rev'])
4926 revs.extend(opts['rev'])
4897 if not revs:
4927 if not revs:
4898 raise util.Abort(_('no revisions specified'))
4928 raise util.Abort(_('no revisions specified'))
4899
4929
4900 revs = scmutil.revrange(repo, revs)
4930 revs = scmutil.revrange(repo, revs)
4901
4931
4902 lock = None
4932 lock = None
4903 ret = 0
4933 ret = 0
4904 if targetphase is None:
4934 if targetphase is None:
4905 # display
4935 # display
4906 for r in revs:
4936 for r in revs:
4907 ctx = repo[r]
4937 ctx = repo[r]
4908 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4938 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4909 else:
4939 else:
4910 tr = None
4940 tr = None
4911 lock = repo.lock()
4941 lock = repo.lock()
4912 try:
4942 try:
4913 tr = repo.transaction("phase")
4943 tr = repo.transaction("phase")
4914 # set phase
4944 # set phase
4915 if not revs:
4945 if not revs:
4916 raise util.Abort(_('empty revision set'))
4946 raise util.Abort(_('empty revision set'))
4917 nodes = [repo[r].node() for r in revs]
4947 nodes = [repo[r].node() for r in revs]
4918 # moving revision from public to draft may hide them
4948 # moving revision from public to draft may hide them
4919 # We have to check result on an unfiltered repository
4949 # We have to check result on an unfiltered repository
4920 unfi = repo.unfiltered()
4950 unfi = repo.unfiltered()
4921 getphase = unfi._phasecache.phase
4951 getphase = unfi._phasecache.phase
4922 olddata = [getphase(unfi, r) for r in unfi]
4952 olddata = [getphase(unfi, r) for r in unfi]
4923 phases.advanceboundary(repo, tr, targetphase, nodes)
4953 phases.advanceboundary(repo, tr, targetphase, nodes)
4924 if opts['force']:
4954 if opts['force']:
4925 phases.retractboundary(repo, tr, targetphase, nodes)
4955 phases.retractboundary(repo, tr, targetphase, nodes)
4926 tr.close()
4956 tr.close()
4927 finally:
4957 finally:
4928 if tr is not None:
4958 if tr is not None:
4929 tr.release()
4959 tr.release()
4930 lock.release()
4960 lock.release()
4931 getphase = unfi._phasecache.phase
4961 getphase = unfi._phasecache.phase
4932 newdata = [getphase(unfi, r) for r in unfi]
4962 newdata = [getphase(unfi, r) for r in unfi]
4933 changes = sum(newdata[r] != olddata[r] for r in unfi)
4963 changes = sum(newdata[r] != olddata[r] for r in unfi)
4934 cl = unfi.changelog
4964 cl = unfi.changelog
4935 rejected = [n for n in nodes
4965 rejected = [n for n in nodes
4936 if newdata[cl.rev(n)] < targetphase]
4966 if newdata[cl.rev(n)] < targetphase]
4937 if rejected:
4967 if rejected:
4938 ui.warn(_('cannot move %i changesets to a higher '
4968 ui.warn(_('cannot move %i changesets to a higher '
4939 'phase, use --force\n') % len(rejected))
4969 'phase, use --force\n') % len(rejected))
4940 ret = 1
4970 ret = 1
4941 if changes:
4971 if changes:
4942 msg = _('phase changed for %i changesets\n') % changes
4972 msg = _('phase changed for %i changesets\n') % changes
4943 if ret:
4973 if ret:
4944 ui.status(msg)
4974 ui.status(msg)
4945 else:
4975 else:
4946 ui.note(msg)
4976 ui.note(msg)
4947 else:
4977 else:
4948 ui.warn(_('no phases changed\n'))
4978 ui.warn(_('no phases changed\n'))
4949 ret = 1
4979 ret = 1
4950 return ret
4980 return ret
4951
4981
4952 def postincoming(ui, repo, modheads, optupdate, checkout):
4982 def postincoming(ui, repo, modheads, optupdate, checkout):
4953 if modheads == 0:
4983 if modheads == 0:
4954 return
4984 return
4955 if optupdate:
4985 if optupdate:
4956 checkout, movemarkfrom = bookmarks.calculateupdate(ui, repo, checkout)
4986 checkout, movemarkfrom = bookmarks.calculateupdate(ui, repo, checkout)
4957 try:
4987 try:
4958 ret = hg.update(repo, checkout)
4988 ret = hg.update(repo, checkout)
4959 except util.Abort, inst:
4989 except util.Abort, inst:
4960 ui.warn(_("not updating: %s\n") % str(inst))
4990 ui.warn(_("not updating: %s\n") % str(inst))
4961 if inst.hint:
4991 if inst.hint:
4962 ui.warn(_("(%s)\n") % inst.hint)
4992 ui.warn(_("(%s)\n") % inst.hint)
4963 return 0
4993 return 0
4964 if not ret and not checkout:
4994 if not ret and not checkout:
4965 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
4995 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
4966 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
4996 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
4967 return ret
4997 return ret
4968 if modheads > 1:
4998 if modheads > 1:
4969 currentbranchheads = len(repo.branchheads())
4999 currentbranchheads = len(repo.branchheads())
4970 if currentbranchheads == modheads:
5000 if currentbranchheads == modheads:
4971 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
5001 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4972 elif currentbranchheads > 1:
5002 elif currentbranchheads > 1:
4973 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
5003 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4974 "merge)\n"))
5004 "merge)\n"))
4975 else:
5005 else:
4976 ui.status(_("(run 'hg heads' to see heads)\n"))
5006 ui.status(_("(run 'hg heads' to see heads)\n"))
4977 else:
5007 else:
4978 ui.status(_("(run 'hg update' to get a working copy)\n"))
5008 ui.status(_("(run 'hg update' to get a working copy)\n"))
4979
5009
4980 @command('^pull',
5010 @command('^pull',
4981 [('u', 'update', None,
5011 [('u', 'update', None,
4982 _('update to new branch head if changesets were pulled')),
5012 _('update to new branch head if changesets were pulled')),
4983 ('f', 'force', None, _('run even when remote repository is unrelated')),
5013 ('f', 'force', None, _('run even when remote repository is unrelated')),
4984 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
5014 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4985 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
5015 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4986 ('b', 'branch', [], _('a specific branch you would like to pull'),
5016 ('b', 'branch', [], _('a specific branch you would like to pull'),
4987 _('BRANCH')),
5017 _('BRANCH')),
4988 ] + remoteopts,
5018 ] + remoteopts,
4989 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
5019 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4990 def pull(ui, repo, source="default", **opts):
5020 def pull(ui, repo, source="default", **opts):
4991 """pull changes from the specified source
5021 """pull changes from the specified source
4992
5022
4993 Pull changes from a remote repository to a local one.
5023 Pull changes from a remote repository to a local one.
4994
5024
4995 This finds all changes from the repository at the specified path
5025 This finds all changes from the repository at the specified path
4996 or URL and adds them to a local repository (the current one unless
5026 or URL and adds them to a local repository (the current one unless
4997 -R is specified). By default, this does not update the copy of the
5027 -R is specified). By default, this does not update the copy of the
4998 project in the working directory.
5028 project in the working directory.
4999
5029
5000 Use :hg:`incoming` if you want to see what would have been added
5030 Use :hg:`incoming` if you want to see what would have been added
5001 by a pull at the time you issued this command. If you then decide
5031 by a pull at the time you issued this command. If you then decide
5002 to add those changes to the repository, you should use :hg:`pull
5032 to add those changes to the repository, you should use :hg:`pull
5003 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5033 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5004
5034
5005 If SOURCE is omitted, the 'default' path will be used.
5035 If SOURCE is omitted, the 'default' path will be used.
5006 See :hg:`help urls` for more information.
5036 See :hg:`help urls` for more information.
5007
5037
5008 Returns 0 on success, 1 if an update had unresolved files.
5038 Returns 0 on success, 1 if an update had unresolved files.
5009 """
5039 """
5010 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
5040 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
5011 ui.status(_('pulling from %s\n') % util.hidepassword(source))
5041 ui.status(_('pulling from %s\n') % util.hidepassword(source))
5012 other = hg.peer(repo, opts, source)
5042 other = hg.peer(repo, opts, source)
5013 try:
5043 try:
5014 revs, checkout = hg.addbranchrevs(repo, other, branches,
5044 revs, checkout = hg.addbranchrevs(repo, other, branches,
5015 opts.get('rev'))
5045 opts.get('rev'))
5016
5046
5017 remotebookmarks = other.listkeys('bookmarks')
5047 remotebookmarks = other.listkeys('bookmarks')
5018
5048
5019 if opts.get('bookmark'):
5049 if opts.get('bookmark'):
5020 if not revs:
5050 if not revs:
5021 revs = []
5051 revs = []
5022 for b in opts['bookmark']:
5052 for b in opts['bookmark']:
5023 if b not in remotebookmarks:
5053 if b not in remotebookmarks:
5024 raise util.Abort(_('remote bookmark %s not found!') % b)
5054 raise util.Abort(_('remote bookmark %s not found!') % b)
5025 revs.append(remotebookmarks[b])
5055 revs.append(remotebookmarks[b])
5026
5056
5027 if revs:
5057 if revs:
5028 try:
5058 try:
5029 revs = [other.lookup(rev) for rev in revs]
5059 revs = [other.lookup(rev) for rev in revs]
5030 except error.CapabilityError:
5060 except error.CapabilityError:
5031 err = _("other repository doesn't support revision lookup, "
5061 err = _("other repository doesn't support revision lookup, "
5032 "so a rev cannot be specified.")
5062 "so a rev cannot be specified.")
5033 raise util.Abort(err)
5063 raise util.Abort(err)
5034
5064
5035 modheads = exchange.pull(repo, other, heads=revs,
5065 modheads = exchange.pull(repo, other, heads=revs,
5036 force=opts.get('force'),
5066 force=opts.get('force'),
5037 bookmarks=opts.get('bookmark', ())).cgresult
5067 bookmarks=opts.get('bookmark', ())).cgresult
5038 if checkout:
5068 if checkout:
5039 checkout = str(repo.changelog.rev(other.lookup(checkout)))
5069 checkout = str(repo.changelog.rev(other.lookup(checkout)))
5040 repo._subtoppath = source
5070 repo._subtoppath = source
5041 try:
5071 try:
5042 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
5072 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
5043
5073
5044 finally:
5074 finally:
5045 del repo._subtoppath
5075 del repo._subtoppath
5046
5076
5047 finally:
5077 finally:
5048 other.close()
5078 other.close()
5049 return ret
5079 return ret
5050
5080
5051 @command('^push',
5081 @command('^push',
5052 [('f', 'force', None, _('force push')),
5082 [('f', 'force', None, _('force push')),
5053 ('r', 'rev', [],
5083 ('r', 'rev', [],
5054 _('a changeset intended to be included in the destination'),
5084 _('a changeset intended to be included in the destination'),
5055 _('REV')),
5085 _('REV')),
5056 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
5086 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
5057 ('b', 'branch', [],
5087 ('b', 'branch', [],
5058 _('a specific branch you would like to push'), _('BRANCH')),
5088 _('a specific branch you would like to push'), _('BRANCH')),
5059 ('', 'new-branch', False, _('allow pushing a new branch')),
5089 ('', 'new-branch', False, _('allow pushing a new branch')),
5060 ] + remoteopts,
5090 ] + remoteopts,
5061 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
5091 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
5062 def push(ui, repo, dest=None, **opts):
5092 def push(ui, repo, dest=None, **opts):
5063 """push changes to the specified destination
5093 """push changes to the specified destination
5064
5094
5065 Push changesets from the local repository to the specified
5095 Push changesets from the local repository to the specified
5066 destination.
5096 destination.
5067
5097
5068 This operation is symmetrical to pull: it is identical to a pull
5098 This operation is symmetrical to pull: it is identical to a pull
5069 in the destination repository from the current one.
5099 in the destination repository from the current one.
5070
5100
5071 By default, push will not allow creation of new heads at the
5101 By default, push will not allow creation of new heads at the
5072 destination, since multiple heads would make it unclear which head
5102 destination, since multiple heads would make it unclear which head
5073 to use. In this situation, it is recommended to pull and merge
5103 to use. In this situation, it is recommended to pull and merge
5074 before pushing.
5104 before pushing.
5075
5105
5076 Use --new-branch if you want to allow push to create a new named
5106 Use --new-branch if you want to allow push to create a new named
5077 branch that is not present at the destination. This allows you to
5107 branch that is not present at the destination. This allows you to
5078 only create a new branch without forcing other changes.
5108 only create a new branch without forcing other changes.
5079
5109
5080 .. note::
5110 .. note::
5081
5111
5082 Extra care should be taken with the -f/--force option,
5112 Extra care should be taken with the -f/--force option,
5083 which will push all new heads on all branches, an action which will
5113 which will push all new heads on all branches, an action which will
5084 almost always cause confusion for collaborators.
5114 almost always cause confusion for collaborators.
5085
5115
5086 If -r/--rev is used, the specified revision and all its ancestors
5116 If -r/--rev is used, the specified revision and all its ancestors
5087 will be pushed to the remote repository.
5117 will be pushed to the remote repository.
5088
5118
5089 If -B/--bookmark is used, the specified bookmarked revision, its
5119 If -B/--bookmark is used, the specified bookmarked revision, its
5090 ancestors, and the bookmark will be pushed to the remote
5120 ancestors, and the bookmark will be pushed to the remote
5091 repository.
5121 repository.
5092
5122
5093 Please see :hg:`help urls` for important details about ``ssh://``
5123 Please see :hg:`help urls` for important details about ``ssh://``
5094 URLs. If DESTINATION is omitted, a default path will be used.
5124 URLs. If DESTINATION is omitted, a default path will be used.
5095
5125
5096 Returns 0 if push was successful, 1 if nothing to push.
5126 Returns 0 if push was successful, 1 if nothing to push.
5097 """
5127 """
5098
5128
5099 if opts.get('bookmark'):
5129 if opts.get('bookmark'):
5100 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
5130 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
5101 for b in opts['bookmark']:
5131 for b in opts['bookmark']:
5102 # translate -B options to -r so changesets get pushed
5132 # translate -B options to -r so changesets get pushed
5103 if b in repo._bookmarks:
5133 if b in repo._bookmarks:
5104 opts.setdefault('rev', []).append(b)
5134 opts.setdefault('rev', []).append(b)
5105 else:
5135 else:
5106 # if we try to push a deleted bookmark, translate it to null
5136 # if we try to push a deleted bookmark, translate it to null
5107 # this lets simultaneous -r, -b options continue working
5137 # this lets simultaneous -r, -b options continue working
5108 opts.setdefault('rev', []).append("null")
5138 opts.setdefault('rev', []).append("null")
5109
5139
5110 dest = ui.expandpath(dest or 'default-push', dest or 'default')
5140 dest = ui.expandpath(dest or 'default-push', dest or 'default')
5111 dest, branches = hg.parseurl(dest, opts.get('branch'))
5141 dest, branches = hg.parseurl(dest, opts.get('branch'))
5112 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
5142 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
5113 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
5143 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
5114 try:
5144 try:
5115 other = hg.peer(repo, opts, dest)
5145 other = hg.peer(repo, opts, dest)
5116 except error.RepoError:
5146 except error.RepoError:
5117 if dest == "default-push":
5147 if dest == "default-push":
5118 raise util.Abort(_("default repository not configured!"),
5148 raise util.Abort(_("default repository not configured!"),
5119 hint=_('see the "path" section in "hg help config"'))
5149 hint=_('see the "path" section in "hg help config"'))
5120 else:
5150 else:
5121 raise
5151 raise
5122
5152
5123 if revs:
5153 if revs:
5124 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
5154 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
5125
5155
5126 repo._subtoppath = dest
5156 repo._subtoppath = dest
5127 try:
5157 try:
5128 # push subrepos depth-first for coherent ordering
5158 # push subrepos depth-first for coherent ordering
5129 c = repo['']
5159 c = repo['']
5130 subs = c.substate # only repos that are committed
5160 subs = c.substate # only repos that are committed
5131 for s in sorted(subs):
5161 for s in sorted(subs):
5132 result = c.sub(s).push(opts)
5162 result = c.sub(s).push(opts)
5133 if result == 0:
5163 if result == 0:
5134 return not result
5164 return not result
5135 finally:
5165 finally:
5136 del repo._subtoppath
5166 del repo._subtoppath
5137 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
5167 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
5138 newbranch=opts.get('new_branch'),
5168 newbranch=opts.get('new_branch'),
5139 bookmarks=opts.get('bookmark', ()))
5169 bookmarks=opts.get('bookmark', ()))
5140
5170
5141 result = not pushop.cgresult
5171 result = not pushop.cgresult
5142
5172
5143 if pushop.bkresult is not None:
5173 if pushop.bkresult is not None:
5144 if pushop.bkresult == 2:
5174 if pushop.bkresult == 2:
5145 result = 2
5175 result = 2
5146 elif not result and pushop.bkresult:
5176 elif not result and pushop.bkresult:
5147 result = 2
5177 result = 2
5148
5178
5149 return result
5179 return result
5150
5180
5151 @command('recover', [])
5181 @command('recover', [])
5152 def recover(ui, repo):
5182 def recover(ui, repo):
5153 """roll back an interrupted transaction
5183 """roll back an interrupted transaction
5154
5184
5155 Recover from an interrupted commit or pull.
5185 Recover from an interrupted commit or pull.
5156
5186
5157 This command tries to fix the repository status after an
5187 This command tries to fix the repository status after an
5158 interrupted operation. It should only be necessary when Mercurial
5188 interrupted operation. It should only be necessary when Mercurial
5159 suggests it.
5189 suggests it.
5160
5190
5161 Returns 0 if successful, 1 if nothing to recover or verify fails.
5191 Returns 0 if successful, 1 if nothing to recover or verify fails.
5162 """
5192 """
5163 if repo.recover():
5193 if repo.recover():
5164 return hg.verify(repo)
5194 return hg.verify(repo)
5165 return 1
5195 return 1
5166
5196
5167 @command('^remove|rm',
5197 @command('^remove|rm',
5168 [('A', 'after', None, _('record delete for missing files')),
5198 [('A', 'after', None, _('record delete for missing files')),
5169 ('f', 'force', None,
5199 ('f', 'force', None,
5170 _('remove (and delete) file even if added or modified')),
5200 _('remove (and delete) file even if added or modified')),
5171 ] + subrepoopts + walkopts,
5201 ] + subrepoopts + walkopts,
5172 _('[OPTION]... FILE...'),
5202 _('[OPTION]... FILE...'),
5173 inferrepo=True)
5203 inferrepo=True)
5174 def remove(ui, repo, *pats, **opts):
5204 def remove(ui, repo, *pats, **opts):
5175 """remove the specified files on the next commit
5205 """remove the specified files on the next commit
5176
5206
5177 Schedule the indicated files for removal from the current branch.
5207 Schedule the indicated files for removal from the current branch.
5178
5208
5179 This command schedules the files to be removed at the next commit.
5209 This command schedules the files to be removed at the next commit.
5180 To undo a remove before that, see :hg:`revert`. To undo added
5210 To undo a remove before that, see :hg:`revert`. To undo added
5181 files, see :hg:`forget`.
5211 files, see :hg:`forget`.
5182
5212
5183 .. container:: verbose
5213 .. container:: verbose
5184
5214
5185 -A/--after can be used to remove only files that have already
5215 -A/--after can be used to remove only files that have already
5186 been deleted, -f/--force can be used to force deletion, and -Af
5216 been deleted, -f/--force can be used to force deletion, and -Af
5187 can be used to remove files from the next revision without
5217 can be used to remove files from the next revision without
5188 deleting them from the working directory.
5218 deleting them from the working directory.
5189
5219
5190 The following table details the behavior of remove for different
5220 The following table details the behavior of remove for different
5191 file states (columns) and option combinations (rows). The file
5221 file states (columns) and option combinations (rows). The file
5192 states are Added [A], Clean [C], Modified [M] and Missing [!]
5222 states are Added [A], Clean [C], Modified [M] and Missing [!]
5193 (as reported by :hg:`status`). The actions are Warn, Remove
5223 (as reported by :hg:`status`). The actions are Warn, Remove
5194 (from branch) and Delete (from disk):
5224 (from branch) and Delete (from disk):
5195
5225
5196 ========= == == == ==
5226 ========= == == == ==
5197 opt/state A C M !
5227 opt/state A C M !
5198 ========= == == == ==
5228 ========= == == == ==
5199 none W RD W R
5229 none W RD W R
5200 -f R RD RD R
5230 -f R RD RD R
5201 -A W W W R
5231 -A W W W R
5202 -Af R R R R
5232 -Af R R R R
5203 ========= == == == ==
5233 ========= == == == ==
5204
5234
5205 Note that remove never deletes files in Added [A] state from the
5235 Note that remove never deletes files in Added [A] state from the
5206 working directory, not even if option --force is specified.
5236 working directory, not even if option --force is specified.
5207
5237
5208 Returns 0 on success, 1 if any warnings encountered.
5238 Returns 0 on success, 1 if any warnings encountered.
5209 """
5239 """
5210
5240
5211 after, force = opts.get('after'), opts.get('force')
5241 after, force = opts.get('after'), opts.get('force')
5212 if not pats and not after:
5242 if not pats and not after:
5213 raise util.Abort(_('no files specified'))
5243 raise util.Abort(_('no files specified'))
5214
5244
5215 m = scmutil.match(repo[None], pats, opts)
5245 m = scmutil.match(repo[None], pats, opts)
5216 subrepos = opts.get('subrepos')
5246 subrepos = opts.get('subrepos')
5217 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
5247 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
5218
5248
5219 @command('rename|move|mv',
5249 @command('rename|move|mv',
5220 [('A', 'after', None, _('record a rename that has already occurred')),
5250 [('A', 'after', None, _('record a rename that has already occurred')),
5221 ('f', 'force', None, _('forcibly copy over an existing managed file')),
5251 ('f', 'force', None, _('forcibly copy over an existing managed file')),
5222 ] + walkopts + dryrunopts,
5252 ] + walkopts + dryrunopts,
5223 _('[OPTION]... SOURCE... DEST'))
5253 _('[OPTION]... SOURCE... DEST'))
5224 def rename(ui, repo, *pats, **opts):
5254 def rename(ui, repo, *pats, **opts):
5225 """rename files; equivalent of copy + remove
5255 """rename files; equivalent of copy + remove
5226
5256
5227 Mark dest as copies of sources; mark sources for deletion. If dest
5257 Mark dest as copies of sources; mark sources for deletion. If dest
5228 is a directory, copies are put in that directory. If dest is a
5258 is a directory, copies are put in that directory. If dest is a
5229 file, there can only be one source.
5259 file, there can only be one source.
5230
5260
5231 By default, this command copies the contents of files as they
5261 By default, this command copies the contents of files as they
5232 exist in the working directory. If invoked with -A/--after, the
5262 exist in the working directory. If invoked with -A/--after, the
5233 operation is recorded, but no copying is performed.
5263 operation is recorded, but no copying is performed.
5234
5264
5235 This command takes effect at the next commit. To undo a rename
5265 This command takes effect at the next commit. To undo a rename
5236 before that, see :hg:`revert`.
5266 before that, see :hg:`revert`.
5237
5267
5238 Returns 0 on success, 1 if errors are encountered.
5268 Returns 0 on success, 1 if errors are encountered.
5239 """
5269 """
5240 wlock = repo.wlock(False)
5270 wlock = repo.wlock(False)
5241 try:
5271 try:
5242 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5272 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5243 finally:
5273 finally:
5244 wlock.release()
5274 wlock.release()
5245
5275
5246 @command('resolve',
5276 @command('resolve',
5247 [('a', 'all', None, _('select all unresolved files')),
5277 [('a', 'all', None, _('select all unresolved files')),
5248 ('l', 'list', None, _('list state of files needing merge')),
5278 ('l', 'list', None, _('list state of files needing merge')),
5249 ('m', 'mark', None, _('mark files as resolved')),
5279 ('m', 'mark', None, _('mark files as resolved')),
5250 ('u', 'unmark', None, _('mark files as unresolved')),
5280 ('u', 'unmark', None, _('mark files as unresolved')),
5251 ('n', 'no-status', None, _('hide status prefix'))]
5281 ('n', 'no-status', None, _('hide status prefix'))]
5252 + mergetoolopts + walkopts + formatteropts,
5282 + mergetoolopts + walkopts + formatteropts,
5253 _('[OPTION]... [FILE]...'),
5283 _('[OPTION]... [FILE]...'),
5254 inferrepo=True)
5284 inferrepo=True)
5255 def resolve(ui, repo, *pats, **opts):
5285 def resolve(ui, repo, *pats, **opts):
5256 """redo merges or set/view the merge status of files
5286 """redo merges or set/view the merge status of files
5257
5287
5258 Merges with unresolved conflicts are often the result of
5288 Merges with unresolved conflicts are often the result of
5259 non-interactive merging using the ``internal:merge`` configuration
5289 non-interactive merging using the ``internal:merge`` configuration
5260 setting, or a command-line merge tool like ``diff3``. The resolve
5290 setting, or a command-line merge tool like ``diff3``. The resolve
5261 command is used to manage the files involved in a merge, after
5291 command is used to manage the files involved in a merge, after
5262 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5292 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5263 working directory must have two parents). See :hg:`help
5293 working directory must have two parents). See :hg:`help
5264 merge-tools` for information on configuring merge tools.
5294 merge-tools` for information on configuring merge tools.
5265
5295
5266 The resolve command can be used in the following ways:
5296 The resolve command can be used in the following ways:
5267
5297
5268 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
5298 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
5269 files, discarding any previous merge attempts. Re-merging is not
5299 files, discarding any previous merge attempts. Re-merging is not
5270 performed for files already marked as resolved. Use ``--all/-a``
5300 performed for files already marked as resolved. Use ``--all/-a``
5271 to select all unresolved files. ``--tool`` can be used to specify
5301 to select all unresolved files. ``--tool`` can be used to specify
5272 the merge tool used for the given files. It overrides the HGMERGE
5302 the merge tool used for the given files. It overrides the HGMERGE
5273 environment variable and your configuration files. Previous file
5303 environment variable and your configuration files. Previous file
5274 contents are saved with a ``.orig`` suffix.
5304 contents are saved with a ``.orig`` suffix.
5275
5305
5276 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5306 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5277 (e.g. after having manually fixed-up the files). The default is
5307 (e.g. after having manually fixed-up the files). The default is
5278 to mark all unresolved files.
5308 to mark all unresolved files.
5279
5309
5280 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5310 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5281 default is to mark all resolved files.
5311 default is to mark all resolved files.
5282
5312
5283 - :hg:`resolve -l`: list files which had or still have conflicts.
5313 - :hg:`resolve -l`: list files which had or still have conflicts.
5284 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5314 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5285
5315
5286 Note that Mercurial will not let you commit files with unresolved
5316 Note that Mercurial will not let you commit files with unresolved
5287 merge conflicts. You must use :hg:`resolve -m ...` before you can
5317 merge conflicts. You must use :hg:`resolve -m ...` before you can
5288 commit after a conflicting merge.
5318 commit after a conflicting merge.
5289
5319
5290 Returns 0 on success, 1 if any files fail a resolve attempt.
5320 Returns 0 on success, 1 if any files fail a resolve attempt.
5291 """
5321 """
5292
5322
5293 all, mark, unmark, show, nostatus = \
5323 all, mark, unmark, show, nostatus = \
5294 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
5324 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
5295
5325
5296 if (show and (mark or unmark)) or (mark and unmark):
5326 if (show and (mark or unmark)) or (mark and unmark):
5297 raise util.Abort(_("too many options specified"))
5327 raise util.Abort(_("too many options specified"))
5298 if pats and all:
5328 if pats and all:
5299 raise util.Abort(_("can't specify --all and patterns"))
5329 raise util.Abort(_("can't specify --all and patterns"))
5300 if not (all or pats or show or mark or unmark):
5330 if not (all or pats or show or mark or unmark):
5301 raise util.Abort(_('no files or directories specified'),
5331 raise util.Abort(_('no files or directories specified'),
5302 hint=('use --all to remerge all files'))
5332 hint=('use --all to remerge all files'))
5303
5333
5304 if show:
5334 if show:
5305 fm = ui.formatter('resolve', opts)
5335 fm = ui.formatter('resolve', opts)
5306 ms = mergemod.mergestate(repo)
5336 ms = mergemod.mergestate(repo)
5307 m = scmutil.match(repo[None], pats, opts)
5337 m = scmutil.match(repo[None], pats, opts)
5308 for f in ms:
5338 for f in ms:
5309 if not m(f):
5339 if not m(f):
5310 continue
5340 continue
5311 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved'}[ms[f]]
5341 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved'}[ms[f]]
5312 fm.startitem()
5342 fm.startitem()
5313 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
5343 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
5314 fm.write('path', '%s\n', f, label=l)
5344 fm.write('path', '%s\n', f, label=l)
5315 fm.end()
5345 fm.end()
5316 return 0
5346 return 0
5317
5347
5318 wlock = repo.wlock()
5348 wlock = repo.wlock()
5319 try:
5349 try:
5320 ms = mergemod.mergestate(repo)
5350 ms = mergemod.mergestate(repo)
5321
5351
5322 if not (ms.active() or repo.dirstate.p2() != nullid):
5352 if not (ms.active() or repo.dirstate.p2() != nullid):
5323 raise util.Abort(
5353 raise util.Abort(
5324 _('resolve command not applicable when not merging'))
5354 _('resolve command not applicable when not merging'))
5325
5355
5326 m = scmutil.match(repo[None], pats, opts)
5356 m = scmutil.match(repo[None], pats, opts)
5327 ret = 0
5357 ret = 0
5328 didwork = False
5358 didwork = False
5329
5359
5330 for f in ms:
5360 for f in ms:
5331 if not m(f):
5361 if not m(f):
5332 continue
5362 continue
5333
5363
5334 didwork = True
5364 didwork = True
5335
5365
5336 if mark:
5366 if mark:
5337 ms.mark(f, "r")
5367 ms.mark(f, "r")
5338 elif unmark:
5368 elif unmark:
5339 ms.mark(f, "u")
5369 ms.mark(f, "u")
5340 else:
5370 else:
5341 wctx = repo[None]
5371 wctx = repo[None]
5342
5372
5343 # backup pre-resolve (merge uses .orig for its own purposes)
5373 # backup pre-resolve (merge uses .orig for its own purposes)
5344 a = repo.wjoin(f)
5374 a = repo.wjoin(f)
5345 util.copyfile(a, a + ".resolve")
5375 util.copyfile(a, a + ".resolve")
5346
5376
5347 try:
5377 try:
5348 # resolve file
5378 # resolve file
5349 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5379 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5350 'resolve')
5380 'resolve')
5351 if ms.resolve(f, wctx):
5381 if ms.resolve(f, wctx):
5352 ret = 1
5382 ret = 1
5353 finally:
5383 finally:
5354 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5384 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5355 ms.commit()
5385 ms.commit()
5356
5386
5357 # replace filemerge's .orig file with our resolve file
5387 # replace filemerge's .orig file with our resolve file
5358 util.rename(a + ".resolve", a + ".orig")
5388 util.rename(a + ".resolve", a + ".orig")
5359
5389
5360 ms.commit()
5390 ms.commit()
5361
5391
5362 if not didwork and pats:
5392 if not didwork and pats:
5363 ui.warn(_("arguments do not match paths that need resolving\n"))
5393 ui.warn(_("arguments do not match paths that need resolving\n"))
5364
5394
5365 finally:
5395 finally:
5366 wlock.release()
5396 wlock.release()
5367
5397
5368 # Nudge users into finishing an unfinished operation
5398 # Nudge users into finishing an unfinished operation
5369 if not list(ms.unresolved()):
5399 if not list(ms.unresolved()):
5370 ui.status(_('(no more unresolved files)\n'))
5400 ui.status(_('(no more unresolved files)\n'))
5371
5401
5372 return ret
5402 return ret
5373
5403
5374 @command('revert',
5404 @command('revert',
5375 [('a', 'all', None, _('revert all changes when no arguments given')),
5405 [('a', 'all', None, _('revert all changes when no arguments given')),
5376 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5406 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5377 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5407 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5378 ('C', 'no-backup', None, _('do not save backup copies of files')),
5408 ('C', 'no-backup', None, _('do not save backup copies of files')),
5379 ('i', 'interactive', None, _('interactively select the changes')),
5409 ('i', 'interactive', None, _('interactively select the changes')),
5380 ] + walkopts + dryrunopts,
5410 ] + walkopts + dryrunopts,
5381 _('[OPTION]... [-r REV] [NAME]...'))
5411 _('[OPTION]... [-r REV] [NAME]...'))
5382 def revert(ui, repo, *pats, **opts):
5412 def revert(ui, repo, *pats, **opts):
5383 """restore files to their checkout state
5413 """restore files to their checkout state
5384
5414
5385 .. note::
5415 .. note::
5386
5416
5387 To check out earlier revisions, you should use :hg:`update REV`.
5417 To check out earlier revisions, you should use :hg:`update REV`.
5388 To cancel an uncommitted merge (and lose your changes),
5418 To cancel an uncommitted merge (and lose your changes),
5389 use :hg:`update --clean .`.
5419 use :hg:`update --clean .`.
5390
5420
5391 With no revision specified, revert the specified files or directories
5421 With no revision specified, revert the specified files or directories
5392 to the contents they had in the parent of the working directory.
5422 to the contents they had in the parent of the working directory.
5393 This restores the contents of files to an unmodified
5423 This restores the contents of files to an unmodified
5394 state and unschedules adds, removes, copies, and renames. If the
5424 state and unschedules adds, removes, copies, and renames. If the
5395 working directory has two parents, you must explicitly specify a
5425 working directory has two parents, you must explicitly specify a
5396 revision.
5426 revision.
5397
5427
5398 Using the -r/--rev or -d/--date options, revert the given files or
5428 Using the -r/--rev or -d/--date options, revert the given files or
5399 directories to their states as of a specific revision. Because
5429 directories to their states as of a specific revision. Because
5400 revert does not change the working directory parents, this will
5430 revert does not change the working directory parents, this will
5401 cause these files to appear modified. This can be helpful to "back
5431 cause these files to appear modified. This can be helpful to "back
5402 out" some or all of an earlier change. See :hg:`backout` for a
5432 out" some or all of an earlier change. See :hg:`backout` for a
5403 related method.
5433 related method.
5404
5434
5405 Modified files are saved with a .orig suffix before reverting.
5435 Modified files are saved with a .orig suffix before reverting.
5406 To disable these backups, use --no-backup.
5436 To disable these backups, use --no-backup.
5407
5437
5408 See :hg:`help dates` for a list of formats valid for -d/--date.
5438 See :hg:`help dates` for a list of formats valid for -d/--date.
5409
5439
5410 Returns 0 on success.
5440 Returns 0 on success.
5411 """
5441 """
5412
5442
5413 if opts.get("date"):
5443 if opts.get("date"):
5414 if opts.get("rev"):
5444 if opts.get("rev"):
5415 raise util.Abort(_("you can't specify a revision and a date"))
5445 raise util.Abort(_("you can't specify a revision and a date"))
5416 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5446 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5417
5447
5418 parent, p2 = repo.dirstate.parents()
5448 parent, p2 = repo.dirstate.parents()
5419 if not opts.get('rev') and p2 != nullid:
5449 if not opts.get('rev') and p2 != nullid:
5420 # revert after merge is a trap for new users (issue2915)
5450 # revert after merge is a trap for new users (issue2915)
5421 raise util.Abort(_('uncommitted merge with no revision specified'),
5451 raise util.Abort(_('uncommitted merge with no revision specified'),
5422 hint=_('use "hg update" or see "hg help revert"'))
5452 hint=_('use "hg update" or see "hg help revert"'))
5423
5453
5424 ctx = scmutil.revsingle(repo, opts.get('rev'))
5454 ctx = scmutil.revsingle(repo, opts.get('rev'))
5425
5455
5426 if not pats and not opts.get('all'):
5456 if not pats and not opts.get('all'):
5427 msg = _("no files or directories specified")
5457 msg = _("no files or directories specified")
5428 if p2 != nullid:
5458 if p2 != nullid:
5429 hint = _("uncommitted merge, use --all to discard all changes,"
5459 hint = _("uncommitted merge, use --all to discard all changes,"
5430 " or 'hg update -C .' to abort the merge")
5460 " or 'hg update -C .' to abort the merge")
5431 raise util.Abort(msg, hint=hint)
5461 raise util.Abort(msg, hint=hint)
5432 dirty = util.any(repo.status())
5462 dirty = util.any(repo.status())
5433 node = ctx.node()
5463 node = ctx.node()
5434 if node != parent:
5464 if node != parent:
5435 if dirty:
5465 if dirty:
5436 hint = _("uncommitted changes, use --all to discard all"
5466 hint = _("uncommitted changes, use --all to discard all"
5437 " changes, or 'hg update %s' to update") % ctx.rev()
5467 " changes, or 'hg update %s' to update") % ctx.rev()
5438 else:
5468 else:
5439 hint = _("use --all to revert all files,"
5469 hint = _("use --all to revert all files,"
5440 " or 'hg update %s' to update") % ctx.rev()
5470 " or 'hg update %s' to update") % ctx.rev()
5441 elif dirty:
5471 elif dirty:
5442 hint = _("uncommitted changes, use --all to discard all changes")
5472 hint = _("uncommitted changes, use --all to discard all changes")
5443 else:
5473 else:
5444 hint = _("use --all to revert all files")
5474 hint = _("use --all to revert all files")
5445 raise util.Abort(msg, hint=hint)
5475 raise util.Abort(msg, hint=hint)
5446
5476
5447 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5477 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5448
5478
5449 @command('rollback', dryrunopts +
5479 @command('rollback', dryrunopts +
5450 [('f', 'force', False, _('ignore safety measures'))])
5480 [('f', 'force', False, _('ignore safety measures'))])
5451 def rollback(ui, repo, **opts):
5481 def rollback(ui, repo, **opts):
5452 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5482 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5453
5483
5454 Please use :hg:`commit --amend` instead of rollback to correct
5484 Please use :hg:`commit --amend` instead of rollback to correct
5455 mistakes in the last commit.
5485 mistakes in the last commit.
5456
5486
5457 This command should be used with care. There is only one level of
5487 This command should be used with care. There is only one level of
5458 rollback, and there is no way to undo a rollback. It will also
5488 rollback, and there is no way to undo a rollback. It will also
5459 restore the dirstate at the time of the last transaction, losing
5489 restore the dirstate at the time of the last transaction, losing
5460 any dirstate changes since that time. This command does not alter
5490 any dirstate changes since that time. This command does not alter
5461 the working directory.
5491 the working directory.
5462
5492
5463 Transactions are used to encapsulate the effects of all commands
5493 Transactions are used to encapsulate the effects of all commands
5464 that create new changesets or propagate existing changesets into a
5494 that create new changesets or propagate existing changesets into a
5465 repository.
5495 repository.
5466
5496
5467 .. container:: verbose
5497 .. container:: verbose
5468
5498
5469 For example, the following commands are transactional, and their
5499 For example, the following commands are transactional, and their
5470 effects can be rolled back:
5500 effects can be rolled back:
5471
5501
5472 - commit
5502 - commit
5473 - import
5503 - import
5474 - pull
5504 - pull
5475 - push (with this repository as the destination)
5505 - push (with this repository as the destination)
5476 - unbundle
5506 - unbundle
5477
5507
5478 To avoid permanent data loss, rollback will refuse to rollback a
5508 To avoid permanent data loss, rollback will refuse to rollback a
5479 commit transaction if it isn't checked out. Use --force to
5509 commit transaction if it isn't checked out. Use --force to
5480 override this protection.
5510 override this protection.
5481
5511
5482 This command is not intended for use on public repositories. Once
5512 This command is not intended for use on public repositories. Once
5483 changes are visible for pull by other users, rolling a transaction
5513 changes are visible for pull by other users, rolling a transaction
5484 back locally is ineffective (someone else may already have pulled
5514 back locally is ineffective (someone else may already have pulled
5485 the changes). Furthermore, a race is possible with readers of the
5515 the changes). Furthermore, a race is possible with readers of the
5486 repository; for example an in-progress pull from the repository
5516 repository; for example an in-progress pull from the repository
5487 may fail if a rollback is performed.
5517 may fail if a rollback is performed.
5488
5518
5489 Returns 0 on success, 1 if no rollback data is available.
5519 Returns 0 on success, 1 if no rollback data is available.
5490 """
5520 """
5491 return repo.rollback(dryrun=opts.get('dry_run'),
5521 return repo.rollback(dryrun=opts.get('dry_run'),
5492 force=opts.get('force'))
5522 force=opts.get('force'))
5493
5523
5494 @command('root', [])
5524 @command('root', [])
5495 def root(ui, repo):
5525 def root(ui, repo):
5496 """print the root (top) of the current working directory
5526 """print the root (top) of the current working directory
5497
5527
5498 Print the root directory of the current repository.
5528 Print the root directory of the current repository.
5499
5529
5500 Returns 0 on success.
5530 Returns 0 on success.
5501 """
5531 """
5502 ui.write(repo.root + "\n")
5532 ui.write(repo.root + "\n")
5503
5533
5504 @command('^serve',
5534 @command('^serve',
5505 [('A', 'accesslog', '', _('name of access log file to write to'),
5535 [('A', 'accesslog', '', _('name of access log file to write to'),
5506 _('FILE')),
5536 _('FILE')),
5507 ('d', 'daemon', None, _('run server in background')),
5537 ('d', 'daemon', None, _('run server in background')),
5508 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('FILE')),
5538 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('FILE')),
5509 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5539 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5510 # use string type, then we can check if something was passed
5540 # use string type, then we can check if something was passed
5511 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5541 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5512 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5542 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5513 _('ADDR')),
5543 _('ADDR')),
5514 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5544 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5515 _('PREFIX')),
5545 _('PREFIX')),
5516 ('n', 'name', '',
5546 ('n', 'name', '',
5517 _('name to show in web pages (default: working directory)'), _('NAME')),
5547 _('name to show in web pages (default: working directory)'), _('NAME')),
5518 ('', 'web-conf', '',
5548 ('', 'web-conf', '',
5519 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5549 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5520 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5550 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5521 _('FILE')),
5551 _('FILE')),
5522 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5552 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5523 ('', 'stdio', None, _('for remote clients')),
5553 ('', 'stdio', None, _('for remote clients')),
5524 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5554 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5525 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5555 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5526 ('', 'style', '', _('template style to use'), _('STYLE')),
5556 ('', 'style', '', _('template style to use'), _('STYLE')),
5527 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5557 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5528 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5558 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5529 _('[OPTION]...'),
5559 _('[OPTION]...'),
5530 optionalrepo=True)
5560 optionalrepo=True)
5531 def serve(ui, repo, **opts):
5561 def serve(ui, repo, **opts):
5532 """start stand-alone webserver
5562 """start stand-alone webserver
5533
5563
5534 Start a local HTTP repository browser and pull server. You can use
5564 Start a local HTTP repository browser and pull server. You can use
5535 this for ad-hoc sharing and browsing of repositories. It is
5565 this for ad-hoc sharing and browsing of repositories. It is
5536 recommended to use a real web server to serve a repository for
5566 recommended to use a real web server to serve a repository for
5537 longer periods of time.
5567 longer periods of time.
5538
5568
5539 Please note that the server does not implement access control.
5569 Please note that the server does not implement access control.
5540 This means that, by default, anybody can read from the server and
5570 This means that, by default, anybody can read from the server and
5541 nobody can write to it by default. Set the ``web.allow_push``
5571 nobody can write to it by default. Set the ``web.allow_push``
5542 option to ``*`` to allow everybody to push to the server. You
5572 option to ``*`` to allow everybody to push to the server. You
5543 should use a real web server if you need to authenticate users.
5573 should use a real web server if you need to authenticate users.
5544
5574
5545 By default, the server logs accesses to stdout and errors to
5575 By default, the server logs accesses to stdout and errors to
5546 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5576 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5547 files.
5577 files.
5548
5578
5549 To have the server choose a free port number to listen on, specify
5579 To have the server choose a free port number to listen on, specify
5550 a port number of 0; in this case, the server will print the port
5580 a port number of 0; in this case, the server will print the port
5551 number it uses.
5581 number it uses.
5552
5582
5553 Returns 0 on success.
5583 Returns 0 on success.
5554 """
5584 """
5555
5585
5556 if opts["stdio"] and opts["cmdserver"]:
5586 if opts["stdio"] and opts["cmdserver"]:
5557 raise util.Abort(_("cannot use --stdio with --cmdserver"))
5587 raise util.Abort(_("cannot use --stdio with --cmdserver"))
5558
5588
5559 if opts["stdio"]:
5589 if opts["stdio"]:
5560 if repo is None:
5590 if repo is None:
5561 raise error.RepoError(_("there is no Mercurial repository here"
5591 raise error.RepoError(_("there is no Mercurial repository here"
5562 " (.hg not found)"))
5592 " (.hg not found)"))
5563 s = sshserver.sshserver(ui, repo)
5593 s = sshserver.sshserver(ui, repo)
5564 s.serve_forever()
5594 s.serve_forever()
5565
5595
5566 if opts["cmdserver"]:
5596 if opts["cmdserver"]:
5567 service = commandserver.createservice(ui, repo, opts)
5597 service = commandserver.createservice(ui, repo, opts)
5568 return cmdutil.service(opts, initfn=service.init, runfn=service.run)
5598 return cmdutil.service(opts, initfn=service.init, runfn=service.run)
5569
5599
5570 # this way we can check if something was given in the command-line
5600 # this way we can check if something was given in the command-line
5571 if opts.get('port'):
5601 if opts.get('port'):
5572 opts['port'] = util.getport(opts.get('port'))
5602 opts['port'] = util.getport(opts.get('port'))
5573
5603
5574 if repo:
5604 if repo:
5575 baseui = repo.baseui
5605 baseui = repo.baseui
5576 else:
5606 else:
5577 baseui = ui
5607 baseui = ui
5578 optlist = ("name templates style address port prefix ipv6"
5608 optlist = ("name templates style address port prefix ipv6"
5579 " accesslog errorlog certificate encoding")
5609 " accesslog errorlog certificate encoding")
5580 for o in optlist.split():
5610 for o in optlist.split():
5581 val = opts.get(o, '')
5611 val = opts.get(o, '')
5582 if val in (None, ''): # should check against default options instead
5612 if val in (None, ''): # should check against default options instead
5583 continue
5613 continue
5584 baseui.setconfig("web", o, val, 'serve')
5614 baseui.setconfig("web", o, val, 'serve')
5585 if repo and repo.ui != baseui:
5615 if repo and repo.ui != baseui:
5586 repo.ui.setconfig("web", o, val, 'serve')
5616 repo.ui.setconfig("web", o, val, 'serve')
5587
5617
5588 o = opts.get('web_conf') or opts.get('webdir_conf')
5618 o = opts.get('web_conf') or opts.get('webdir_conf')
5589 if not o:
5619 if not o:
5590 if not repo:
5620 if not repo:
5591 raise error.RepoError(_("there is no Mercurial repository"
5621 raise error.RepoError(_("there is no Mercurial repository"
5592 " here (.hg not found)"))
5622 " here (.hg not found)"))
5593 o = repo
5623 o = repo
5594
5624
5595 app = hgweb.hgweb(o, baseui=baseui)
5625 app = hgweb.hgweb(o, baseui=baseui)
5596 service = httpservice(ui, app, opts)
5626 service = httpservice(ui, app, opts)
5597 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5627 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5598
5628
5599 class httpservice(object):
5629 class httpservice(object):
5600 def __init__(self, ui, app, opts):
5630 def __init__(self, ui, app, opts):
5601 self.ui = ui
5631 self.ui = ui
5602 self.app = app
5632 self.app = app
5603 self.opts = opts
5633 self.opts = opts
5604
5634
5605 def init(self):
5635 def init(self):
5606 util.setsignalhandler()
5636 util.setsignalhandler()
5607 self.httpd = hgweb_server.create_server(self.ui, self.app)
5637 self.httpd = hgweb_server.create_server(self.ui, self.app)
5608
5638
5609 if self.opts['port'] and not self.ui.verbose:
5639 if self.opts['port'] and not self.ui.verbose:
5610 return
5640 return
5611
5641
5612 if self.httpd.prefix:
5642 if self.httpd.prefix:
5613 prefix = self.httpd.prefix.strip('/') + '/'
5643 prefix = self.httpd.prefix.strip('/') + '/'
5614 else:
5644 else:
5615 prefix = ''
5645 prefix = ''
5616
5646
5617 port = ':%d' % self.httpd.port
5647 port = ':%d' % self.httpd.port
5618 if port == ':80':
5648 if port == ':80':
5619 port = ''
5649 port = ''
5620
5650
5621 bindaddr = self.httpd.addr
5651 bindaddr = self.httpd.addr
5622 if bindaddr == '0.0.0.0':
5652 if bindaddr == '0.0.0.0':
5623 bindaddr = '*'
5653 bindaddr = '*'
5624 elif ':' in bindaddr: # IPv6
5654 elif ':' in bindaddr: # IPv6
5625 bindaddr = '[%s]' % bindaddr
5655 bindaddr = '[%s]' % bindaddr
5626
5656
5627 fqaddr = self.httpd.fqaddr
5657 fqaddr = self.httpd.fqaddr
5628 if ':' in fqaddr:
5658 if ':' in fqaddr:
5629 fqaddr = '[%s]' % fqaddr
5659 fqaddr = '[%s]' % fqaddr
5630 if self.opts['port']:
5660 if self.opts['port']:
5631 write = self.ui.status
5661 write = self.ui.status
5632 else:
5662 else:
5633 write = self.ui.write
5663 write = self.ui.write
5634 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5664 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5635 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5665 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5636 self.ui.flush() # avoid buffering of status message
5666 self.ui.flush() # avoid buffering of status message
5637
5667
5638 def run(self):
5668 def run(self):
5639 self.httpd.serve_forever()
5669 self.httpd.serve_forever()
5640
5670
5641
5671
5642 @command('^status|st',
5672 @command('^status|st',
5643 [('A', 'all', None, _('show status of all files')),
5673 [('A', 'all', None, _('show status of all files')),
5644 ('m', 'modified', None, _('show only modified files')),
5674 ('m', 'modified', None, _('show only modified files')),
5645 ('a', 'added', None, _('show only added files')),
5675 ('a', 'added', None, _('show only added files')),
5646 ('r', 'removed', None, _('show only removed files')),
5676 ('r', 'removed', None, _('show only removed files')),
5647 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5677 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5648 ('c', 'clean', None, _('show only files without changes')),
5678 ('c', 'clean', None, _('show only files without changes')),
5649 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5679 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5650 ('i', 'ignored', None, _('show only ignored files')),
5680 ('i', 'ignored', None, _('show only ignored files')),
5651 ('n', 'no-status', None, _('hide status prefix')),
5681 ('n', 'no-status', None, _('hide status prefix')),
5652 ('C', 'copies', None, _('show source of copied files')),
5682 ('C', 'copies', None, _('show source of copied files')),
5653 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5683 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5654 ('', 'rev', [], _('show difference from revision'), _('REV')),
5684 ('', 'rev', [], _('show difference from revision'), _('REV')),
5655 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5685 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5656 ] + walkopts + subrepoopts + formatteropts,
5686 ] + walkopts + subrepoopts + formatteropts,
5657 _('[OPTION]... [FILE]...'),
5687 _('[OPTION]... [FILE]...'),
5658 inferrepo=True)
5688 inferrepo=True)
5659 def status(ui, repo, *pats, **opts):
5689 def status(ui, repo, *pats, **opts):
5660 """show changed files in the working directory
5690 """show changed files in the working directory
5661
5691
5662 Show status of files in the repository. If names are given, only
5692 Show status of files in the repository. If names are given, only
5663 files that match are shown. Files that are clean or ignored or
5693 files that match are shown. Files that are clean or ignored or
5664 the source of a copy/move operation, are not listed unless
5694 the source of a copy/move operation, are not listed unless
5665 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5695 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5666 Unless options described with "show only ..." are given, the
5696 Unless options described with "show only ..." are given, the
5667 options -mardu are used.
5697 options -mardu are used.
5668
5698
5669 Option -q/--quiet hides untracked (unknown and ignored) files
5699 Option -q/--quiet hides untracked (unknown and ignored) files
5670 unless explicitly requested with -u/--unknown or -i/--ignored.
5700 unless explicitly requested with -u/--unknown or -i/--ignored.
5671
5701
5672 .. note::
5702 .. note::
5673
5703
5674 status may appear to disagree with diff if permissions have
5704 status may appear to disagree with diff if permissions have
5675 changed or a merge has occurred. The standard diff format does
5705 changed or a merge has occurred. The standard diff format does
5676 not report permission changes and diff only reports changes
5706 not report permission changes and diff only reports changes
5677 relative to one merge parent.
5707 relative to one merge parent.
5678
5708
5679 If one revision is given, it is used as the base revision.
5709 If one revision is given, it is used as the base revision.
5680 If two revisions are given, the differences between them are
5710 If two revisions are given, the differences between them are
5681 shown. The --change option can also be used as a shortcut to list
5711 shown. The --change option can also be used as a shortcut to list
5682 the changed files of a revision from its first parent.
5712 the changed files of a revision from its first parent.
5683
5713
5684 The codes used to show the status of files are::
5714 The codes used to show the status of files are::
5685
5715
5686 M = modified
5716 M = modified
5687 A = added
5717 A = added
5688 R = removed
5718 R = removed
5689 C = clean
5719 C = clean
5690 ! = missing (deleted by non-hg command, but still tracked)
5720 ! = missing (deleted by non-hg command, but still tracked)
5691 ? = not tracked
5721 ? = not tracked
5692 I = ignored
5722 I = ignored
5693 = origin of the previous file (with --copies)
5723 = origin of the previous file (with --copies)
5694
5724
5695 .. container:: verbose
5725 .. container:: verbose
5696
5726
5697 Examples:
5727 Examples:
5698
5728
5699 - show changes in the working directory relative to a
5729 - show changes in the working directory relative to a
5700 changeset::
5730 changeset::
5701
5731
5702 hg status --rev 9353
5732 hg status --rev 9353
5703
5733
5704 - show all changes including copies in an existing changeset::
5734 - show all changes including copies in an existing changeset::
5705
5735
5706 hg status --copies --change 9353
5736 hg status --copies --change 9353
5707
5737
5708 - get a NUL separated list of added files, suitable for xargs::
5738 - get a NUL separated list of added files, suitable for xargs::
5709
5739
5710 hg status -an0
5740 hg status -an0
5711
5741
5712 Returns 0 on success.
5742 Returns 0 on success.
5713 """
5743 """
5714
5744
5715 revs = opts.get('rev')
5745 revs = opts.get('rev')
5716 change = opts.get('change')
5746 change = opts.get('change')
5717
5747
5718 if revs and change:
5748 if revs and change:
5719 msg = _('cannot specify --rev and --change at the same time')
5749 msg = _('cannot specify --rev and --change at the same time')
5720 raise util.Abort(msg)
5750 raise util.Abort(msg)
5721 elif change:
5751 elif change:
5722 node2 = scmutil.revsingle(repo, change, None).node()
5752 node2 = scmutil.revsingle(repo, change, None).node()
5723 node1 = repo[node2].p1().node()
5753 node1 = repo[node2].p1().node()
5724 else:
5754 else:
5725 node1, node2 = scmutil.revpair(repo, revs)
5755 node1, node2 = scmutil.revpair(repo, revs)
5726
5756
5727 if pats:
5757 if pats:
5728 cwd = repo.getcwd()
5758 cwd = repo.getcwd()
5729 else:
5759 else:
5730 cwd = ''
5760 cwd = ''
5731
5761
5732 if opts.get('print0'):
5762 if opts.get('print0'):
5733 end = '\0'
5763 end = '\0'
5734 else:
5764 else:
5735 end = '\n'
5765 end = '\n'
5736 copy = {}
5766 copy = {}
5737 states = 'modified added removed deleted unknown ignored clean'.split()
5767 states = 'modified added removed deleted unknown ignored clean'.split()
5738 show = [k for k in states if opts.get(k)]
5768 show = [k for k in states if opts.get(k)]
5739 if opts.get('all'):
5769 if opts.get('all'):
5740 show += ui.quiet and (states[:4] + ['clean']) or states
5770 show += ui.quiet and (states[:4] + ['clean']) or states
5741 if not show:
5771 if not show:
5742 if ui.quiet:
5772 if ui.quiet:
5743 show = states[:4]
5773 show = states[:4]
5744 else:
5774 else:
5745 show = states[:5]
5775 show = states[:5]
5746
5776
5747 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5777 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5748 'ignored' in show, 'clean' in show, 'unknown' in show,
5778 'ignored' in show, 'clean' in show, 'unknown' in show,
5749 opts.get('subrepos'))
5779 opts.get('subrepos'))
5750 changestates = zip(states, 'MAR!?IC', stat)
5780 changestates = zip(states, 'MAR!?IC', stat)
5751
5781
5752 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5782 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5753 copy = copies.pathcopies(repo[node1], repo[node2])
5783 copy = copies.pathcopies(repo[node1], repo[node2])
5754
5784
5755 fm = ui.formatter('status', opts)
5785 fm = ui.formatter('status', opts)
5756 fmt = '%s' + end
5786 fmt = '%s' + end
5757 showchar = not opts.get('no_status')
5787 showchar = not opts.get('no_status')
5758
5788
5759 for state, char, files in changestates:
5789 for state, char, files in changestates:
5760 if state in show:
5790 if state in show:
5761 label = 'status.' + state
5791 label = 'status.' + state
5762 for f in files:
5792 for f in files:
5763 fm.startitem()
5793 fm.startitem()
5764 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5794 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5765 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5795 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5766 if f in copy:
5796 if f in copy:
5767 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5797 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5768 label='status.copied')
5798 label='status.copied')
5769 fm.end()
5799 fm.end()
5770
5800
5771 @command('^summary|sum',
5801 @command('^summary|sum',
5772 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5802 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5773 def summary(ui, repo, **opts):
5803 def summary(ui, repo, **opts):
5774 """summarize working directory state
5804 """summarize working directory state
5775
5805
5776 This generates a brief summary of the working directory state,
5806 This generates a brief summary of the working directory state,
5777 including parents, branch, commit status, and available updates.
5807 including parents, branch, commit status, and available updates.
5778
5808
5779 With the --remote option, this will check the default paths for
5809 With the --remote option, this will check the default paths for
5780 incoming and outgoing changes. This can be time-consuming.
5810 incoming and outgoing changes. This can be time-consuming.
5781
5811
5782 Returns 0 on success.
5812 Returns 0 on success.
5783 """
5813 """
5784
5814
5785 ctx = repo[None]
5815 ctx = repo[None]
5786 parents = ctx.parents()
5816 parents = ctx.parents()
5787 pnode = parents[0].node()
5817 pnode = parents[0].node()
5788 marks = []
5818 marks = []
5789
5819
5790 for p in parents:
5820 for p in parents:
5791 # label with log.changeset (instead of log.parent) since this
5821 # label with log.changeset (instead of log.parent) since this
5792 # shows a working directory parent *changeset*:
5822 # shows a working directory parent *changeset*:
5793 # i18n: column positioning for "hg summary"
5823 # i18n: column positioning for "hg summary"
5794 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5824 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5795 label='log.changeset changeset.%s' % p.phasestr())
5825 label='log.changeset changeset.%s' % p.phasestr())
5796 ui.write(' '.join(p.tags()), label='log.tag')
5826 ui.write(' '.join(p.tags()), label='log.tag')
5797 if p.bookmarks():
5827 if p.bookmarks():
5798 marks.extend(p.bookmarks())
5828 marks.extend(p.bookmarks())
5799 if p.rev() == -1:
5829 if p.rev() == -1:
5800 if not len(repo):
5830 if not len(repo):
5801 ui.write(_(' (empty repository)'))
5831 ui.write(_(' (empty repository)'))
5802 else:
5832 else:
5803 ui.write(_(' (no revision checked out)'))
5833 ui.write(_(' (no revision checked out)'))
5804 ui.write('\n')
5834 ui.write('\n')
5805 if p.description():
5835 if p.description():
5806 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5836 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5807 label='log.summary')
5837 label='log.summary')
5808
5838
5809 branch = ctx.branch()
5839 branch = ctx.branch()
5810 bheads = repo.branchheads(branch)
5840 bheads = repo.branchheads(branch)
5811 # i18n: column positioning for "hg summary"
5841 # i18n: column positioning for "hg summary"
5812 m = _('branch: %s\n') % branch
5842 m = _('branch: %s\n') % branch
5813 if branch != 'default':
5843 if branch != 'default':
5814 ui.write(m, label='log.branch')
5844 ui.write(m, label='log.branch')
5815 else:
5845 else:
5816 ui.status(m, label='log.branch')
5846 ui.status(m, label='log.branch')
5817
5847
5818 if marks:
5848 if marks:
5819 current = repo._bookmarkcurrent
5849 current = repo._bookmarkcurrent
5820 # i18n: column positioning for "hg summary"
5850 # i18n: column positioning for "hg summary"
5821 ui.write(_('bookmarks:'), label='log.bookmark')
5851 ui.write(_('bookmarks:'), label='log.bookmark')
5822 if current is not None:
5852 if current is not None:
5823 if current in marks:
5853 if current in marks:
5824 ui.write(' *' + current, label='bookmarks.current')
5854 ui.write(' *' + current, label='bookmarks.current')
5825 marks.remove(current)
5855 marks.remove(current)
5826 else:
5856 else:
5827 ui.write(' [%s]' % current, label='bookmarks.current')
5857 ui.write(' [%s]' % current, label='bookmarks.current')
5828 for m in marks:
5858 for m in marks:
5829 ui.write(' ' + m, label='log.bookmark')
5859 ui.write(' ' + m, label='log.bookmark')
5830 ui.write('\n', label='log.bookmark')
5860 ui.write('\n', label='log.bookmark')
5831
5861
5832 status = repo.status(unknown=True)
5862 status = repo.status(unknown=True)
5833
5863
5834 c = repo.dirstate.copies()
5864 c = repo.dirstate.copies()
5835 copied, renamed = [], []
5865 copied, renamed = [], []
5836 for d, s in c.iteritems():
5866 for d, s in c.iteritems():
5837 if s in status.removed:
5867 if s in status.removed:
5838 status.removed.remove(s)
5868 status.removed.remove(s)
5839 renamed.append(d)
5869 renamed.append(d)
5840 else:
5870 else:
5841 copied.append(d)
5871 copied.append(d)
5842 if d in status.added:
5872 if d in status.added:
5843 status.added.remove(d)
5873 status.added.remove(d)
5844
5874
5845 ms = mergemod.mergestate(repo)
5875 ms = mergemod.mergestate(repo)
5846 unresolved = [f for f in ms if ms[f] == 'u']
5876 unresolved = [f for f in ms if ms[f] == 'u']
5847
5877
5848 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5878 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5849
5879
5850 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
5880 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
5851 (ui.label(_('%d added'), 'status.added'), status.added),
5881 (ui.label(_('%d added'), 'status.added'), status.added),
5852 (ui.label(_('%d removed'), 'status.removed'), status.removed),
5882 (ui.label(_('%d removed'), 'status.removed'), status.removed),
5853 (ui.label(_('%d renamed'), 'status.copied'), renamed),
5883 (ui.label(_('%d renamed'), 'status.copied'), renamed),
5854 (ui.label(_('%d copied'), 'status.copied'), copied),
5884 (ui.label(_('%d copied'), 'status.copied'), copied),
5855 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
5885 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
5856 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
5886 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
5857 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
5887 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
5858 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
5888 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
5859 t = []
5889 t = []
5860 for l, s in labels:
5890 for l, s in labels:
5861 if s:
5891 if s:
5862 t.append(l % len(s))
5892 t.append(l % len(s))
5863
5893
5864 t = ', '.join(t)
5894 t = ', '.join(t)
5865 cleanworkdir = False
5895 cleanworkdir = False
5866
5896
5867 if repo.vfs.exists('updatestate'):
5897 if repo.vfs.exists('updatestate'):
5868 t += _(' (interrupted update)')
5898 t += _(' (interrupted update)')
5869 elif len(parents) > 1:
5899 elif len(parents) > 1:
5870 t += _(' (merge)')
5900 t += _(' (merge)')
5871 elif branch != parents[0].branch():
5901 elif branch != parents[0].branch():
5872 t += _(' (new branch)')
5902 t += _(' (new branch)')
5873 elif (parents[0].closesbranch() and
5903 elif (parents[0].closesbranch() and
5874 pnode in repo.branchheads(branch, closed=True)):
5904 pnode in repo.branchheads(branch, closed=True)):
5875 t += _(' (head closed)')
5905 t += _(' (head closed)')
5876 elif not (status.modified or status.added or status.removed or renamed or
5906 elif not (status.modified or status.added or status.removed or renamed or
5877 copied or subs):
5907 copied or subs):
5878 t += _(' (clean)')
5908 t += _(' (clean)')
5879 cleanworkdir = True
5909 cleanworkdir = True
5880 elif pnode not in bheads:
5910 elif pnode not in bheads:
5881 t += _(' (new branch head)')
5911 t += _(' (new branch head)')
5882
5912
5883 if cleanworkdir:
5913 if cleanworkdir:
5884 # i18n: column positioning for "hg summary"
5914 # i18n: column positioning for "hg summary"
5885 ui.status(_('commit: %s\n') % t.strip())
5915 ui.status(_('commit: %s\n') % t.strip())
5886 else:
5916 else:
5887 # i18n: column positioning for "hg summary"
5917 # i18n: column positioning for "hg summary"
5888 ui.write(_('commit: %s\n') % t.strip())
5918 ui.write(_('commit: %s\n') % t.strip())
5889
5919
5890 # all ancestors of branch heads - all ancestors of parent = new csets
5920 # all ancestors of branch heads - all ancestors of parent = new csets
5891 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
5921 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
5892 bheads))
5922 bheads))
5893
5923
5894 if new == 0:
5924 if new == 0:
5895 # i18n: column positioning for "hg summary"
5925 # i18n: column positioning for "hg summary"
5896 ui.status(_('update: (current)\n'))
5926 ui.status(_('update: (current)\n'))
5897 elif pnode not in bheads:
5927 elif pnode not in bheads:
5898 # i18n: column positioning for "hg summary"
5928 # i18n: column positioning for "hg summary"
5899 ui.write(_('update: %d new changesets (update)\n') % new)
5929 ui.write(_('update: %d new changesets (update)\n') % new)
5900 else:
5930 else:
5901 # i18n: column positioning for "hg summary"
5931 # i18n: column positioning for "hg summary"
5902 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5932 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5903 (new, len(bheads)))
5933 (new, len(bheads)))
5904
5934
5905 cmdutil.summaryhooks(ui, repo)
5935 cmdutil.summaryhooks(ui, repo)
5906
5936
5907 if opts.get('remote'):
5937 if opts.get('remote'):
5908 needsincoming, needsoutgoing = True, True
5938 needsincoming, needsoutgoing = True, True
5909 else:
5939 else:
5910 needsincoming, needsoutgoing = False, False
5940 needsincoming, needsoutgoing = False, False
5911 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
5941 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
5912 if i:
5942 if i:
5913 needsincoming = True
5943 needsincoming = True
5914 if o:
5944 if o:
5915 needsoutgoing = True
5945 needsoutgoing = True
5916 if not needsincoming and not needsoutgoing:
5946 if not needsincoming and not needsoutgoing:
5917 return
5947 return
5918
5948
5919 def getincoming():
5949 def getincoming():
5920 source, branches = hg.parseurl(ui.expandpath('default'))
5950 source, branches = hg.parseurl(ui.expandpath('default'))
5921 sbranch = branches[0]
5951 sbranch = branches[0]
5922 try:
5952 try:
5923 other = hg.peer(repo, {}, source)
5953 other = hg.peer(repo, {}, source)
5924 except error.RepoError:
5954 except error.RepoError:
5925 if opts.get('remote'):
5955 if opts.get('remote'):
5926 raise
5956 raise
5927 return source, sbranch, None, None, None
5957 return source, sbranch, None, None, None
5928 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5958 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5929 if revs:
5959 if revs:
5930 revs = [other.lookup(rev) for rev in revs]
5960 revs = [other.lookup(rev) for rev in revs]
5931 ui.debug('comparing with %s\n' % util.hidepassword(source))
5961 ui.debug('comparing with %s\n' % util.hidepassword(source))
5932 repo.ui.pushbuffer()
5962 repo.ui.pushbuffer()
5933 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5963 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5934 repo.ui.popbuffer()
5964 repo.ui.popbuffer()
5935 return source, sbranch, other, commoninc, commoninc[1]
5965 return source, sbranch, other, commoninc, commoninc[1]
5936
5966
5937 if needsincoming:
5967 if needsincoming:
5938 source, sbranch, sother, commoninc, incoming = getincoming()
5968 source, sbranch, sother, commoninc, incoming = getincoming()
5939 else:
5969 else:
5940 source = sbranch = sother = commoninc = incoming = None
5970 source = sbranch = sother = commoninc = incoming = None
5941
5971
5942 def getoutgoing():
5972 def getoutgoing():
5943 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5973 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5944 dbranch = branches[0]
5974 dbranch = branches[0]
5945 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5975 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5946 if source != dest:
5976 if source != dest:
5947 try:
5977 try:
5948 dother = hg.peer(repo, {}, dest)
5978 dother = hg.peer(repo, {}, dest)
5949 except error.RepoError:
5979 except error.RepoError:
5950 if opts.get('remote'):
5980 if opts.get('remote'):
5951 raise
5981 raise
5952 return dest, dbranch, None, None
5982 return dest, dbranch, None, None
5953 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5983 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5954 elif sother is None:
5984 elif sother is None:
5955 # there is no explicit destination peer, but source one is invalid
5985 # there is no explicit destination peer, but source one is invalid
5956 return dest, dbranch, None, None
5986 return dest, dbranch, None, None
5957 else:
5987 else:
5958 dother = sother
5988 dother = sother
5959 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5989 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5960 common = None
5990 common = None
5961 else:
5991 else:
5962 common = commoninc
5992 common = commoninc
5963 if revs:
5993 if revs:
5964 revs = [repo.lookup(rev) for rev in revs]
5994 revs = [repo.lookup(rev) for rev in revs]
5965 repo.ui.pushbuffer()
5995 repo.ui.pushbuffer()
5966 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5996 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5967 commoninc=common)
5997 commoninc=common)
5968 repo.ui.popbuffer()
5998 repo.ui.popbuffer()
5969 return dest, dbranch, dother, outgoing
5999 return dest, dbranch, dother, outgoing
5970
6000
5971 if needsoutgoing:
6001 if needsoutgoing:
5972 dest, dbranch, dother, outgoing = getoutgoing()
6002 dest, dbranch, dother, outgoing = getoutgoing()
5973 else:
6003 else:
5974 dest = dbranch = dother = outgoing = None
6004 dest = dbranch = dother = outgoing = None
5975
6005
5976 if opts.get('remote'):
6006 if opts.get('remote'):
5977 t = []
6007 t = []
5978 if incoming:
6008 if incoming:
5979 t.append(_('1 or more incoming'))
6009 t.append(_('1 or more incoming'))
5980 o = outgoing.missing
6010 o = outgoing.missing
5981 if o:
6011 if o:
5982 t.append(_('%d outgoing') % len(o))
6012 t.append(_('%d outgoing') % len(o))
5983 other = dother or sother
6013 other = dother or sother
5984 if 'bookmarks' in other.listkeys('namespaces'):
6014 if 'bookmarks' in other.listkeys('namespaces'):
5985 counts = bookmarks.summary(repo, other)
6015 counts = bookmarks.summary(repo, other)
5986 if counts[0] > 0:
6016 if counts[0] > 0:
5987 t.append(_('%d incoming bookmarks') % counts[0])
6017 t.append(_('%d incoming bookmarks') % counts[0])
5988 if counts[1] > 0:
6018 if counts[1] > 0:
5989 t.append(_('%d outgoing bookmarks') % counts[1])
6019 t.append(_('%d outgoing bookmarks') % counts[1])
5990
6020
5991 if t:
6021 if t:
5992 # i18n: column positioning for "hg summary"
6022 # i18n: column positioning for "hg summary"
5993 ui.write(_('remote: %s\n') % (', '.join(t)))
6023 ui.write(_('remote: %s\n') % (', '.join(t)))
5994 else:
6024 else:
5995 # i18n: column positioning for "hg summary"
6025 # i18n: column positioning for "hg summary"
5996 ui.status(_('remote: (synced)\n'))
6026 ui.status(_('remote: (synced)\n'))
5997
6027
5998 cmdutil.summaryremotehooks(ui, repo, opts,
6028 cmdutil.summaryremotehooks(ui, repo, opts,
5999 ((source, sbranch, sother, commoninc),
6029 ((source, sbranch, sother, commoninc),
6000 (dest, dbranch, dother, outgoing)))
6030 (dest, dbranch, dother, outgoing)))
6001
6031
6002 @command('tag',
6032 @command('tag',
6003 [('f', 'force', None, _('force tag')),
6033 [('f', 'force', None, _('force tag')),
6004 ('l', 'local', None, _('make the tag local')),
6034 ('l', 'local', None, _('make the tag local')),
6005 ('r', 'rev', '', _('revision to tag'), _('REV')),
6035 ('r', 'rev', '', _('revision to tag'), _('REV')),
6006 ('', 'remove', None, _('remove a tag')),
6036 ('', 'remove', None, _('remove a tag')),
6007 # -l/--local is already there, commitopts cannot be used
6037 # -l/--local is already there, commitopts cannot be used
6008 ('e', 'edit', None, _('invoke editor on commit messages')),
6038 ('e', 'edit', None, _('invoke editor on commit messages')),
6009 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
6039 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
6010 ] + commitopts2,
6040 ] + commitopts2,
6011 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
6041 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
6012 def tag(ui, repo, name1, *names, **opts):
6042 def tag(ui, repo, name1, *names, **opts):
6013 """add one or more tags for the current or given revision
6043 """add one or more tags for the current or given revision
6014
6044
6015 Name a particular revision using <name>.
6045 Name a particular revision using <name>.
6016
6046
6017 Tags are used to name particular revisions of the repository and are
6047 Tags are used to name particular revisions of the repository and are
6018 very useful to compare different revisions, to go back to significant
6048 very useful to compare different revisions, to go back to significant
6019 earlier versions or to mark branch points as releases, etc. Changing
6049 earlier versions or to mark branch points as releases, etc. Changing
6020 an existing tag is normally disallowed; use -f/--force to override.
6050 an existing tag is normally disallowed; use -f/--force to override.
6021
6051
6022 If no revision is given, the parent of the working directory is
6052 If no revision is given, the parent of the working directory is
6023 used.
6053 used.
6024
6054
6025 To facilitate version control, distribution, and merging of tags,
6055 To facilitate version control, distribution, and merging of tags,
6026 they are stored as a file named ".hgtags" which is managed similarly
6056 they are stored as a file named ".hgtags" which is managed similarly
6027 to other project files and can be hand-edited if necessary. This
6057 to other project files and can be hand-edited if necessary. This
6028 also means that tagging creates a new commit. The file
6058 also means that tagging creates a new commit. The file
6029 ".hg/localtags" is used for local tags (not shared among
6059 ".hg/localtags" is used for local tags (not shared among
6030 repositories).
6060 repositories).
6031
6061
6032 Tag commits are usually made at the head of a branch. If the parent
6062 Tag commits are usually made at the head of a branch. If the parent
6033 of the working directory is not a branch head, :hg:`tag` aborts; use
6063 of the working directory is not a branch head, :hg:`tag` aborts; use
6034 -f/--force to force the tag commit to be based on a non-head
6064 -f/--force to force the tag commit to be based on a non-head
6035 changeset.
6065 changeset.
6036
6066
6037 See :hg:`help dates` for a list of formats valid for -d/--date.
6067 See :hg:`help dates` for a list of formats valid for -d/--date.
6038
6068
6039 Since tag names have priority over branch names during revision
6069 Since tag names have priority over branch names during revision
6040 lookup, using an existing branch name as a tag name is discouraged.
6070 lookup, using an existing branch name as a tag name is discouraged.
6041
6071
6042 Returns 0 on success.
6072 Returns 0 on success.
6043 """
6073 """
6044 wlock = lock = None
6074 wlock = lock = None
6045 try:
6075 try:
6046 wlock = repo.wlock()
6076 wlock = repo.wlock()
6047 lock = repo.lock()
6077 lock = repo.lock()
6048 rev_ = "."
6078 rev_ = "."
6049 names = [t.strip() for t in (name1,) + names]
6079 names = [t.strip() for t in (name1,) + names]
6050 if len(names) != len(set(names)):
6080 if len(names) != len(set(names)):
6051 raise util.Abort(_('tag names must be unique'))
6081 raise util.Abort(_('tag names must be unique'))
6052 for n in names:
6082 for n in names:
6053 scmutil.checknewlabel(repo, n, 'tag')
6083 scmutil.checknewlabel(repo, n, 'tag')
6054 if not n:
6084 if not n:
6055 raise util.Abort(_('tag names cannot consist entirely of '
6085 raise util.Abort(_('tag names cannot consist entirely of '
6056 'whitespace'))
6086 'whitespace'))
6057 if opts.get('rev') and opts.get('remove'):
6087 if opts.get('rev') and opts.get('remove'):
6058 raise util.Abort(_("--rev and --remove are incompatible"))
6088 raise util.Abort(_("--rev and --remove are incompatible"))
6059 if opts.get('rev'):
6089 if opts.get('rev'):
6060 rev_ = opts['rev']
6090 rev_ = opts['rev']
6061 message = opts.get('message')
6091 message = opts.get('message')
6062 if opts.get('remove'):
6092 if opts.get('remove'):
6063 if opts.get('local'):
6093 if opts.get('local'):
6064 expectedtype = 'local'
6094 expectedtype = 'local'
6065 else:
6095 else:
6066 expectedtype = 'global'
6096 expectedtype = 'global'
6067
6097
6068 for n in names:
6098 for n in names:
6069 if not repo.tagtype(n):
6099 if not repo.tagtype(n):
6070 raise util.Abort(_("tag '%s' does not exist") % n)
6100 raise util.Abort(_("tag '%s' does not exist") % n)
6071 if repo.tagtype(n) != expectedtype:
6101 if repo.tagtype(n) != expectedtype:
6072 if expectedtype == 'global':
6102 if expectedtype == 'global':
6073 raise util.Abort(_("tag '%s' is not a global tag") % n)
6103 raise util.Abort(_("tag '%s' is not a global tag") % n)
6074 else:
6104 else:
6075 raise util.Abort(_("tag '%s' is not a local tag") % n)
6105 raise util.Abort(_("tag '%s' is not a local tag") % n)
6076 rev_ = nullid
6106 rev_ = nullid
6077 if not message:
6107 if not message:
6078 # we don't translate commit messages
6108 # we don't translate commit messages
6079 message = 'Removed tag %s' % ', '.join(names)
6109 message = 'Removed tag %s' % ', '.join(names)
6080 elif not opts.get('force'):
6110 elif not opts.get('force'):
6081 for n in names:
6111 for n in names:
6082 if n in repo.tags():
6112 if n in repo.tags():
6083 raise util.Abort(_("tag '%s' already exists "
6113 raise util.Abort(_("tag '%s' already exists "
6084 "(use -f to force)") % n)
6114 "(use -f to force)") % n)
6085 if not opts.get('local'):
6115 if not opts.get('local'):
6086 p1, p2 = repo.dirstate.parents()
6116 p1, p2 = repo.dirstate.parents()
6087 if p2 != nullid:
6117 if p2 != nullid:
6088 raise util.Abort(_('uncommitted merge'))
6118 raise util.Abort(_('uncommitted merge'))
6089 bheads = repo.branchheads()
6119 bheads = repo.branchheads()
6090 if not opts.get('force') and bheads and p1 not in bheads:
6120 if not opts.get('force') and bheads and p1 not in bheads:
6091 raise util.Abort(_('not at a branch head (use -f to force)'))
6121 raise util.Abort(_('not at a branch head (use -f to force)'))
6092 r = scmutil.revsingle(repo, rev_).node()
6122 r = scmutil.revsingle(repo, rev_).node()
6093
6123
6094 if not message:
6124 if not message:
6095 # we don't translate commit messages
6125 # we don't translate commit messages
6096 message = ('Added tag %s for changeset %s' %
6126 message = ('Added tag %s for changeset %s' %
6097 (', '.join(names), short(r)))
6127 (', '.join(names), short(r)))
6098
6128
6099 date = opts.get('date')
6129 date = opts.get('date')
6100 if date:
6130 if date:
6101 date = util.parsedate(date)
6131 date = util.parsedate(date)
6102
6132
6103 if opts.get('remove'):
6133 if opts.get('remove'):
6104 editform = 'tag.remove'
6134 editform = 'tag.remove'
6105 else:
6135 else:
6106 editform = 'tag.add'
6136 editform = 'tag.add'
6107 editor = cmdutil.getcommiteditor(editform=editform, **opts)
6137 editor = cmdutil.getcommiteditor(editform=editform, **opts)
6108
6138
6109 # don't allow tagging the null rev
6139 # don't allow tagging the null rev
6110 if (not opts.get('remove') and
6140 if (not opts.get('remove') and
6111 scmutil.revsingle(repo, rev_).rev() == nullrev):
6141 scmutil.revsingle(repo, rev_).rev() == nullrev):
6112 raise util.Abort(_("cannot tag null revision"))
6142 raise util.Abort(_("cannot tag null revision"))
6113
6143
6114 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
6144 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
6115 editor=editor)
6145 editor=editor)
6116 finally:
6146 finally:
6117 release(lock, wlock)
6147 release(lock, wlock)
6118
6148
6119 @command('tags', formatteropts, '')
6149 @command('tags', formatteropts, '')
6120 def tags(ui, repo, **opts):
6150 def tags(ui, repo, **opts):
6121 """list repository tags
6151 """list repository tags
6122
6152
6123 This lists both regular and local tags. When the -v/--verbose
6153 This lists both regular and local tags. When the -v/--verbose
6124 switch is used, a third column "local" is printed for local tags.
6154 switch is used, a third column "local" is printed for local tags.
6125
6155
6126 Returns 0 on success.
6156 Returns 0 on success.
6127 """
6157 """
6128
6158
6129 fm = ui.formatter('tags', opts)
6159 fm = ui.formatter('tags', opts)
6130 hexfunc = fm.hexfunc
6160 hexfunc = fm.hexfunc
6131 tagtype = ""
6161 tagtype = ""
6132
6162
6133 for t, n in reversed(repo.tagslist()):
6163 for t, n in reversed(repo.tagslist()):
6134 hn = hexfunc(n)
6164 hn = hexfunc(n)
6135 label = 'tags.normal'
6165 label = 'tags.normal'
6136 tagtype = ''
6166 tagtype = ''
6137 if repo.tagtype(t) == 'local':
6167 if repo.tagtype(t) == 'local':
6138 label = 'tags.local'
6168 label = 'tags.local'
6139 tagtype = 'local'
6169 tagtype = 'local'
6140
6170
6141 fm.startitem()
6171 fm.startitem()
6142 fm.write('tag', '%s', t, label=label)
6172 fm.write('tag', '%s', t, label=label)
6143 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6173 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6144 fm.condwrite(not ui.quiet, 'rev node', fmt,
6174 fm.condwrite(not ui.quiet, 'rev node', fmt,
6145 repo.changelog.rev(n), hn, label=label)
6175 repo.changelog.rev(n), hn, label=label)
6146 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6176 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6147 tagtype, label=label)
6177 tagtype, label=label)
6148 fm.plain('\n')
6178 fm.plain('\n')
6149 fm.end()
6179 fm.end()
6150
6180
6151 @command('tip',
6181 @command('tip',
6152 [('p', 'patch', None, _('show patch')),
6182 [('p', 'patch', None, _('show patch')),
6153 ('g', 'git', None, _('use git extended diff format')),
6183 ('g', 'git', None, _('use git extended diff format')),
6154 ] + templateopts,
6184 ] + templateopts,
6155 _('[-p] [-g]'))
6185 _('[-p] [-g]'))
6156 def tip(ui, repo, **opts):
6186 def tip(ui, repo, **opts):
6157 """show the tip revision (DEPRECATED)
6187 """show the tip revision (DEPRECATED)
6158
6188
6159 The tip revision (usually just called the tip) is the changeset
6189 The tip revision (usually just called the tip) is the changeset
6160 most recently added to the repository (and therefore the most
6190 most recently added to the repository (and therefore the most
6161 recently changed head).
6191 recently changed head).
6162
6192
6163 If you have just made a commit, that commit will be the tip. If
6193 If you have just made a commit, that commit will be the tip. If
6164 you have just pulled changes from another repository, the tip of
6194 you have just pulled changes from another repository, the tip of
6165 that repository becomes the current tip. The "tip" tag is special
6195 that repository becomes the current tip. The "tip" tag is special
6166 and cannot be renamed or assigned to a different changeset.
6196 and cannot be renamed or assigned to a different changeset.
6167
6197
6168 This command is deprecated, please use :hg:`heads` instead.
6198 This command is deprecated, please use :hg:`heads` instead.
6169
6199
6170 Returns 0 on success.
6200 Returns 0 on success.
6171 """
6201 """
6172 displayer = cmdutil.show_changeset(ui, repo, opts)
6202 displayer = cmdutil.show_changeset(ui, repo, opts)
6173 displayer.show(repo['tip'])
6203 displayer.show(repo['tip'])
6174 displayer.close()
6204 displayer.close()
6175
6205
6176 @command('unbundle',
6206 @command('unbundle',
6177 [('u', 'update', None,
6207 [('u', 'update', None,
6178 _('update to new branch head if changesets were unbundled'))],
6208 _('update to new branch head if changesets were unbundled'))],
6179 _('[-u] FILE...'))
6209 _('[-u] FILE...'))
6180 def unbundle(ui, repo, fname1, *fnames, **opts):
6210 def unbundle(ui, repo, fname1, *fnames, **opts):
6181 """apply one or more changegroup files
6211 """apply one or more changegroup files
6182
6212
6183 Apply one or more compressed changegroup files generated by the
6213 Apply one or more compressed changegroup files generated by the
6184 bundle command.
6214 bundle command.
6185
6215
6186 Returns 0 on success, 1 if an update has unresolved files.
6216 Returns 0 on success, 1 if an update has unresolved files.
6187 """
6217 """
6188 fnames = (fname1,) + fnames
6218 fnames = (fname1,) + fnames
6189
6219
6190 lock = repo.lock()
6220 lock = repo.lock()
6191 try:
6221 try:
6192 for fname in fnames:
6222 for fname in fnames:
6193 f = hg.openpath(ui, fname)
6223 f = hg.openpath(ui, fname)
6194 gen = exchange.readbundle(ui, f, fname)
6224 gen = exchange.readbundle(ui, f, fname)
6195 if isinstance(gen, bundle2.unbundle20):
6225 if isinstance(gen, bundle2.unbundle20):
6196 tr = repo.transaction('unbundle')
6226 tr = repo.transaction('unbundle')
6197 try:
6227 try:
6198 op = bundle2.processbundle(repo, gen, lambda: tr)
6228 op = bundle2.processbundle(repo, gen, lambda: tr)
6199 tr.close()
6229 tr.close()
6200 finally:
6230 finally:
6201 if tr:
6231 if tr:
6202 tr.release()
6232 tr.release()
6203 changes = [r.get('result', 0)
6233 changes = [r.get('result', 0)
6204 for r in op.records['changegroup']]
6234 for r in op.records['changegroup']]
6205 modheads = changegroup.combineresults(changes)
6235 modheads = changegroup.combineresults(changes)
6206 else:
6236 else:
6207 modheads = changegroup.addchangegroup(repo, gen, 'unbundle',
6237 modheads = changegroup.addchangegroup(repo, gen, 'unbundle',
6208 'bundle:' + fname)
6238 'bundle:' + fname)
6209 finally:
6239 finally:
6210 lock.release()
6240 lock.release()
6211
6241
6212 return postincoming(ui, repo, modheads, opts.get('update'), None)
6242 return postincoming(ui, repo, modheads, opts.get('update'), None)
6213
6243
6214 @command('^update|up|checkout|co',
6244 @command('^update|up|checkout|co',
6215 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6245 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6216 ('c', 'check', None,
6246 ('c', 'check', None,
6217 _('update across branches if no uncommitted changes')),
6247 _('update across branches if no uncommitted changes')),
6218 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6248 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6219 ('r', 'rev', '', _('revision'), _('REV'))
6249 ('r', 'rev', '', _('revision'), _('REV'))
6220 ] + mergetoolopts,
6250 ] + mergetoolopts,
6221 _('[-c] [-C] [-d DATE] [[-r] REV]'))
6251 _('[-c] [-C] [-d DATE] [[-r] REV]'))
6222 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
6252 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
6223 tool=None):
6253 tool=None):
6224 """update working directory (or switch revisions)
6254 """update working directory (or switch revisions)
6225
6255
6226 Update the repository's working directory to the specified
6256 Update the repository's working directory to the specified
6227 changeset. If no changeset is specified, update to the tip of the
6257 changeset. If no changeset is specified, update to the tip of the
6228 current named branch and move the current bookmark (see :hg:`help
6258 current named branch and move the current bookmark (see :hg:`help
6229 bookmarks`).
6259 bookmarks`).
6230
6260
6231 Update sets the working directory's parent revision to the specified
6261 Update sets the working directory's parent revision to the specified
6232 changeset (see :hg:`help parents`).
6262 changeset (see :hg:`help parents`).
6233
6263
6234 If the changeset is not a descendant or ancestor of the working
6264 If the changeset is not a descendant or ancestor of the working
6235 directory's parent, the update is aborted. With the -c/--check
6265 directory's parent, the update is aborted. With the -c/--check
6236 option, the working directory is checked for uncommitted changes; if
6266 option, the working directory is checked for uncommitted changes; if
6237 none are found, the working directory is updated to the specified
6267 none are found, the working directory is updated to the specified
6238 changeset.
6268 changeset.
6239
6269
6240 .. container:: verbose
6270 .. container:: verbose
6241
6271
6242 The following rules apply when the working directory contains
6272 The following rules apply when the working directory contains
6243 uncommitted changes:
6273 uncommitted changes:
6244
6274
6245 1. If neither -c/--check nor -C/--clean is specified, and if
6275 1. If neither -c/--check nor -C/--clean is specified, and if
6246 the requested changeset is an ancestor or descendant of
6276 the requested changeset is an ancestor or descendant of
6247 the working directory's parent, the uncommitted changes
6277 the working directory's parent, the uncommitted changes
6248 are merged into the requested changeset and the merged
6278 are merged into the requested changeset and the merged
6249 result is left uncommitted. If the requested changeset is
6279 result is left uncommitted. If the requested changeset is
6250 not an ancestor or descendant (that is, it is on another
6280 not an ancestor or descendant (that is, it is on another
6251 branch), the update is aborted and the uncommitted changes
6281 branch), the update is aborted and the uncommitted changes
6252 are preserved.
6282 are preserved.
6253
6283
6254 2. With the -c/--check option, the update is aborted and the
6284 2. With the -c/--check option, the update is aborted and the
6255 uncommitted changes are preserved.
6285 uncommitted changes are preserved.
6256
6286
6257 3. With the -C/--clean option, uncommitted changes are discarded and
6287 3. With the -C/--clean option, uncommitted changes are discarded and
6258 the working directory is updated to the requested changeset.
6288 the working directory is updated to the requested changeset.
6259
6289
6260 To cancel an uncommitted merge (and lose your changes), use
6290 To cancel an uncommitted merge (and lose your changes), use
6261 :hg:`update --clean .`.
6291 :hg:`update --clean .`.
6262
6292
6263 Use null as the changeset to remove the working directory (like
6293 Use null as the changeset to remove the working directory (like
6264 :hg:`clone -U`).
6294 :hg:`clone -U`).
6265
6295
6266 If you want to revert just one file to an older revision, use
6296 If you want to revert just one file to an older revision, use
6267 :hg:`revert [-r REV] NAME`.
6297 :hg:`revert [-r REV] NAME`.
6268
6298
6269 See :hg:`help dates` for a list of formats valid for -d/--date.
6299 See :hg:`help dates` for a list of formats valid for -d/--date.
6270
6300
6271 Returns 0 on success, 1 if there are unresolved files.
6301 Returns 0 on success, 1 if there are unresolved files.
6272 """
6302 """
6273 if rev and node:
6303 if rev and node:
6274 raise util.Abort(_("please specify just one revision"))
6304 raise util.Abort(_("please specify just one revision"))
6275
6305
6276 if rev is None or rev == '':
6306 if rev is None or rev == '':
6277 rev = node
6307 rev = node
6278
6308
6279 cmdutil.clearunfinished(repo)
6309 cmdutil.clearunfinished(repo)
6280
6310
6281 # with no argument, we also move the current bookmark, if any
6311 # with no argument, we also move the current bookmark, if any
6282 rev, movemarkfrom = bookmarks.calculateupdate(ui, repo, rev)
6312 rev, movemarkfrom = bookmarks.calculateupdate(ui, repo, rev)
6283
6313
6284 # if we defined a bookmark, we have to remember the original bookmark name
6314 # if we defined a bookmark, we have to remember the original bookmark name
6285 brev = rev
6315 brev = rev
6286 rev = scmutil.revsingle(repo, rev, rev).rev()
6316 rev = scmutil.revsingle(repo, rev, rev).rev()
6287
6317
6288 if check and clean:
6318 if check and clean:
6289 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
6319 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
6290
6320
6291 if date:
6321 if date:
6292 if rev is not None:
6322 if rev is not None:
6293 raise util.Abort(_("you can't specify a revision and a date"))
6323 raise util.Abort(_("you can't specify a revision and a date"))
6294 rev = cmdutil.finddate(ui, repo, date)
6324 rev = cmdutil.finddate(ui, repo, date)
6295
6325
6296 if check:
6326 if check:
6297 c = repo[None]
6327 c = repo[None]
6298 if c.dirty(merge=False, branch=False, missing=True):
6328 if c.dirty(merge=False, branch=False, missing=True):
6299 raise util.Abort(_("uncommitted changes"))
6329 raise util.Abort(_("uncommitted changes"))
6300 if rev is None:
6330 if rev is None:
6301 rev = repo[repo[None].branch()].rev()
6331 rev = repo[repo[None].branch()].rev()
6302
6332
6303 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
6333 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
6304
6334
6305 if clean:
6335 if clean:
6306 ret = hg.clean(repo, rev)
6336 ret = hg.clean(repo, rev)
6307 else:
6337 else:
6308 ret = hg.update(repo, rev)
6338 ret = hg.update(repo, rev)
6309
6339
6310 if not ret and movemarkfrom:
6340 if not ret and movemarkfrom:
6311 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
6341 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
6312 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
6342 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
6313 elif brev in repo._bookmarks:
6343 elif brev in repo._bookmarks:
6314 bookmarks.setcurrent(repo, brev)
6344 bookmarks.setcurrent(repo, brev)
6315 ui.status(_("(activating bookmark %s)\n") % brev)
6345 ui.status(_("(activating bookmark %s)\n") % brev)
6316 elif brev:
6346 elif brev:
6317 if repo._bookmarkcurrent:
6347 if repo._bookmarkcurrent:
6318 ui.status(_("(leaving bookmark %s)\n") %
6348 ui.status(_("(leaving bookmark %s)\n") %
6319 repo._bookmarkcurrent)
6349 repo._bookmarkcurrent)
6320 bookmarks.unsetcurrent(repo)
6350 bookmarks.unsetcurrent(repo)
6321
6351
6322 return ret
6352 return ret
6323
6353
6324 @command('verify', [])
6354 @command('verify', [])
6325 def verify(ui, repo):
6355 def verify(ui, repo):
6326 """verify the integrity of the repository
6356 """verify the integrity of the repository
6327
6357
6328 Verify the integrity of the current repository.
6358 Verify the integrity of the current repository.
6329
6359
6330 This will perform an extensive check of the repository's
6360 This will perform an extensive check of the repository's
6331 integrity, validating the hashes and checksums of each entry in
6361 integrity, validating the hashes and checksums of each entry in
6332 the changelog, manifest, and tracked files, as well as the
6362 the changelog, manifest, and tracked files, as well as the
6333 integrity of their crosslinks and indices.
6363 integrity of their crosslinks and indices.
6334
6364
6335 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption
6365 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption
6336 for more information about recovery from corruption of the
6366 for more information about recovery from corruption of the
6337 repository.
6367 repository.
6338
6368
6339 Returns 0 on success, 1 if errors are encountered.
6369 Returns 0 on success, 1 if errors are encountered.
6340 """
6370 """
6341 return hg.verify(repo)
6371 return hg.verify(repo)
6342
6372
6343 @command('version', [], norepo=True)
6373 @command('version', [], norepo=True)
6344 def version_(ui):
6374 def version_(ui):
6345 """output version and copyright information"""
6375 """output version and copyright information"""
6346 ui.write(_("Mercurial Distributed SCM (version %s)\n")
6376 ui.write(_("Mercurial Distributed SCM (version %s)\n")
6347 % util.version())
6377 % util.version())
6348 ui.status(_(
6378 ui.status(_(
6349 "(see http://mercurial.selenic.com for more information)\n"
6379 "(see http://mercurial.selenic.com for more information)\n"
6350 "\nCopyright (C) 2005-2015 Matt Mackall and others\n"
6380 "\nCopyright (C) 2005-2015 Matt Mackall and others\n"
6351 "This is free software; see the source for copying conditions. "
6381 "This is free software; see the source for copying conditions. "
6352 "There is NO\nwarranty; "
6382 "There is NO\nwarranty; "
6353 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6383 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6354 ))
6384 ))
6355
6385
6356 ui.note(_("\nEnabled extensions:\n\n"))
6386 ui.note(_("\nEnabled extensions:\n\n"))
6357 if ui.verbose:
6387 if ui.verbose:
6358 # format names and versions into columns
6388 # format names and versions into columns
6359 names = []
6389 names = []
6360 vers = []
6390 vers = []
6361 for name, module in extensions.extensions():
6391 for name, module in extensions.extensions():
6362 names.append(name)
6392 names.append(name)
6363 vers.append(extensions.moduleversion(module))
6393 vers.append(extensions.moduleversion(module))
6364 if names:
6394 if names:
6365 maxnamelen = max(len(n) for n in names)
6395 maxnamelen = max(len(n) for n in names)
6366 for i, name in enumerate(names):
6396 for i, name in enumerate(names):
6367 ui.write(" %-*s %s\n" % (maxnamelen, name, vers[i]))
6397 ui.write(" %-*s %s\n" % (maxnamelen, name, vers[i]))
@@ -1,519 +1,589 b''
1 $ HGMERGE=true; export HGMERGE
1 $ HGMERGE=true; export HGMERGE
2
2
3 init
3 init
4
4
5 $ hg init repo
5 $ hg init repo
6 $ cd repo
6 $ cd repo
7
7
8 commit
8 commit
9
9
10 $ echo 'a' > a
10 $ echo 'a' > a
11 $ hg ci -A -m test -u nobody -d '1 0'
11 $ hg ci -A -m test -u nobody -d '1 0'
12 adding a
12 adding a
13
13
14 annotate -c
14 annotate -c
15
15
16 $ hg annotate -c a
16 $ hg annotate -c a
17 8435f90966e4: a
17 8435f90966e4: a
18
18
19 annotate -cl
19 annotate -cl
20
20
21 $ hg annotate -cl a
21 $ hg annotate -cl a
22 8435f90966e4:1: a
22 8435f90966e4:1: a
23
23
24 annotate -d
24 annotate -d
25
25
26 $ hg annotate -d a
26 $ hg annotate -d a
27 Thu Jan 01 00:00:01 1970 +0000: a
27 Thu Jan 01 00:00:01 1970 +0000: a
28
28
29 annotate -n
29 annotate -n
30
30
31 $ hg annotate -n a
31 $ hg annotate -n a
32 0: a
32 0: a
33
33
34 annotate -nl
34 annotate -nl
35
35
36 $ hg annotate -nl a
36 $ hg annotate -nl a
37 0:1: a
37 0:1: a
38
38
39 annotate -u
39 annotate -u
40
40
41 $ hg annotate -u a
41 $ hg annotate -u a
42 nobody: a
42 nobody: a
43
43
44 annotate -cdnu
44 annotate -cdnu
45
45
46 $ hg annotate -cdnu a
46 $ hg annotate -cdnu a
47 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000: a
47 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000: a
48
48
49 annotate -cdnul
49 annotate -cdnul
50
50
51 $ hg annotate -cdnul a
51 $ hg annotate -cdnul a
52 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000:1: a
52 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000:1: a
53
53
54 annotate (JSON)
54 annotate (JSON)
55
55
56 $ hg annotate -Tjson a
56 $ hg annotate -Tjson a
57 [
57 [
58 {
58 {
59 "line": "a\n",
59 "line": "a\n",
60 "rev": 0
60 "rev": 0
61 }
61 }
62 ]
62 ]
63
63
64 $ hg annotate -Tjson -cdfnul a
64 $ hg annotate -Tjson -cdfnul a
65 [
65 [
66 {
66 {
67 "date": [1.0, 0],
67 "date": [1.0, 0],
68 "file": "a",
68 "file": "a",
69 "line": "a\n",
69 "line": "a\n",
70 "line_number": 1,
70 "line_number": 1,
71 "node": "8435f90966e442695d2ded29fdade2bac5ad8065",
71 "node": "8435f90966e442695d2ded29fdade2bac5ad8065",
72 "rev": 0,
72 "rev": 0,
73 "user": "nobody"
73 "user": "nobody"
74 }
74 }
75 ]
75 ]
76
76
77 $ cat <<EOF >>a
77 $ cat <<EOF >>a
78 > a
78 > a
79 > a
79 > a
80 > EOF
80 > EOF
81 $ hg ci -ma1 -d '1 0'
81 $ hg ci -ma1 -d '1 0'
82 $ hg cp a b
82 $ hg cp a b
83 $ hg ci -mb -d '1 0'
83 $ hg ci -mb -d '1 0'
84 $ cat <<EOF >> b
84 $ cat <<EOF >> b
85 > b4
85 > b4
86 > b5
86 > b5
87 > b6
87 > b6
88 > EOF
88 > EOF
89 $ hg ci -mb2 -d '2 0'
89 $ hg ci -mb2 -d '2 0'
90
90
91 annotate -n b
91 annotate -n b
92
92
93 $ hg annotate -n b
93 $ hg annotate -n b
94 0: a
94 0: a
95 1: a
95 1: a
96 1: a
96 1: a
97 3: b4
97 3: b4
98 3: b5
98 3: b5
99 3: b6
99 3: b6
100
100
101 annotate --no-follow b
101 annotate --no-follow b
102
102
103 $ hg annotate --no-follow b
103 $ hg annotate --no-follow b
104 2: a
104 2: a
105 2: a
105 2: a
106 2: a
106 2: a
107 3: b4
107 3: b4
108 3: b5
108 3: b5
109 3: b6
109 3: b6
110
110
111 annotate -nl b
111 annotate -nl b
112
112
113 $ hg annotate -nl b
113 $ hg annotate -nl b
114 0:1: a
114 0:1: a
115 1:2: a
115 1:2: a
116 1:3: a
116 1:3: a
117 3:4: b4
117 3:4: b4
118 3:5: b5
118 3:5: b5
119 3:6: b6
119 3:6: b6
120
120
121 annotate -nf b
121 annotate -nf b
122
122
123 $ hg annotate -nf b
123 $ hg annotate -nf b
124 0 a: a
124 0 a: a
125 1 a: a
125 1 a: a
126 1 a: a
126 1 a: a
127 3 b: b4
127 3 b: b4
128 3 b: b5
128 3 b: b5
129 3 b: b6
129 3 b: b6
130
130
131 annotate -nlf b
131 annotate -nlf b
132
132
133 $ hg annotate -nlf b
133 $ hg annotate -nlf b
134 0 a:1: a
134 0 a:1: a
135 1 a:2: a
135 1 a:2: a
136 1 a:3: a
136 1 a:3: a
137 3 b:4: b4
137 3 b:4: b4
138 3 b:5: b5
138 3 b:5: b5
139 3 b:6: b6
139 3 b:6: b6
140
140
141 $ hg up -C 2
141 $ hg up -C 2
142 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
143 $ cat <<EOF >> b
143 $ cat <<EOF >> b
144 > b4
144 > b4
145 > c
145 > c
146 > b5
146 > b5
147 > EOF
147 > EOF
148 $ hg ci -mb2.1 -d '2 0'
148 $ hg ci -mb2.1 -d '2 0'
149 created new head
149 created new head
150 $ hg merge
150 $ hg merge
151 merging b
151 merging b
152 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
152 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
153 (branch merge, don't forget to commit)
153 (branch merge, don't forget to commit)
154 $ hg ci -mmergeb -d '3 0'
154 $ hg ci -mmergeb -d '3 0'
155
155
156 annotate after merge
156 annotate after merge
157
157
158 $ hg annotate -nf b
158 $ hg annotate -nf b
159 0 a: a
159 0 a: a
160 1 a: a
160 1 a: a
161 1 a: a
161 1 a: a
162 3 b: b4
162 3 b: b4
163 4 b: c
163 4 b: c
164 3 b: b5
164 3 b: b5
165
165
166 annotate after merge with -l
166 annotate after merge with -l
167
167
168 $ hg annotate -nlf b
168 $ hg annotate -nlf b
169 0 a:1: a
169 0 a:1: a
170 1 a:2: a
170 1 a:2: a
171 1 a:3: a
171 1 a:3: a
172 3 b:4: b4
172 3 b:4: b4
173 4 b:5: c
173 4 b:5: c
174 3 b:5: b5
174 3 b:5: b5
175
175
176 $ hg up -C 1
176 $ hg up -C 1
177 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
177 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
178 $ hg cp a b
178 $ hg cp a b
179 $ cat <<EOF > b
179 $ cat <<EOF > b
180 > a
180 > a
181 > z
181 > z
182 > a
182 > a
183 > EOF
183 > EOF
184 $ hg ci -mc -d '3 0'
184 $ hg ci -mc -d '3 0'
185 created new head
185 created new head
186 $ hg merge
186 $ hg merge
187 merging b
187 merging b
188 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
188 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
189 (branch merge, don't forget to commit)
189 (branch merge, don't forget to commit)
190 $ cat <<EOF >> b
190 $ cat <<EOF >> b
191 > b4
191 > b4
192 > c
192 > c
193 > b5
193 > b5
194 > EOF
194 > EOF
195 $ echo d >> b
195 $ echo d >> b
196 $ hg ci -mmerge2 -d '4 0'
196 $ hg ci -mmerge2 -d '4 0'
197
197
198 annotate after rename merge
198 annotate after rename merge
199
199
200 $ hg annotate -nf b
200 $ hg annotate -nf b
201 0 a: a
201 0 a: a
202 6 b: z
202 6 b: z
203 1 a: a
203 1 a: a
204 3 b: b4
204 3 b: b4
205 4 b: c
205 4 b: c
206 3 b: b5
206 3 b: b5
207 7 b: d
207 7 b: d
208
208
209 annotate after rename merge with -l
209 annotate after rename merge with -l
210
210
211 $ hg annotate -nlf b
211 $ hg annotate -nlf b
212 0 a:1: a
212 0 a:1: a
213 6 b:2: z
213 6 b:2: z
214 1 a:3: a
214 1 a:3: a
215 3 b:4: b4
215 3 b:4: b4
216 4 b:5: c
216 4 b:5: c
217 3 b:5: b5
217 3 b:5: b5
218 7 b:7: d
218 7 b:7: d
219
219
220 Issue2807: alignment of line numbers with -l
220 Issue2807: alignment of line numbers with -l
221
221
222 $ echo more >> b
222 $ echo more >> b
223 $ hg ci -mmore -d '5 0'
223 $ hg ci -mmore -d '5 0'
224 $ echo more >> b
224 $ echo more >> b
225 $ hg ci -mmore -d '6 0'
225 $ hg ci -mmore -d '6 0'
226 $ echo more >> b
226 $ echo more >> b
227 $ hg ci -mmore -d '7 0'
227 $ hg ci -mmore -d '7 0'
228 $ hg annotate -nlf b
228 $ hg annotate -nlf b
229 0 a: 1: a
229 0 a: 1: a
230 6 b: 2: z
230 6 b: 2: z
231 1 a: 3: a
231 1 a: 3: a
232 3 b: 4: b4
232 3 b: 4: b4
233 4 b: 5: c
233 4 b: 5: c
234 3 b: 5: b5
234 3 b: 5: b5
235 7 b: 7: d
235 7 b: 7: d
236 8 b: 8: more
236 8 b: 8: more
237 9 b: 9: more
237 9 b: 9: more
238 10 b:10: more
238 10 b:10: more
239
239
240 linkrev vs rev
240 linkrev vs rev
241
241
242 $ hg annotate -r tip -n a
242 $ hg annotate -r tip -n a
243 0: a
243 0: a
244 1: a
244 1: a
245 1: a
245 1: a
246
246
247 linkrev vs rev with -l
247 linkrev vs rev with -l
248
248
249 $ hg annotate -r tip -nl a
249 $ hg annotate -r tip -nl a
250 0:1: a
250 0:1: a
251 1:2: a
251 1:2: a
252 1:3: a
252 1:3: a
253
253
254 Issue589: "undelete" sequence leads to crash
254 Issue589: "undelete" sequence leads to crash
255
255
256 annotate was crashing when trying to --follow something
256 annotate was crashing when trying to --follow something
257
257
258 like A -> B -> A
258 like A -> B -> A
259
259
260 generate ABA rename configuration
260 generate ABA rename configuration
261
261
262 $ echo foo > foo
262 $ echo foo > foo
263 $ hg add foo
263 $ hg add foo
264 $ hg ci -m addfoo
264 $ hg ci -m addfoo
265 $ hg rename foo bar
265 $ hg rename foo bar
266 $ hg ci -m renamefoo
266 $ hg ci -m renamefoo
267 $ hg rename bar foo
267 $ hg rename bar foo
268 $ hg ci -m renamebar
268 $ hg ci -m renamebar
269
269
270 annotate after ABA with follow
270 annotate after ABA with follow
271
271
272 $ hg annotate --follow foo
272 $ hg annotate --follow foo
273 foo: foo
273 foo: foo
274
274
275 missing file
275 missing file
276
276
277 $ hg ann nosuchfile
277 $ hg ann nosuchfile
278 abort: nosuchfile: no such file in rev e9e6b4fa872f
278 abort: nosuchfile: no such file in rev e9e6b4fa872f
279 [255]
279 [255]
280
280
281 annotate file without '\n' on last line
281 annotate file without '\n' on last line
282
282
283 $ printf "" > c
283 $ printf "" > c
284 $ hg ci -A -m test -u nobody -d '1 0'
284 $ hg ci -A -m test -u nobody -d '1 0'
285 adding c
285 adding c
286 $ hg annotate c
286 $ hg annotate c
287 $ printf "a\nb" > c
287 $ printf "a\nb" > c
288 $ hg ci -m test
288 $ hg ci -m test
289 $ hg annotate c
289 $ hg annotate c
290 [0-9]+: a (re)
290 [0-9]+: a (re)
291 [0-9]+: b (re)
291 [0-9]+: b (re)
292
292
293 Issue3841: check annotation of the file of which filelog includes
293 Issue3841: check annotation of the file of which filelog includes
294 merging between the revision and its ancestor
294 merging between the revision and its ancestor
295
295
296 to reproduce the situation with recent Mercurial, this script uses (1)
296 to reproduce the situation with recent Mercurial, this script uses (1)
297 "hg debugsetparents" to merge without ancestor check by "hg merge",
297 "hg debugsetparents" to merge without ancestor check by "hg merge",
298 and (2) the extension to allow filelog merging between the revision
298 and (2) the extension to allow filelog merging between the revision
299 and its ancestor by overriding "repo._filecommit".
299 and its ancestor by overriding "repo._filecommit".
300
300
301 $ cat > ../legacyrepo.py <<EOF
301 $ cat > ../legacyrepo.py <<EOF
302 > from mercurial import node, util
302 > from mercurial import node, util
303 > def reposetup(ui, repo):
303 > def reposetup(ui, repo):
304 > class legacyrepo(repo.__class__):
304 > class legacyrepo(repo.__class__):
305 > def _filecommit(self, fctx, manifest1, manifest2,
305 > def _filecommit(self, fctx, manifest1, manifest2,
306 > linkrev, tr, changelist):
306 > linkrev, tr, changelist):
307 > fname = fctx.path()
307 > fname = fctx.path()
308 > text = fctx.data()
308 > text = fctx.data()
309 > flog = self.file(fname)
309 > flog = self.file(fname)
310 > fparent1 = manifest1.get(fname, node.nullid)
310 > fparent1 = manifest1.get(fname, node.nullid)
311 > fparent2 = manifest2.get(fname, node.nullid)
311 > fparent2 = manifest2.get(fname, node.nullid)
312 > meta = {}
312 > meta = {}
313 > copy = fctx.renamed()
313 > copy = fctx.renamed()
314 > if copy and copy[0] != fname:
314 > if copy and copy[0] != fname:
315 > raise util.Abort('copying is not supported')
315 > raise util.Abort('copying is not supported')
316 > if fparent2 != node.nullid:
316 > if fparent2 != node.nullid:
317 > changelist.append(fname)
317 > changelist.append(fname)
318 > return flog.add(text, meta, tr, linkrev,
318 > return flog.add(text, meta, tr, linkrev,
319 > fparent1, fparent2)
319 > fparent1, fparent2)
320 > raise util.Abort('only merging is supported')
320 > raise util.Abort('only merging is supported')
321 > repo.__class__ = legacyrepo
321 > repo.__class__ = legacyrepo
322 > EOF
322 > EOF
323
323
324 $ cat > baz <<EOF
324 $ cat > baz <<EOF
325 > 1
325 > 1
326 > 2
326 > 2
327 > 3
327 > 3
328 > 4
328 > 4
329 > 5
329 > 5
330 > EOF
330 > EOF
331 $ hg add baz
331 $ hg add baz
332 $ hg commit -m "baz:0"
332 $ hg commit -m "baz:0"
333
333
334 $ cat > baz <<EOF
334 $ cat > baz <<EOF
335 > 1 baz:1
335 > 1 baz:1
336 > 2
336 > 2
337 > 3
337 > 3
338 > 4
338 > 4
339 > 5
339 > 5
340 > EOF
340 > EOF
341 $ hg commit -m "baz:1"
341 $ hg commit -m "baz:1"
342
342
343 $ cat > baz <<EOF
343 $ cat > baz <<EOF
344 > 1 baz:1
344 > 1 baz:1
345 > 2 baz:2
345 > 2 baz:2
346 > 3
346 > 3
347 > 4
347 > 4
348 > 5
348 > 5
349 > EOF
349 > EOF
350 $ hg debugsetparents 17 17
350 $ hg debugsetparents 17 17
351 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:2"
351 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:2"
352 $ hg debugindexdot .hg/store/data/baz.i
352 $ hg debugindexdot .hg/store/data/baz.i
353 digraph G {
353 digraph G {
354 -1 -> 0
354 -1 -> 0
355 0 -> 1
355 0 -> 1
356 1 -> 2
356 1 -> 2
357 1 -> 2
357 1 -> 2
358 }
358 }
359 $ hg annotate baz
359 $ hg annotate baz
360 17: 1 baz:1
360 17: 1 baz:1
361 18: 2 baz:2
361 18: 2 baz:2
362 16: 3
362 16: 3
363 16: 4
363 16: 4
364 16: 5
364 16: 5
365
365
366 $ cat > baz <<EOF
366 $ cat > baz <<EOF
367 > 1 baz:1
367 > 1 baz:1
368 > 2 baz:2
368 > 2 baz:2
369 > 3 baz:3
369 > 3 baz:3
370 > 4
370 > 4
371 > 5
371 > 5
372 > EOF
372 > EOF
373 $ hg commit -m "baz:3"
373 $ hg commit -m "baz:3"
374
374
375 $ cat > baz <<EOF
375 $ cat > baz <<EOF
376 > 1 baz:1
376 > 1 baz:1
377 > 2 baz:2
377 > 2 baz:2
378 > 3 baz:3
378 > 3 baz:3
379 > 4 baz:4
379 > 4 baz:4
380 > 5
380 > 5
381 > EOF
381 > EOF
382 $ hg debugsetparents 19 18
382 $ hg debugsetparents 19 18
383 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:4"
383 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:4"
384 $ hg debugindexdot .hg/store/data/baz.i
384 $ hg debugindexdot .hg/store/data/baz.i
385 digraph G {
385 digraph G {
386 -1 -> 0
386 -1 -> 0
387 0 -> 1
387 0 -> 1
388 1 -> 2
388 1 -> 2
389 1 -> 2
389 1 -> 2
390 2 -> 3
390 2 -> 3
391 3 -> 4
391 3 -> 4
392 2 -> 4
392 2 -> 4
393 }
393 }
394 $ hg annotate baz
394 $ hg annotate baz
395 17: 1 baz:1
395 17: 1 baz:1
396 18: 2 baz:2
396 18: 2 baz:2
397 19: 3 baz:3
397 19: 3 baz:3
398 20: 4 baz:4
398 20: 4 baz:4
399 16: 5
399 16: 5
400
400
401 annotate clean file
402
403 $ hg annotate -ncr "wdir()" foo
404 11 472b18db256d : foo
405
406 annotate modified file
407
408 $ echo foofoo >> foo
409 $ hg annotate -r "wdir()" foo
410 11 : foo
411 20+: foofoo
412
413 $ hg annotate -cr "wdir()" foo
414 472b18db256d : foo
415 b6bedd5477e7+: foofoo
416
417 $ hg annotate -ncr "wdir()" foo
418 11 472b18db256d : foo
419 20 b6bedd5477e7+: foofoo
420
421 $ hg annotate --debug -ncr "wdir()" foo
422 11 472b18db256d1e8282064eab4bfdaf48cbfe83cd : foo
423 20 b6bedd5477e797f25e568a6402d4697f3f895a72+: foofoo
424
425 $ hg annotate -udr "wdir()" foo
426 test Thu Jan 01 00:00:00 1970 +0000: foo
427 test [A-Za-z0-9:+ ]+: foofoo (re)
428
429 $ hg annotate -ncr "wdir()" -Tjson foo
430 [
431 {
432 "line": "foo\n",
433 "node": "472b18db256d1e8282064eab4bfdaf48cbfe83cd",
434 "rev": 11
435 },
436 {
437 "line": "foofoo\n",
438 "node": null,
439 "rev": null
440 }
441 ]
442
443 annotate added file
444
445 $ echo bar > bar
446 $ hg add bar
447 $ hg annotate -ncr "wdir()" bar
448 20 b6bedd5477e7+: bar
449
450 annotate renamed file
451
452 $ hg rename foo renamefoo2
453 $ hg annotate -ncr "wdir()" renamefoo2
454 11 472b18db256d : foo
455 20 b6bedd5477e7+: foofoo
456
457 annotate missing file
458
459 $ rm baz
460 $ hg annotate -ncr "wdir()" baz
461 abort: No such file or directory: $TESTTMP/repo/baz
462 [255]
463
464 annotate removed file
465
466 $ hg rm baz
467 $ hg annotate -ncr "wdir()" baz
468 abort: No such file or directory: $TESTTMP/repo/baz
469 [255]
470
401 Test annotate with whitespace options
471 Test annotate with whitespace options
402
472
403 $ cd ..
473 $ cd ..
404 $ hg init repo-ws
474 $ hg init repo-ws
405 $ cd repo-ws
475 $ cd repo-ws
406 $ cat > a <<EOF
476 $ cat > a <<EOF
407 > aa
477 > aa
408 >
478 >
409 > b b
479 > b b
410 > EOF
480 > EOF
411 $ hg ci -Am "adda"
481 $ hg ci -Am "adda"
412 adding a
482 adding a
413 $ sed 's/EOL$//g' > a <<EOF
483 $ sed 's/EOL$//g' > a <<EOF
414 > a a
484 > a a
415 >
485 >
416 > EOL
486 > EOL
417 > b b
487 > b b
418 > EOF
488 > EOF
419 $ hg ci -m "changea"
489 $ hg ci -m "changea"
420
490
421 Annotate with no option
491 Annotate with no option
422
492
423 $ hg annotate a
493 $ hg annotate a
424 1: a a
494 1: a a
425 0:
495 0:
426 1:
496 1:
427 1: b b
497 1: b b
428
498
429 Annotate with --ignore-space-change
499 Annotate with --ignore-space-change
430
500
431 $ hg annotate --ignore-space-change a
501 $ hg annotate --ignore-space-change a
432 1: a a
502 1: a a
433 1:
503 1:
434 0:
504 0:
435 0: b b
505 0: b b
436
506
437 Annotate with --ignore-all-space
507 Annotate with --ignore-all-space
438
508
439 $ hg annotate --ignore-all-space a
509 $ hg annotate --ignore-all-space a
440 0: a a
510 0: a a
441 0:
511 0:
442 1:
512 1:
443 0: b b
513 0: b b
444
514
445 Annotate with --ignore-blank-lines (similar to no options case)
515 Annotate with --ignore-blank-lines (similar to no options case)
446
516
447 $ hg annotate --ignore-blank-lines a
517 $ hg annotate --ignore-blank-lines a
448 1: a a
518 1: a a
449 0:
519 0:
450 1:
520 1:
451 1: b b
521 1: b b
452
522
453 $ cd ..
523 $ cd ..
454
524
455 Annotate with linkrev pointing to another branch
525 Annotate with linkrev pointing to another branch
456 ------------------------------------------------
526 ------------------------------------------------
457
527
458 create history with a filerev whose linkrev points to another branch
528 create history with a filerev whose linkrev points to another branch
459
529
460 $ hg init branchedlinkrev
530 $ hg init branchedlinkrev
461 $ cd branchedlinkrev
531 $ cd branchedlinkrev
462 $ echo A > a
532 $ echo A > a
463 $ hg commit -Am 'contentA'
533 $ hg commit -Am 'contentA'
464 adding a
534 adding a
465 $ echo B >> a
535 $ echo B >> a
466 $ hg commit -m 'contentB'
536 $ hg commit -m 'contentB'
467 $ hg up --rev 'desc(contentA)'
537 $ hg up --rev 'desc(contentA)'
468 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
538 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
469 $ echo unrelated > unrelated
539 $ echo unrelated > unrelated
470 $ hg commit -Am 'unrelated'
540 $ hg commit -Am 'unrelated'
471 adding unrelated
541 adding unrelated
472 created new head
542 created new head
473 $ hg graft -r 'desc(contentB)'
543 $ hg graft -r 'desc(contentB)'
474 grafting 1:fd27c222e3e6 "contentB"
544 grafting 1:fd27c222e3e6 "contentB"
475 $ echo C >> a
545 $ echo C >> a
476 $ hg commit -m 'contentC'
546 $ hg commit -m 'contentC'
477 $ hg log -G
547 $ hg log -G
478 @ changeset: 4:072f1e8df249
548 @ changeset: 4:072f1e8df249
479 | tag: tip
549 | tag: tip
480 | user: test
550 | user: test
481 | date: Thu Jan 01 00:00:00 1970 +0000
551 | date: Thu Jan 01 00:00:00 1970 +0000
482 | summary: contentC
552 | summary: contentC
483 |
553 |
484 o changeset: 3:ff38df03cc4b
554 o changeset: 3:ff38df03cc4b
485 | user: test
555 | user: test
486 | date: Thu Jan 01 00:00:00 1970 +0000
556 | date: Thu Jan 01 00:00:00 1970 +0000
487 | summary: contentB
557 | summary: contentB
488 |
558 |
489 o changeset: 2:62aaf3f6fc06
559 o changeset: 2:62aaf3f6fc06
490 | parent: 0:f0932f74827e
560 | parent: 0:f0932f74827e
491 | user: test
561 | user: test
492 | date: Thu Jan 01 00:00:00 1970 +0000
562 | date: Thu Jan 01 00:00:00 1970 +0000
493 | summary: unrelated
563 | summary: unrelated
494 |
564 |
495 | o changeset: 1:fd27c222e3e6
565 | o changeset: 1:fd27c222e3e6
496 |/ user: test
566 |/ user: test
497 | date: Thu Jan 01 00:00:00 1970 +0000
567 | date: Thu Jan 01 00:00:00 1970 +0000
498 | summary: contentB
568 | summary: contentB
499 |
569 |
500 o changeset: 0:f0932f74827e
570 o changeset: 0:f0932f74827e
501 user: test
571 user: test
502 date: Thu Jan 01 00:00:00 1970 +0000
572 date: Thu Jan 01 00:00:00 1970 +0000
503 summary: contentA
573 summary: contentA
504
574
505
575
506 Annotate should list ancestor of starting revision only
576 Annotate should list ancestor of starting revision only
507
577
508 $ hg annotate a
578 $ hg annotate a
509 0: A
579 0: A
510 3: B
580 3: B
511 4: C
581 4: C
512
582
513 Even when the starting revision is the linkrev-shadowed one:
583 Even when the starting revision is the linkrev-shadowed one:
514
584
515 $ hg annotate a -r 3
585 $ hg annotate a -r 3
516 0: A
586 0: A
517 3: B
587 3: B
518
588
519 $ cd ..
589 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now