##// END OF EJS Templates
backout: commit changeset by default (BC)...
Ruslan Sayfutdinov -
r27890:ce76c4d2 default
parent child Browse files
Show More
@@ -1,7026 +1,7031 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, nullhex, nullid, nullrev, short
8 from node import hex, bin, nullhex, 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
16 import sshserver, hgweb
17 import extensions
17 import extensions
18 import merge as mergemod
18 import merge as mergemod
19 import minirst, revset, fileset
19 import minirst, revset, fileset
20 import dagparser, context, simplemerge, graphmod, copies
20 import dagparser, context, simplemerge, graphmod, copies
21 import random, operator
21 import random, operator
22 import setdiscovery, treediscovery, dagutil, pvec, localrepo, destutil
22 import setdiscovery, treediscovery, dagutil, pvec, localrepo, destutil
23 import phases, obsolete, exchange, bundle2, repair, lock as lockmod
23 import phases, obsolete, exchange, bundle2, repair, lock as lockmod
24 import ui as uimod
24 import ui as uimod
25 import streamclone
25 import streamclone
26 import commandserver
26 import commandserver
27
27
28 table = {}
28 table = {}
29
29
30 command = cmdutil.command(table)
30 command = cmdutil.command(table)
31
31
32 # Space delimited list of commands that don't require local repositories.
32 # Space delimited list of commands that don't require local repositories.
33 # This should be populated by passing norepo=True into the @command decorator.
33 # This should be populated by passing norepo=True into the @command decorator.
34 norepo = ''
34 norepo = ''
35 # Space delimited list of commands that optionally require local repositories.
35 # Space delimited list of commands that optionally require local repositories.
36 # This should be populated by passing optionalrepo=True into the @command
36 # This should be populated by passing optionalrepo=True into the @command
37 # decorator.
37 # decorator.
38 optionalrepo = ''
38 optionalrepo = ''
39 # Space delimited list of commands that will examine arguments looking for
39 # Space delimited list of commands that will examine arguments looking for
40 # a repository. This should be populated by passing inferrepo=True into the
40 # a repository. This should be populated by passing inferrepo=True into the
41 # @command decorator.
41 # @command decorator.
42 inferrepo = ''
42 inferrepo = ''
43
43
44 # label constants
44 # label constants
45 # until 3.5, bookmarks.current was the advertised name, not
45 # until 3.5, bookmarks.current was the advertised name, not
46 # bookmarks.active, so we must use both to avoid breaking old
46 # bookmarks.active, so we must use both to avoid breaking old
47 # custom styles
47 # custom styles
48 activebookmarklabel = 'bookmarks.active bookmarks.current'
48 activebookmarklabel = 'bookmarks.active bookmarks.current'
49
49
50 # common command options
50 # common command options
51
51
52 globalopts = [
52 globalopts = [
53 ('R', 'repository', '',
53 ('R', 'repository', '',
54 _('repository root directory or name of overlay bundle file'),
54 _('repository root directory or name of overlay bundle file'),
55 _('REPO')),
55 _('REPO')),
56 ('', 'cwd', '',
56 ('', 'cwd', '',
57 _('change working directory'), _('DIR')),
57 _('change working directory'), _('DIR')),
58 ('y', 'noninteractive', None,
58 ('y', 'noninteractive', None,
59 _('do not prompt, automatically pick the first choice for all prompts')),
59 _('do not prompt, automatically pick the first choice for all prompts')),
60 ('q', 'quiet', None, _('suppress output')),
60 ('q', 'quiet', None, _('suppress output')),
61 ('v', 'verbose', None, _('enable additional output')),
61 ('v', 'verbose', None, _('enable additional output')),
62 ('', 'config', [],
62 ('', 'config', [],
63 _('set/override config option (use \'section.name=value\')'),
63 _('set/override config option (use \'section.name=value\')'),
64 _('CONFIG')),
64 _('CONFIG')),
65 ('', 'debug', None, _('enable debugging output')),
65 ('', 'debug', None, _('enable debugging output')),
66 ('', 'debugger', None, _('start debugger')),
66 ('', 'debugger', None, _('start debugger')),
67 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
67 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
68 _('ENCODE')),
68 _('ENCODE')),
69 ('', 'encodingmode', encoding.encodingmode,
69 ('', 'encodingmode', encoding.encodingmode,
70 _('set the charset encoding mode'), _('MODE')),
70 _('set the charset encoding mode'), _('MODE')),
71 ('', 'traceback', None, _('always print a traceback on exception')),
71 ('', 'traceback', None, _('always print a traceback on exception')),
72 ('', 'time', None, _('time how long the command takes')),
72 ('', 'time', None, _('time how long the command takes')),
73 ('', 'profile', None, _('print command execution profile')),
73 ('', 'profile', None, _('print command execution profile')),
74 ('', 'version', None, _('output version information and exit')),
74 ('', 'version', None, _('output version information and exit')),
75 ('h', 'help', None, _('display help and exit')),
75 ('h', 'help', None, _('display help and exit')),
76 ('', 'hidden', False, _('consider hidden changesets')),
76 ('', 'hidden', False, _('consider hidden changesets')),
77 ]
77 ]
78
78
79 dryrunopts = [('n', 'dry-run', None,
79 dryrunopts = [('n', 'dry-run', None,
80 _('do not perform actions, just print output'))]
80 _('do not perform actions, just print output'))]
81
81
82 remoteopts = [
82 remoteopts = [
83 ('e', 'ssh', '',
83 ('e', 'ssh', '',
84 _('specify ssh command to use'), _('CMD')),
84 _('specify ssh command to use'), _('CMD')),
85 ('', 'remotecmd', '',
85 ('', 'remotecmd', '',
86 _('specify hg command to run on the remote side'), _('CMD')),
86 _('specify hg command to run on the remote side'), _('CMD')),
87 ('', 'insecure', None,
87 ('', 'insecure', None,
88 _('do not verify server certificate (ignoring web.cacerts config)')),
88 _('do not verify server certificate (ignoring web.cacerts config)')),
89 ]
89 ]
90
90
91 walkopts = [
91 walkopts = [
92 ('I', 'include', [],
92 ('I', 'include', [],
93 _('include names matching the given patterns'), _('PATTERN')),
93 _('include names matching the given patterns'), _('PATTERN')),
94 ('X', 'exclude', [],
94 ('X', 'exclude', [],
95 _('exclude names matching the given patterns'), _('PATTERN')),
95 _('exclude names matching the given patterns'), _('PATTERN')),
96 ]
96 ]
97
97
98 commitopts = [
98 commitopts = [
99 ('m', 'message', '',
99 ('m', 'message', '',
100 _('use text as commit message'), _('TEXT')),
100 _('use text as commit message'), _('TEXT')),
101 ('l', 'logfile', '',
101 ('l', 'logfile', '',
102 _('read commit message from file'), _('FILE')),
102 _('read commit message from file'), _('FILE')),
103 ]
103 ]
104
104
105 commitopts2 = [
105 commitopts2 = [
106 ('d', 'date', '',
106 ('d', 'date', '',
107 _('record the specified date as commit date'), _('DATE')),
107 _('record the specified date as commit date'), _('DATE')),
108 ('u', 'user', '',
108 ('u', 'user', '',
109 _('record the specified user as committer'), _('USER')),
109 _('record the specified user as committer'), _('USER')),
110 ]
110 ]
111
111
112 # hidden for now
112 # hidden for now
113 formatteropts = [
113 formatteropts = [
114 ('T', 'template', '',
114 ('T', 'template', '',
115 _('display with template (EXPERIMENTAL)'), _('TEMPLATE')),
115 _('display with template (EXPERIMENTAL)'), _('TEMPLATE')),
116 ]
116 ]
117
117
118 templateopts = [
118 templateopts = [
119 ('', 'style', '',
119 ('', 'style', '',
120 _('display using template map file (DEPRECATED)'), _('STYLE')),
120 _('display using template map file (DEPRECATED)'), _('STYLE')),
121 ('T', 'template', '',
121 ('T', 'template', '',
122 _('display with template'), _('TEMPLATE')),
122 _('display with template'), _('TEMPLATE')),
123 ]
123 ]
124
124
125 logopts = [
125 logopts = [
126 ('p', 'patch', None, _('show patch')),
126 ('p', 'patch', None, _('show patch')),
127 ('g', 'git', None, _('use git extended diff format')),
127 ('g', 'git', None, _('use git extended diff format')),
128 ('l', 'limit', '',
128 ('l', 'limit', '',
129 _('limit number of changes displayed'), _('NUM')),
129 _('limit number of changes displayed'), _('NUM')),
130 ('M', 'no-merges', None, _('do not show merges')),
130 ('M', 'no-merges', None, _('do not show merges')),
131 ('', 'stat', None, _('output diffstat-style summary of changes')),
131 ('', 'stat', None, _('output diffstat-style summary of changes')),
132 ('G', 'graph', None, _("show the revision DAG")),
132 ('G', 'graph', None, _("show the revision DAG")),
133 ] + templateopts
133 ] + templateopts
134
134
135 diffopts = [
135 diffopts = [
136 ('a', 'text', None, _('treat all files as text')),
136 ('a', 'text', None, _('treat all files as text')),
137 ('g', 'git', None, _('use git extended diff format')),
137 ('g', 'git', None, _('use git extended diff format')),
138 ('', 'nodates', None, _('omit dates from diff headers'))
138 ('', 'nodates', None, _('omit dates from diff headers'))
139 ]
139 ]
140
140
141 diffwsopts = [
141 diffwsopts = [
142 ('w', 'ignore-all-space', None,
142 ('w', 'ignore-all-space', None,
143 _('ignore white space when comparing lines')),
143 _('ignore white space when comparing lines')),
144 ('b', 'ignore-space-change', None,
144 ('b', 'ignore-space-change', None,
145 _('ignore changes in the amount of white space')),
145 _('ignore changes in the amount of white space')),
146 ('B', 'ignore-blank-lines', None,
146 ('B', 'ignore-blank-lines', None,
147 _('ignore changes whose lines are all blank')),
147 _('ignore changes whose lines are all blank')),
148 ]
148 ]
149
149
150 diffopts2 = [
150 diffopts2 = [
151 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
151 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
152 ('p', 'show-function', None, _('show which function each change is in')),
152 ('p', 'show-function', None, _('show which function each change is in')),
153 ('', 'reverse', None, _('produce a diff that undoes the changes')),
153 ('', 'reverse', None, _('produce a diff that undoes the changes')),
154 ] + diffwsopts + [
154 ] + diffwsopts + [
155 ('U', 'unified', '',
155 ('U', 'unified', '',
156 _('number of lines of context to show'), _('NUM')),
156 _('number of lines of context to show'), _('NUM')),
157 ('', 'stat', None, _('output diffstat-style summary of changes')),
157 ('', 'stat', None, _('output diffstat-style summary of changes')),
158 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
158 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
159 ]
159 ]
160
160
161 mergetoolopts = [
161 mergetoolopts = [
162 ('t', 'tool', '', _('specify merge tool')),
162 ('t', 'tool', '', _('specify merge tool')),
163 ]
163 ]
164
164
165 similarityopts = [
165 similarityopts = [
166 ('s', 'similarity', '',
166 ('s', 'similarity', '',
167 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
167 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
168 ]
168 ]
169
169
170 subrepoopts = [
170 subrepoopts = [
171 ('S', 'subrepos', None,
171 ('S', 'subrepos', None,
172 _('recurse into subrepositories'))
172 _('recurse into subrepositories'))
173 ]
173 ]
174
174
175 debugrevlogopts = [
175 debugrevlogopts = [
176 ('c', 'changelog', False, _('open changelog')),
176 ('c', 'changelog', False, _('open changelog')),
177 ('m', 'manifest', False, _('open manifest')),
177 ('m', 'manifest', False, _('open manifest')),
178 ('', 'dir', False, _('open directory manifest')),
178 ('', 'dir', False, _('open directory manifest')),
179 ]
179 ]
180
180
181 # Commands start here, listed alphabetically
181 # Commands start here, listed alphabetically
182
182
183 @command('^add',
183 @command('^add',
184 walkopts + subrepoopts + dryrunopts,
184 walkopts + subrepoopts + dryrunopts,
185 _('[OPTION]... [FILE]...'),
185 _('[OPTION]... [FILE]...'),
186 inferrepo=True)
186 inferrepo=True)
187 def add(ui, repo, *pats, **opts):
187 def add(ui, repo, *pats, **opts):
188 """add the specified files on the next commit
188 """add the specified files on the next commit
189
189
190 Schedule files to be version controlled and added to the
190 Schedule files to be version controlled and added to the
191 repository.
191 repository.
192
192
193 The files will be added to the repository at the next commit. To
193 The files will be added to the repository at the next commit. To
194 undo an add before that, see :hg:`forget`.
194 undo an add before that, see :hg:`forget`.
195
195
196 If no names are given, add all files to the repository (except
196 If no names are given, add all files to the repository (except
197 files matching ``.hgignore``).
197 files matching ``.hgignore``).
198
198
199 .. container:: verbose
199 .. container:: verbose
200
200
201 Examples:
201 Examples:
202
202
203 - New (unknown) files are added
203 - New (unknown) files are added
204 automatically by :hg:`add`::
204 automatically by :hg:`add`::
205
205
206 $ ls
206 $ ls
207 foo.c
207 foo.c
208 $ hg status
208 $ hg status
209 ? foo.c
209 ? foo.c
210 $ hg add
210 $ hg add
211 adding foo.c
211 adding foo.c
212 $ hg status
212 $ hg status
213 A foo.c
213 A foo.c
214
214
215 - Specific files to be added can be specified::
215 - Specific files to be added can be specified::
216
216
217 $ ls
217 $ ls
218 bar.c foo.c
218 bar.c foo.c
219 $ hg status
219 $ hg status
220 ? bar.c
220 ? bar.c
221 ? foo.c
221 ? foo.c
222 $ hg add bar.c
222 $ hg add bar.c
223 $ hg status
223 $ hg status
224 A bar.c
224 A bar.c
225 ? foo.c
225 ? foo.c
226
226
227 Returns 0 if all files are successfully added.
227 Returns 0 if all files are successfully added.
228 """
228 """
229
229
230 m = scmutil.match(repo[None], pats, opts)
230 m = scmutil.match(repo[None], pats, opts)
231 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
231 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
232 return rejected and 1 or 0
232 return rejected and 1 or 0
233
233
234 @command('addremove',
234 @command('addremove',
235 similarityopts + subrepoopts + walkopts + dryrunopts,
235 similarityopts + subrepoopts + walkopts + dryrunopts,
236 _('[OPTION]... [FILE]...'),
236 _('[OPTION]... [FILE]...'),
237 inferrepo=True)
237 inferrepo=True)
238 def addremove(ui, repo, *pats, **opts):
238 def addremove(ui, repo, *pats, **opts):
239 """add all new files, delete all missing files
239 """add all new files, delete all missing files
240
240
241 Add all new files and remove all missing files from the
241 Add all new files and remove all missing files from the
242 repository.
242 repository.
243
243
244 Unless names are given, new files are ignored if they match any of
244 Unless names are given, new files are ignored if they match any of
245 the patterns in ``.hgignore``. As with add, these changes take
245 the patterns in ``.hgignore``. As with add, these changes take
246 effect at the next commit.
246 effect at the next commit.
247
247
248 Use the -s/--similarity option to detect renamed files. This
248 Use the -s/--similarity option to detect renamed files. This
249 option takes a percentage between 0 (disabled) and 100 (files must
249 option takes a percentage between 0 (disabled) and 100 (files must
250 be identical) as its parameter. With a parameter greater than 0,
250 be identical) as its parameter. With a parameter greater than 0,
251 this compares every removed file with every added file and records
251 this compares every removed file with every added file and records
252 those similar enough as renames. Detecting renamed files this way
252 those similar enough as renames. Detecting renamed files this way
253 can be expensive. After using this option, :hg:`status -C` can be
253 can be expensive. After using this option, :hg:`status -C` can be
254 used to check which files were identified as moved or renamed. If
254 used to check which files were identified as moved or renamed. If
255 not specified, -s/--similarity defaults to 100 and only renames of
255 not specified, -s/--similarity defaults to 100 and only renames of
256 identical files are detected.
256 identical files are detected.
257
257
258 .. container:: verbose
258 .. container:: verbose
259
259
260 Examples:
260 Examples:
261
261
262 - A number of files (bar.c and foo.c) are new,
262 - A number of files (bar.c and foo.c) are new,
263 while foobar.c has been removed (without using :hg:`remove`)
263 while foobar.c has been removed (without using :hg:`remove`)
264 from the repository::
264 from the repository::
265
265
266 $ ls
266 $ ls
267 bar.c foo.c
267 bar.c foo.c
268 $ hg status
268 $ hg status
269 ! foobar.c
269 ! foobar.c
270 ? bar.c
270 ? bar.c
271 ? foo.c
271 ? foo.c
272 $ hg addremove
272 $ hg addremove
273 adding bar.c
273 adding bar.c
274 adding foo.c
274 adding foo.c
275 removing foobar.c
275 removing foobar.c
276 $ hg status
276 $ hg status
277 A bar.c
277 A bar.c
278 A foo.c
278 A foo.c
279 R foobar.c
279 R foobar.c
280
280
281 - A file foobar.c was moved to foo.c without using :hg:`rename`.
281 - A file foobar.c was moved to foo.c without using :hg:`rename`.
282 Afterwards, it was edited slightly::
282 Afterwards, it was edited slightly::
283
283
284 $ ls
284 $ ls
285 foo.c
285 foo.c
286 $ hg status
286 $ hg status
287 ! foobar.c
287 ! foobar.c
288 ? foo.c
288 ? foo.c
289 $ hg addremove --similarity 90
289 $ hg addremove --similarity 90
290 removing foobar.c
290 removing foobar.c
291 adding foo.c
291 adding foo.c
292 recording removal of foobar.c as rename to foo.c (94% similar)
292 recording removal of foobar.c as rename to foo.c (94% similar)
293 $ hg status -C
293 $ hg status -C
294 A foo.c
294 A foo.c
295 foobar.c
295 foobar.c
296 R foobar.c
296 R foobar.c
297
297
298 Returns 0 if all files are successfully added.
298 Returns 0 if all files are successfully added.
299 """
299 """
300 try:
300 try:
301 sim = float(opts.get('similarity') or 100)
301 sim = float(opts.get('similarity') or 100)
302 except ValueError:
302 except ValueError:
303 raise error.Abort(_('similarity must be a number'))
303 raise error.Abort(_('similarity must be a number'))
304 if sim < 0 or sim > 100:
304 if sim < 0 or sim > 100:
305 raise error.Abort(_('similarity must be between 0 and 100'))
305 raise error.Abort(_('similarity must be between 0 and 100'))
306 matcher = scmutil.match(repo[None], pats, opts)
306 matcher = scmutil.match(repo[None], pats, opts)
307 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
307 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
308
308
309 @command('^annotate|blame',
309 @command('^annotate|blame',
310 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
310 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
311 ('', 'follow', None,
311 ('', 'follow', None,
312 _('follow copies/renames and list the filename (DEPRECATED)')),
312 _('follow copies/renames and list the filename (DEPRECATED)')),
313 ('', 'no-follow', None, _("don't follow copies and renames")),
313 ('', 'no-follow', None, _("don't follow copies and renames")),
314 ('a', 'text', None, _('treat all files as text')),
314 ('a', 'text', None, _('treat all files as text')),
315 ('u', 'user', None, _('list the author (long with -v)')),
315 ('u', 'user', None, _('list the author (long with -v)')),
316 ('f', 'file', None, _('list the filename')),
316 ('f', 'file', None, _('list the filename')),
317 ('d', 'date', None, _('list the date (short with -q)')),
317 ('d', 'date', None, _('list the date (short with -q)')),
318 ('n', 'number', None, _('list the revision number (default)')),
318 ('n', 'number', None, _('list the revision number (default)')),
319 ('c', 'changeset', None, _('list the changeset')),
319 ('c', 'changeset', None, _('list the changeset')),
320 ('l', 'line-number', None, _('show line number at the first appearance'))
320 ('l', 'line-number', None, _('show line number at the first appearance'))
321 ] + diffwsopts + walkopts + formatteropts,
321 ] + diffwsopts + walkopts + formatteropts,
322 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
322 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
323 inferrepo=True)
323 inferrepo=True)
324 def annotate(ui, repo, *pats, **opts):
324 def annotate(ui, repo, *pats, **opts):
325 """show changeset information by line for each file
325 """show changeset information by line for each file
326
326
327 List changes in files, showing the revision id responsible for
327 List changes in files, showing the revision id responsible for
328 each line.
328 each line.
329
329
330 This command is useful for discovering when a change was made and
330 This command is useful for discovering when a change was made and
331 by whom.
331 by whom.
332
332
333 If you include --file, --user, or --date, the revision number is
333 If you include --file, --user, or --date, the revision number is
334 suppressed unless you also include --number.
334 suppressed unless you also include --number.
335
335
336 Without the -a/--text option, annotate will avoid processing files
336 Without the -a/--text option, annotate will avoid processing files
337 it detects as binary. With -a, annotate will annotate the file
337 it detects as binary. With -a, annotate will annotate the file
338 anyway, although the results will probably be neither useful
338 anyway, although the results will probably be neither useful
339 nor desirable.
339 nor desirable.
340
340
341 Returns 0 on success.
341 Returns 0 on success.
342 """
342 """
343 if not pats:
343 if not pats:
344 raise error.Abort(_('at least one filename or pattern is required'))
344 raise error.Abort(_('at least one filename or pattern is required'))
345
345
346 if opts.get('follow'):
346 if opts.get('follow'):
347 # --follow is deprecated and now just an alias for -f/--file
347 # --follow is deprecated and now just an alias for -f/--file
348 # to mimic the behavior of Mercurial before version 1.5
348 # to mimic the behavior of Mercurial before version 1.5
349 opts['file'] = True
349 opts['file'] = True
350
350
351 ctx = scmutil.revsingle(repo, opts.get('rev'))
351 ctx = scmutil.revsingle(repo, opts.get('rev'))
352
352
353 fm = ui.formatter('annotate', opts)
353 fm = ui.formatter('annotate', opts)
354 if ui.quiet:
354 if ui.quiet:
355 datefunc = util.shortdate
355 datefunc = util.shortdate
356 else:
356 else:
357 datefunc = util.datestr
357 datefunc = util.datestr
358 if ctx.rev() is None:
358 if ctx.rev() is None:
359 def hexfn(node):
359 def hexfn(node):
360 if node is None:
360 if node is None:
361 return None
361 return None
362 else:
362 else:
363 return fm.hexfunc(node)
363 return fm.hexfunc(node)
364 if opts.get('changeset'):
364 if opts.get('changeset'):
365 # omit "+" suffix which is appended to node hex
365 # omit "+" suffix which is appended to node hex
366 def formatrev(rev):
366 def formatrev(rev):
367 if rev is None:
367 if rev is None:
368 return '%d' % ctx.p1().rev()
368 return '%d' % ctx.p1().rev()
369 else:
369 else:
370 return '%d' % rev
370 return '%d' % rev
371 else:
371 else:
372 def formatrev(rev):
372 def formatrev(rev):
373 if rev is None:
373 if rev is None:
374 return '%d+' % ctx.p1().rev()
374 return '%d+' % ctx.p1().rev()
375 else:
375 else:
376 return '%d ' % rev
376 return '%d ' % rev
377 def formathex(hex):
377 def formathex(hex):
378 if hex is None:
378 if hex is None:
379 return '%s+' % fm.hexfunc(ctx.p1().node())
379 return '%s+' % fm.hexfunc(ctx.p1().node())
380 else:
380 else:
381 return '%s ' % hex
381 return '%s ' % hex
382 else:
382 else:
383 hexfn = fm.hexfunc
383 hexfn = fm.hexfunc
384 formatrev = formathex = str
384 formatrev = formathex = str
385
385
386 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
386 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
387 ('number', ' ', lambda x: x[0].rev(), formatrev),
387 ('number', ' ', lambda x: x[0].rev(), formatrev),
388 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
388 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
389 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
389 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
390 ('file', ' ', lambda x: x[0].path(), str),
390 ('file', ' ', lambda x: x[0].path(), str),
391 ('line_number', ':', lambda x: x[1], str),
391 ('line_number', ':', lambda x: x[1], str),
392 ]
392 ]
393 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
393 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
394
394
395 if (not opts.get('user') and not opts.get('changeset')
395 if (not opts.get('user') and not opts.get('changeset')
396 and not opts.get('date') and not opts.get('file')):
396 and not opts.get('date') and not opts.get('file')):
397 opts['number'] = True
397 opts['number'] = True
398
398
399 linenumber = opts.get('line_number') is not None
399 linenumber = opts.get('line_number') is not None
400 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
400 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
401 raise error.Abort(_('at least one of -n/-c is required for -l'))
401 raise error.Abort(_('at least one of -n/-c is required for -l'))
402
402
403 if fm:
403 if fm:
404 def makefunc(get, fmt):
404 def makefunc(get, fmt):
405 return get
405 return get
406 else:
406 else:
407 def makefunc(get, fmt):
407 def makefunc(get, fmt):
408 return lambda x: fmt(get(x))
408 return lambda x: fmt(get(x))
409 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
409 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
410 if opts.get(op)]
410 if opts.get(op)]
411 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
411 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
412 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
412 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
413 if opts.get(op))
413 if opts.get(op))
414
414
415 def bad(x, y):
415 def bad(x, y):
416 raise error.Abort("%s: %s" % (x, y))
416 raise error.Abort("%s: %s" % (x, y))
417
417
418 m = scmutil.match(ctx, pats, opts, badfn=bad)
418 m = scmutil.match(ctx, pats, opts, badfn=bad)
419
419
420 follow = not opts.get('no_follow')
420 follow = not opts.get('no_follow')
421 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
421 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
422 whitespace=True)
422 whitespace=True)
423 for abs in ctx.walk(m):
423 for abs in ctx.walk(m):
424 fctx = ctx[abs]
424 fctx = ctx[abs]
425 if not opts.get('text') and util.binary(fctx.data()):
425 if not opts.get('text') and util.binary(fctx.data()):
426 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
426 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
427 continue
427 continue
428
428
429 lines = fctx.annotate(follow=follow, linenumber=linenumber,
429 lines = fctx.annotate(follow=follow, linenumber=linenumber,
430 diffopts=diffopts)
430 diffopts=diffopts)
431 formats = []
431 formats = []
432 pieces = []
432 pieces = []
433
433
434 for f, sep in funcmap:
434 for f, sep in funcmap:
435 l = [f(n) for n, dummy in lines]
435 l = [f(n) for n, dummy in lines]
436 if l:
436 if l:
437 if fm:
437 if fm:
438 formats.append(['%s' for x in l])
438 formats.append(['%s' for x in l])
439 else:
439 else:
440 sizes = [encoding.colwidth(x) for x in l]
440 sizes = [encoding.colwidth(x) for x in l]
441 ml = max(sizes)
441 ml = max(sizes)
442 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
442 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
443 pieces.append(l)
443 pieces.append(l)
444
444
445 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
445 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
446 fm.startitem()
446 fm.startitem()
447 fm.write(fields, "".join(f), *p)
447 fm.write(fields, "".join(f), *p)
448 fm.write('line', ": %s", l[1])
448 fm.write('line', ": %s", l[1])
449
449
450 if lines and not lines[-1][1].endswith('\n'):
450 if lines and not lines[-1][1].endswith('\n'):
451 fm.plain('\n')
451 fm.plain('\n')
452
452
453 fm.end()
453 fm.end()
454
454
455 @command('archive',
455 @command('archive',
456 [('', 'no-decode', None, _('do not pass files through decoders')),
456 [('', 'no-decode', None, _('do not pass files through decoders')),
457 ('p', 'prefix', '', _('directory prefix for files in archive'),
457 ('p', 'prefix', '', _('directory prefix for files in archive'),
458 _('PREFIX')),
458 _('PREFIX')),
459 ('r', 'rev', '', _('revision to distribute'), _('REV')),
459 ('r', 'rev', '', _('revision to distribute'), _('REV')),
460 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
460 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
461 ] + subrepoopts + walkopts,
461 ] + subrepoopts + walkopts,
462 _('[OPTION]... DEST'))
462 _('[OPTION]... DEST'))
463 def archive(ui, repo, dest, **opts):
463 def archive(ui, repo, dest, **opts):
464 '''create an unversioned archive of a repository revision
464 '''create an unversioned archive of a repository revision
465
465
466 By default, the revision used is the parent of the working
466 By default, the revision used is the parent of the working
467 directory; use -r/--rev to specify a different revision.
467 directory; use -r/--rev to specify a different revision.
468
468
469 The archive type is automatically detected based on file
469 The archive type is automatically detected based on file
470 extension (to override, use -t/--type).
470 extension (to override, use -t/--type).
471
471
472 .. container:: verbose
472 .. container:: verbose
473
473
474 Examples:
474 Examples:
475
475
476 - create a zip file containing the 1.0 release::
476 - create a zip file containing the 1.0 release::
477
477
478 hg archive -r 1.0 project-1.0.zip
478 hg archive -r 1.0 project-1.0.zip
479
479
480 - create a tarball excluding .hg files::
480 - create a tarball excluding .hg files::
481
481
482 hg archive project.tar.gz -X ".hg*"
482 hg archive project.tar.gz -X ".hg*"
483
483
484 Valid types are:
484 Valid types are:
485
485
486 :``files``: a directory full of files (default)
486 :``files``: a directory full of files (default)
487 :``tar``: tar archive, uncompressed
487 :``tar``: tar archive, uncompressed
488 :``tbz2``: tar archive, compressed using bzip2
488 :``tbz2``: tar archive, compressed using bzip2
489 :``tgz``: tar archive, compressed using gzip
489 :``tgz``: tar archive, compressed using gzip
490 :``uzip``: zip archive, uncompressed
490 :``uzip``: zip archive, uncompressed
491 :``zip``: zip archive, compressed using deflate
491 :``zip``: zip archive, compressed using deflate
492
492
493 The exact name of the destination archive or directory is given
493 The exact name of the destination archive or directory is given
494 using a format string; see :hg:`help export` for details.
494 using a format string; see :hg:`help export` for details.
495
495
496 Each member added to an archive file has a directory prefix
496 Each member added to an archive file has a directory prefix
497 prepended. Use -p/--prefix to specify a format string for the
497 prepended. Use -p/--prefix to specify a format string for the
498 prefix. The default is the basename of the archive, with suffixes
498 prefix. The default is the basename of the archive, with suffixes
499 removed.
499 removed.
500
500
501 Returns 0 on success.
501 Returns 0 on success.
502 '''
502 '''
503
503
504 ctx = scmutil.revsingle(repo, opts.get('rev'))
504 ctx = scmutil.revsingle(repo, opts.get('rev'))
505 if not ctx:
505 if not ctx:
506 raise error.Abort(_('no working directory: please specify a revision'))
506 raise error.Abort(_('no working directory: please specify a revision'))
507 node = ctx.node()
507 node = ctx.node()
508 dest = cmdutil.makefilename(repo, dest, node)
508 dest = cmdutil.makefilename(repo, dest, node)
509 if os.path.realpath(dest) == repo.root:
509 if os.path.realpath(dest) == repo.root:
510 raise error.Abort(_('repository root cannot be destination'))
510 raise error.Abort(_('repository root cannot be destination'))
511
511
512 kind = opts.get('type') or archival.guesskind(dest) or 'files'
512 kind = opts.get('type') or archival.guesskind(dest) or 'files'
513 prefix = opts.get('prefix')
513 prefix = opts.get('prefix')
514
514
515 if dest == '-':
515 if dest == '-':
516 if kind == 'files':
516 if kind == 'files':
517 raise error.Abort(_('cannot archive plain files to stdout'))
517 raise error.Abort(_('cannot archive plain files to stdout'))
518 dest = cmdutil.makefileobj(repo, dest)
518 dest = cmdutil.makefileobj(repo, dest)
519 if not prefix:
519 if not prefix:
520 prefix = os.path.basename(repo.root) + '-%h'
520 prefix = os.path.basename(repo.root) + '-%h'
521
521
522 prefix = cmdutil.makefilename(repo, prefix, node)
522 prefix = cmdutil.makefilename(repo, prefix, node)
523 matchfn = scmutil.match(ctx, [], opts)
523 matchfn = scmutil.match(ctx, [], opts)
524 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
524 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
525 matchfn, prefix, subrepos=opts.get('subrepos'))
525 matchfn, prefix, subrepos=opts.get('subrepos'))
526
526
527 @command('backout',
527 @command('backout',
528 [('', 'merge', None, _('merge with old dirstate parent after backout')),
528 [('', 'merge', None, _('merge with old dirstate parent after backout')),
529 ('', 'commit', None, _('commit if no conflicts were encountered')),
529 ('', 'commit', None,
530 _('commit if no conflicts were encountered (DEPRECATED)')),
531 ('', 'no-commit', None, _('do not commit')),
530 ('', 'parent', '',
532 ('', 'parent', '',
531 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
533 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
532 ('r', 'rev', '', _('revision to backout'), _('REV')),
534 ('r', 'rev', '', _('revision to backout'), _('REV')),
533 ('e', 'edit', False, _('invoke editor on commit messages')),
535 ('e', 'edit', False, _('invoke editor on commit messages')),
534 ] + mergetoolopts + walkopts + commitopts + commitopts2,
536 ] + mergetoolopts + walkopts + commitopts + commitopts2,
535 _('[OPTION]... [-r] REV'))
537 _('[OPTION]... [-r] REV'))
536 def backout(ui, repo, node=None, rev=None, commit=False, **opts):
538 def backout(ui, repo, node=None, rev=None, **opts):
537 '''reverse effect of earlier changeset
539 '''reverse effect of earlier changeset
538
540
539 Prepare a new changeset with the effect of REV undone in the
541 Prepare a new changeset with the effect of REV undone in the
540 current working directory.
542 current working directory. If no conflicts were encountered,
543 it will be committed immediately.
541
544
542 If REV is the parent of the working directory, then this new changeset
545 If REV is the parent of the working directory, then this new changeset
543 is committed automatically. Otherwise, hg needs to merge the
546 is committed automatically (unless --no-commit is specified).
544 changes and the merged result is left uncommitted.
545
547
546 .. note::
548 .. note::
547
549
548 :hg:`backout` cannot be used to fix either an unwanted or
550 :hg:`backout` cannot be used to fix either an unwanted or
549 incorrect merge.
551 incorrect merge.
550
552
551 .. container:: verbose
553 .. container:: verbose
552
554
553 Examples:
555 Examples:
554
556
555 - Reverse the effect of the parent of the working directory.
557 - Reverse the effect of the parent of the working directory.
556 This backout will be committed immediately::
558 This backout will be committed immediately::
557
559
558 hg backout -r .
560 hg backout -r .
559
561
560 - Reverse the effect of previous bad revision 23::
562 - Reverse the effect of previous bad revision 23::
561
563
562 hg backout -r 23
564 hg backout -r 23
563 hg commit -m "Backout revision 23"
564
565
565 - Reverse the effect of previous bad revision 23 and
566 - Reverse the effect of previous bad revision 23 and
566 commit the backout immediately::
567 leave changes uncommitted::
567
568
568 hg backout -r 23 --commit
569 hg backout -r 23 --no-commit
570 hg commit -m "Backout revision 23"
569
571
570 By default, the pending changeset will have one parent,
572 By default, the pending changeset will have one parent,
571 maintaining a linear history. With --merge, the pending
573 maintaining a linear history. With --merge, the pending
572 changeset will instead have two parents: the old parent of the
574 changeset will instead have two parents: the old parent of the
573 working directory and a new child of REV that simply undoes REV.
575 working directory and a new child of REV that simply undoes REV.
574
576
575 Before version 1.7, the behavior without --merge was equivalent
577 Before version 1.7, the behavior without --merge was equivalent
576 to specifying --merge followed by :hg:`update --clean .` to
578 to specifying --merge followed by :hg:`update --clean .` to
577 cancel the merge and leave the child of REV as a head to be
579 cancel the merge and leave the child of REV as a head to be
578 merged separately.
580 merged separately.
579
581
580 See :hg:`help dates` for a list of formats valid for -d/--date.
582 See :hg:`help dates` for a list of formats valid for -d/--date.
581
583
582 See :hg:`help revert` for a way to restore files to the state
584 See :hg:`help revert` for a way to restore files to the state
583 of another revision.
585 of another revision.
584
586
585 Returns 0 on success, 1 if nothing to backout or there are unresolved
587 Returns 0 on success, 1 if nothing to backout or there are unresolved
586 files.
588 files.
587 '''
589 '''
588 wlock = lock = None
590 wlock = lock = None
589 try:
591 try:
590 wlock = repo.wlock()
592 wlock = repo.wlock()
591 lock = repo.lock()
593 lock = repo.lock()
592 return _dobackout(ui, repo, node, rev, commit, **opts)
594 return _dobackout(ui, repo, node, rev, **opts)
593 finally:
595 finally:
594 release(lock, wlock)
596 release(lock, wlock)
595
597
596 def _dobackout(ui, repo, node=None, rev=None, commit=False, **opts):
598 def _dobackout(ui, repo, node=None, rev=None, **opts):
599 if opts.get('commit') and opts.get('no_commit'):
600 raise error.Abort(_("cannot use --commit with --no-commit"))
601
597 if rev and node:
602 if rev and node:
598 raise error.Abort(_("please specify just one revision"))
603 raise error.Abort(_("please specify just one revision"))
599
604
600 if not rev:
605 if not rev:
601 rev = node
606 rev = node
602
607
603 if not rev:
608 if not rev:
604 raise error.Abort(_("please specify a revision to backout"))
609 raise error.Abort(_("please specify a revision to backout"))
605
610
606 date = opts.get('date')
611 date = opts.get('date')
607 if date:
612 if date:
608 opts['date'] = util.parsedate(date)
613 opts['date'] = util.parsedate(date)
609
614
610 cmdutil.checkunfinished(repo)
615 cmdutil.checkunfinished(repo)
611 cmdutil.bailifchanged(repo)
616 cmdutil.bailifchanged(repo)
612 node = scmutil.revsingle(repo, rev).node()
617 node = scmutil.revsingle(repo, rev).node()
613
618
614 op1, op2 = repo.dirstate.parents()
619 op1, op2 = repo.dirstate.parents()
615 if not repo.changelog.isancestor(node, op1):
620 if not repo.changelog.isancestor(node, op1):
616 raise error.Abort(_('cannot backout change that is not an ancestor'))
621 raise error.Abort(_('cannot backout change that is not an ancestor'))
617
622
618 p1, p2 = repo.changelog.parents(node)
623 p1, p2 = repo.changelog.parents(node)
619 if p1 == nullid:
624 if p1 == nullid:
620 raise error.Abort(_('cannot backout a change with no parents'))
625 raise error.Abort(_('cannot backout a change with no parents'))
621 if p2 != nullid:
626 if p2 != nullid:
622 if not opts.get('parent'):
627 if not opts.get('parent'):
623 raise error.Abort(_('cannot backout a merge changeset'))
628 raise error.Abort(_('cannot backout a merge changeset'))
624 p = repo.lookup(opts['parent'])
629 p = repo.lookup(opts['parent'])
625 if p not in (p1, p2):
630 if p not in (p1, p2):
626 raise error.Abort(_('%s is not a parent of %s') %
631 raise error.Abort(_('%s is not a parent of %s') %
627 (short(p), short(node)))
632 (short(p), short(node)))
628 parent = p
633 parent = p
629 else:
634 else:
630 if opts.get('parent'):
635 if opts.get('parent'):
631 raise error.Abort(_('cannot use --parent on non-merge changeset'))
636 raise error.Abort(_('cannot use --parent on non-merge changeset'))
632 parent = p1
637 parent = p1
633
638
634 # the backout should appear on the same branch
639 # the backout should appear on the same branch
635 branch = repo.dirstate.branch()
640 branch = repo.dirstate.branch()
636 bheads = repo.branchheads(branch)
641 bheads = repo.branchheads(branch)
637 rctx = scmutil.revsingle(repo, hex(parent))
642 rctx = scmutil.revsingle(repo, hex(parent))
638 if not opts.get('merge') and op1 != node:
643 if not opts.get('merge') and op1 != node:
639 dsguard = cmdutil.dirstateguard(repo, 'backout')
644 dsguard = cmdutil.dirstateguard(repo, 'backout')
640 try:
645 try:
641 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
646 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
642 'backout')
647 'backout')
643 stats = mergemod.update(repo, parent, True, True, node, False)
648 stats = mergemod.update(repo, parent, True, True, node, False)
644 repo.setparents(op1, op2)
649 repo.setparents(op1, op2)
645 dsguard.close()
650 dsguard.close()
646 hg._showstats(repo, stats)
651 hg._showstats(repo, stats)
647 if stats[3]:
652 if stats[3]:
648 repo.ui.status(_("use 'hg resolve' to retry unresolved "
653 repo.ui.status(_("use 'hg resolve' to retry unresolved "
649 "file merges\n"))
654 "file merges\n"))
650 return 1
655 return 1
651 elif not commit:
656 elif opts.get('no_commit'):
652 msg = _("changeset %s backed out, "
657 msg = _("changeset %s backed out, "
653 "don't forget to commit.\n")
658 "don't forget to commit.\n")
654 ui.status(msg % short(node))
659 ui.status(msg % short(node))
655 return 0
660 return 0
656 finally:
661 finally:
657 ui.setconfig('ui', 'forcemerge', '', '')
662 ui.setconfig('ui', 'forcemerge', '', '')
658 lockmod.release(dsguard)
663 lockmod.release(dsguard)
659 else:
664 else:
660 hg.clean(repo, node, show_stats=False)
665 hg.clean(repo, node, show_stats=False)
661 repo.dirstate.setbranch(branch)
666 repo.dirstate.setbranch(branch)
662 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
667 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
663
668
664
669
665 def commitfunc(ui, repo, message, match, opts):
670 def commitfunc(ui, repo, message, match, opts):
666 editform = 'backout'
671 editform = 'backout'
667 e = cmdutil.getcommiteditor(editform=editform, **opts)
672 e = cmdutil.getcommiteditor(editform=editform, **opts)
668 if not message:
673 if not message:
669 # we don't translate commit messages
674 # we don't translate commit messages
670 message = "Backed out changeset %s" % short(node)
675 message = "Backed out changeset %s" % short(node)
671 e = cmdutil.getcommiteditor(edit=True, editform=editform)
676 e = cmdutil.getcommiteditor(edit=True, editform=editform)
672 return repo.commit(message, opts.get('user'), opts.get('date'),
677 return repo.commit(message, opts.get('user'), opts.get('date'),
673 match, editor=e)
678 match, editor=e)
674 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
679 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
675 if not newnode:
680 if not newnode:
676 ui.status(_("nothing changed\n"))
681 ui.status(_("nothing changed\n"))
677 return 1
682 return 1
678 cmdutil.commitstatus(repo, newnode, branch, bheads)
683 cmdutil.commitstatus(repo, newnode, branch, bheads)
679
684
680 def nice(node):
685 def nice(node):
681 return '%d:%s' % (repo.changelog.rev(node), short(node))
686 return '%d:%s' % (repo.changelog.rev(node), short(node))
682 ui.status(_('changeset %s backs out changeset %s\n') %
687 ui.status(_('changeset %s backs out changeset %s\n') %
683 (nice(repo.changelog.tip()), nice(node)))
688 (nice(repo.changelog.tip()), nice(node)))
684 if opts.get('merge') and op1 != node:
689 if opts.get('merge') and op1 != node:
685 hg.clean(repo, op1, show_stats=False)
690 hg.clean(repo, op1, show_stats=False)
686 ui.status(_('merging with changeset %s\n')
691 ui.status(_('merging with changeset %s\n')
687 % nice(repo.changelog.tip()))
692 % nice(repo.changelog.tip()))
688 try:
693 try:
689 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
694 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
690 'backout')
695 'backout')
691 return hg.merge(repo, hex(repo.changelog.tip()))
696 return hg.merge(repo, hex(repo.changelog.tip()))
692 finally:
697 finally:
693 ui.setconfig('ui', 'forcemerge', '', '')
698 ui.setconfig('ui', 'forcemerge', '', '')
694 return 0
699 return 0
695
700
696 @command('bisect',
701 @command('bisect',
697 [('r', 'reset', False, _('reset bisect state')),
702 [('r', 'reset', False, _('reset bisect state')),
698 ('g', 'good', False, _('mark changeset good')),
703 ('g', 'good', False, _('mark changeset good')),
699 ('b', 'bad', False, _('mark changeset bad')),
704 ('b', 'bad', False, _('mark changeset bad')),
700 ('s', 'skip', False, _('skip testing changeset')),
705 ('s', 'skip', False, _('skip testing changeset')),
701 ('e', 'extend', False, _('extend the bisect range')),
706 ('e', 'extend', False, _('extend the bisect range')),
702 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
707 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
703 ('U', 'noupdate', False, _('do not update to target'))],
708 ('U', 'noupdate', False, _('do not update to target'))],
704 _("[-gbsr] [-U] [-c CMD] [REV]"))
709 _("[-gbsr] [-U] [-c CMD] [REV]"))
705 def bisect(ui, repo, rev=None, extra=None, command=None,
710 def bisect(ui, repo, rev=None, extra=None, command=None,
706 reset=None, good=None, bad=None, skip=None, extend=None,
711 reset=None, good=None, bad=None, skip=None, extend=None,
707 noupdate=None):
712 noupdate=None):
708 """subdivision search of changesets
713 """subdivision search of changesets
709
714
710 This command helps to find changesets which introduce problems. To
715 This command helps to find changesets which introduce problems. To
711 use, mark the earliest changeset you know exhibits the problem as
716 use, mark the earliest changeset you know exhibits the problem as
712 bad, then mark the latest changeset which is free from the problem
717 bad, then mark the latest changeset which is free from the problem
713 as good. Bisect will update your working directory to a revision
718 as good. Bisect will update your working directory to a revision
714 for testing (unless the -U/--noupdate option is specified). Once
719 for testing (unless the -U/--noupdate option is specified). Once
715 you have performed tests, mark the working directory as good or
720 you have performed tests, mark the working directory as good or
716 bad, and bisect will either update to another candidate changeset
721 bad, and bisect will either update to another candidate changeset
717 or announce that it has found the bad revision.
722 or announce that it has found the bad revision.
718
723
719 As a shortcut, you can also use the revision argument to mark a
724 As a shortcut, you can also use the revision argument to mark a
720 revision as good or bad without checking it out first.
725 revision as good or bad without checking it out first.
721
726
722 If you supply a command, it will be used for automatic bisection.
727 If you supply a command, it will be used for automatic bisection.
723 The environment variable HG_NODE will contain the ID of the
728 The environment variable HG_NODE will contain the ID of the
724 changeset being tested. The exit status of the command will be
729 changeset being tested. The exit status of the command will be
725 used to mark revisions as good or bad: status 0 means good, 125
730 used to mark revisions as good or bad: status 0 means good, 125
726 means to skip the revision, 127 (command not found) will abort the
731 means to skip the revision, 127 (command not found) will abort the
727 bisection, and any other non-zero exit status means the revision
732 bisection, and any other non-zero exit status means the revision
728 is bad.
733 is bad.
729
734
730 .. container:: verbose
735 .. container:: verbose
731
736
732 Some examples:
737 Some examples:
733
738
734 - start a bisection with known bad revision 34, and good revision 12::
739 - start a bisection with known bad revision 34, and good revision 12::
735
740
736 hg bisect --bad 34
741 hg bisect --bad 34
737 hg bisect --good 12
742 hg bisect --good 12
738
743
739 - advance the current bisection by marking current revision as good or
744 - advance the current bisection by marking current revision as good or
740 bad::
745 bad::
741
746
742 hg bisect --good
747 hg bisect --good
743 hg bisect --bad
748 hg bisect --bad
744
749
745 - mark the current revision, or a known revision, to be skipped (e.g. if
750 - mark the current revision, or a known revision, to be skipped (e.g. if
746 that revision is not usable because of another issue)::
751 that revision is not usable because of another issue)::
747
752
748 hg bisect --skip
753 hg bisect --skip
749 hg bisect --skip 23
754 hg bisect --skip 23
750
755
751 - skip all revisions that do not touch directories ``foo`` or ``bar``::
756 - skip all revisions that do not touch directories ``foo`` or ``bar``::
752
757
753 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
758 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
754
759
755 - forget the current bisection::
760 - forget the current bisection::
756
761
757 hg bisect --reset
762 hg bisect --reset
758
763
759 - use 'make && make tests' to automatically find the first broken
764 - use 'make && make tests' to automatically find the first broken
760 revision::
765 revision::
761
766
762 hg bisect --reset
767 hg bisect --reset
763 hg bisect --bad 34
768 hg bisect --bad 34
764 hg bisect --good 12
769 hg bisect --good 12
765 hg bisect --command "make && make tests"
770 hg bisect --command "make && make tests"
766
771
767 - see all changesets whose states are already known in the current
772 - see all changesets whose states are already known in the current
768 bisection::
773 bisection::
769
774
770 hg log -r "bisect(pruned)"
775 hg log -r "bisect(pruned)"
771
776
772 - see the changeset currently being bisected (especially useful
777 - see the changeset currently being bisected (especially useful
773 if running with -U/--noupdate)::
778 if running with -U/--noupdate)::
774
779
775 hg log -r "bisect(current)"
780 hg log -r "bisect(current)"
776
781
777 - see all changesets that took part in the current bisection::
782 - see all changesets that took part in the current bisection::
778
783
779 hg log -r "bisect(range)"
784 hg log -r "bisect(range)"
780
785
781 - you can even get a nice graph::
786 - you can even get a nice graph::
782
787
783 hg log --graph -r "bisect(range)"
788 hg log --graph -r "bisect(range)"
784
789
785 See :hg:`help revsets` for more about the `bisect()` keyword.
790 See :hg:`help revsets` for more about the `bisect()` keyword.
786
791
787 Returns 0 on success.
792 Returns 0 on success.
788 """
793 """
789 def extendbisectrange(nodes, good):
794 def extendbisectrange(nodes, good):
790 # bisect is incomplete when it ends on a merge node and
795 # bisect is incomplete when it ends on a merge node and
791 # one of the parent was not checked.
796 # one of the parent was not checked.
792 parents = repo[nodes[0]].parents()
797 parents = repo[nodes[0]].parents()
793 if len(parents) > 1:
798 if len(parents) > 1:
794 if good:
799 if good:
795 side = state['bad']
800 side = state['bad']
796 else:
801 else:
797 side = state['good']
802 side = state['good']
798 num = len(set(i.node() for i in parents) & set(side))
803 num = len(set(i.node() for i in parents) & set(side))
799 if num == 1:
804 if num == 1:
800 return parents[0].ancestor(parents[1])
805 return parents[0].ancestor(parents[1])
801 return None
806 return None
802
807
803 def print_result(nodes, good):
808 def print_result(nodes, good):
804 displayer = cmdutil.show_changeset(ui, repo, {})
809 displayer = cmdutil.show_changeset(ui, repo, {})
805 if len(nodes) == 1:
810 if len(nodes) == 1:
806 # narrowed it down to a single revision
811 # narrowed it down to a single revision
807 if good:
812 if good:
808 ui.write(_("The first good revision is:\n"))
813 ui.write(_("The first good revision is:\n"))
809 else:
814 else:
810 ui.write(_("The first bad revision is:\n"))
815 ui.write(_("The first bad revision is:\n"))
811 displayer.show(repo[nodes[0]])
816 displayer.show(repo[nodes[0]])
812 extendnode = extendbisectrange(nodes, good)
817 extendnode = extendbisectrange(nodes, good)
813 if extendnode is not None:
818 if extendnode is not None:
814 ui.write(_('Not all ancestors of this changeset have been'
819 ui.write(_('Not all ancestors of this changeset have been'
815 ' checked.\nUse bisect --extend to continue the '
820 ' checked.\nUse bisect --extend to continue the '
816 'bisection from\nthe common ancestor, %s.\n')
821 'bisection from\nthe common ancestor, %s.\n')
817 % extendnode)
822 % extendnode)
818 else:
823 else:
819 # multiple possible revisions
824 # multiple possible revisions
820 if good:
825 if good:
821 ui.write(_("Due to skipped revisions, the first "
826 ui.write(_("Due to skipped revisions, the first "
822 "good revision could be any of:\n"))
827 "good revision could be any of:\n"))
823 else:
828 else:
824 ui.write(_("Due to skipped revisions, the first "
829 ui.write(_("Due to skipped revisions, the first "
825 "bad revision could be any of:\n"))
830 "bad revision could be any of:\n"))
826 for n in nodes:
831 for n in nodes:
827 displayer.show(repo[n])
832 displayer.show(repo[n])
828 displayer.close()
833 displayer.close()
829
834
830 def check_state(state, interactive=True):
835 def check_state(state, interactive=True):
831 if not state['good'] or not state['bad']:
836 if not state['good'] or not state['bad']:
832 if (good or bad or skip or reset) and interactive:
837 if (good or bad or skip or reset) and interactive:
833 return
838 return
834 if not state['good']:
839 if not state['good']:
835 raise error.Abort(_('cannot bisect (no known good revisions)'))
840 raise error.Abort(_('cannot bisect (no known good revisions)'))
836 else:
841 else:
837 raise error.Abort(_('cannot bisect (no known bad revisions)'))
842 raise error.Abort(_('cannot bisect (no known bad revisions)'))
838 return True
843 return True
839
844
840 # backward compatibility
845 # backward compatibility
841 if rev in "good bad reset init".split():
846 if rev in "good bad reset init".split():
842 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
847 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
843 cmd, rev, extra = rev, extra, None
848 cmd, rev, extra = rev, extra, None
844 if cmd == "good":
849 if cmd == "good":
845 good = True
850 good = True
846 elif cmd == "bad":
851 elif cmd == "bad":
847 bad = True
852 bad = True
848 else:
853 else:
849 reset = True
854 reset = True
850 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
855 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
851 raise error.Abort(_('incompatible arguments'))
856 raise error.Abort(_('incompatible arguments'))
852
857
853 cmdutil.checkunfinished(repo)
858 cmdutil.checkunfinished(repo)
854
859
855 if reset:
860 if reset:
856 p = repo.join("bisect.state")
861 p = repo.join("bisect.state")
857 if os.path.exists(p):
862 if os.path.exists(p):
858 os.unlink(p)
863 os.unlink(p)
859 return
864 return
860
865
861 state = hbisect.load_state(repo)
866 state = hbisect.load_state(repo)
862
867
863 if command:
868 if command:
864 changesets = 1
869 changesets = 1
865 if noupdate:
870 if noupdate:
866 try:
871 try:
867 node = state['current'][0]
872 node = state['current'][0]
868 except LookupError:
873 except LookupError:
869 raise error.Abort(_('current bisect revision is unknown - '
874 raise error.Abort(_('current bisect revision is unknown - '
870 'start a new bisect to fix'))
875 'start a new bisect to fix'))
871 else:
876 else:
872 node, p2 = repo.dirstate.parents()
877 node, p2 = repo.dirstate.parents()
873 if p2 != nullid:
878 if p2 != nullid:
874 raise error.Abort(_('current bisect revision is a merge'))
879 raise error.Abort(_('current bisect revision is a merge'))
875 try:
880 try:
876 while changesets:
881 while changesets:
877 # update state
882 # update state
878 state['current'] = [node]
883 state['current'] = [node]
879 hbisect.save_state(repo, state)
884 hbisect.save_state(repo, state)
880 status = ui.system(command, environ={'HG_NODE': hex(node)})
885 status = ui.system(command, environ={'HG_NODE': hex(node)})
881 if status == 125:
886 if status == 125:
882 transition = "skip"
887 transition = "skip"
883 elif status == 0:
888 elif status == 0:
884 transition = "good"
889 transition = "good"
885 # status < 0 means process was killed
890 # status < 0 means process was killed
886 elif status == 127:
891 elif status == 127:
887 raise error.Abort(_("failed to execute %s") % command)
892 raise error.Abort(_("failed to execute %s") % command)
888 elif status < 0:
893 elif status < 0:
889 raise error.Abort(_("%s killed") % command)
894 raise error.Abort(_("%s killed") % command)
890 else:
895 else:
891 transition = "bad"
896 transition = "bad"
892 ctx = scmutil.revsingle(repo, rev, node)
897 ctx = scmutil.revsingle(repo, rev, node)
893 rev = None # clear for future iterations
898 rev = None # clear for future iterations
894 state[transition].append(ctx.node())
899 state[transition].append(ctx.node())
895 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
900 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
896 check_state(state, interactive=False)
901 check_state(state, interactive=False)
897 # bisect
902 # bisect
898 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
903 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
899 # update to next check
904 # update to next check
900 node = nodes[0]
905 node = nodes[0]
901 if not noupdate:
906 if not noupdate:
902 cmdutil.bailifchanged(repo)
907 cmdutil.bailifchanged(repo)
903 hg.clean(repo, node, show_stats=False)
908 hg.clean(repo, node, show_stats=False)
904 finally:
909 finally:
905 state['current'] = [node]
910 state['current'] = [node]
906 hbisect.save_state(repo, state)
911 hbisect.save_state(repo, state)
907 print_result(nodes, bgood)
912 print_result(nodes, bgood)
908 return
913 return
909
914
910 # update state
915 # update state
911
916
912 if rev:
917 if rev:
913 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
918 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
914 else:
919 else:
915 nodes = [repo.lookup('.')]
920 nodes = [repo.lookup('.')]
916
921
917 if good or bad or skip:
922 if good or bad or skip:
918 if good:
923 if good:
919 state['good'] += nodes
924 state['good'] += nodes
920 elif bad:
925 elif bad:
921 state['bad'] += nodes
926 state['bad'] += nodes
922 elif skip:
927 elif skip:
923 state['skip'] += nodes
928 state['skip'] += nodes
924 hbisect.save_state(repo, state)
929 hbisect.save_state(repo, state)
925
930
926 if not check_state(state):
931 if not check_state(state):
927 return
932 return
928
933
929 # actually bisect
934 # actually bisect
930 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
935 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
931 if extend:
936 if extend:
932 if not changesets:
937 if not changesets:
933 extendnode = extendbisectrange(nodes, good)
938 extendnode = extendbisectrange(nodes, good)
934 if extendnode is not None:
939 if extendnode is not None:
935 ui.write(_("Extending search to changeset %d:%s\n")
940 ui.write(_("Extending search to changeset %d:%s\n")
936 % (extendnode.rev(), extendnode))
941 % (extendnode.rev(), extendnode))
937 state['current'] = [extendnode.node()]
942 state['current'] = [extendnode.node()]
938 hbisect.save_state(repo, state)
943 hbisect.save_state(repo, state)
939 if noupdate:
944 if noupdate:
940 return
945 return
941 cmdutil.bailifchanged(repo)
946 cmdutil.bailifchanged(repo)
942 return hg.clean(repo, extendnode.node())
947 return hg.clean(repo, extendnode.node())
943 raise error.Abort(_("nothing to extend"))
948 raise error.Abort(_("nothing to extend"))
944
949
945 if changesets == 0:
950 if changesets == 0:
946 print_result(nodes, good)
951 print_result(nodes, good)
947 else:
952 else:
948 assert len(nodes) == 1 # only a single node can be tested next
953 assert len(nodes) == 1 # only a single node can be tested next
949 node = nodes[0]
954 node = nodes[0]
950 # compute the approximate number of remaining tests
955 # compute the approximate number of remaining tests
951 tests, size = 0, 2
956 tests, size = 0, 2
952 while size <= changesets:
957 while size <= changesets:
953 tests, size = tests + 1, size * 2
958 tests, size = tests + 1, size * 2
954 rev = repo.changelog.rev(node)
959 rev = repo.changelog.rev(node)
955 ui.write(_("Testing changeset %d:%s "
960 ui.write(_("Testing changeset %d:%s "
956 "(%d changesets remaining, ~%d tests)\n")
961 "(%d changesets remaining, ~%d tests)\n")
957 % (rev, short(node), changesets, tests))
962 % (rev, short(node), changesets, tests))
958 state['current'] = [node]
963 state['current'] = [node]
959 hbisect.save_state(repo, state)
964 hbisect.save_state(repo, state)
960 if not noupdate:
965 if not noupdate:
961 cmdutil.bailifchanged(repo)
966 cmdutil.bailifchanged(repo)
962 return hg.clean(repo, node)
967 return hg.clean(repo, node)
963
968
964 @command('bookmarks|bookmark',
969 @command('bookmarks|bookmark',
965 [('f', 'force', False, _('force')),
970 [('f', 'force', False, _('force')),
966 ('r', 'rev', '', _('revision'), _('REV')),
971 ('r', 'rev', '', _('revision'), _('REV')),
967 ('d', 'delete', False, _('delete a given bookmark')),
972 ('d', 'delete', False, _('delete a given bookmark')),
968 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
973 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
969 ('i', 'inactive', False, _('mark a bookmark inactive')),
974 ('i', 'inactive', False, _('mark a bookmark inactive')),
970 ] + formatteropts,
975 ] + formatteropts,
971 _('hg bookmarks [OPTIONS]... [NAME]...'))
976 _('hg bookmarks [OPTIONS]... [NAME]...'))
972 def bookmark(ui, repo, *names, **opts):
977 def bookmark(ui, repo, *names, **opts):
973 '''create a new bookmark or list existing bookmarks
978 '''create a new bookmark or list existing bookmarks
974
979
975 Bookmarks are labels on changesets to help track lines of development.
980 Bookmarks are labels on changesets to help track lines of development.
976 Bookmarks are unversioned and can be moved, renamed and deleted.
981 Bookmarks are unversioned and can be moved, renamed and deleted.
977 Deleting or moving a bookmark has no effect on the associated changesets.
982 Deleting or moving a bookmark has no effect on the associated changesets.
978
983
979 Creating or updating to a bookmark causes it to be marked as 'active'.
984 Creating or updating to a bookmark causes it to be marked as 'active'.
980 The active bookmark is indicated with a '*'.
985 The active bookmark is indicated with a '*'.
981 When a commit is made, the active bookmark will advance to the new commit.
986 When a commit is made, the active bookmark will advance to the new commit.
982 A plain :hg:`update` will also advance an active bookmark, if possible.
987 A plain :hg:`update` will also advance an active bookmark, if possible.
983 Updating away from a bookmark will cause it to be deactivated.
988 Updating away from a bookmark will cause it to be deactivated.
984
989
985 Bookmarks can be pushed and pulled between repositories (see
990 Bookmarks can be pushed and pulled between repositories (see
986 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
991 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
987 diverged, a new 'divergent bookmark' of the form 'name@path' will
992 diverged, a new 'divergent bookmark' of the form 'name@path' will
988 be created. Using :hg:`merge` will resolve the divergence.
993 be created. Using :hg:`merge` will resolve the divergence.
989
994
990 A bookmark named '@' has the special property that :hg:`clone` will
995 A bookmark named '@' has the special property that :hg:`clone` will
991 check it out by default if it exists.
996 check it out by default if it exists.
992
997
993 .. container:: verbose
998 .. container:: verbose
994
999
995 Examples:
1000 Examples:
996
1001
997 - create an active bookmark for a new line of development::
1002 - create an active bookmark for a new line of development::
998
1003
999 hg book new-feature
1004 hg book new-feature
1000
1005
1001 - create an inactive bookmark as a place marker::
1006 - create an inactive bookmark as a place marker::
1002
1007
1003 hg book -i reviewed
1008 hg book -i reviewed
1004
1009
1005 - create an inactive bookmark on another changeset::
1010 - create an inactive bookmark on another changeset::
1006
1011
1007 hg book -r .^ tested
1012 hg book -r .^ tested
1008
1013
1009 - rename bookmark turkey to dinner::
1014 - rename bookmark turkey to dinner::
1010
1015
1011 hg book -m turkey dinner
1016 hg book -m turkey dinner
1012
1017
1013 - move the '@' bookmark from another branch::
1018 - move the '@' bookmark from another branch::
1014
1019
1015 hg book -f @
1020 hg book -f @
1016 '''
1021 '''
1017 force = opts.get('force')
1022 force = opts.get('force')
1018 rev = opts.get('rev')
1023 rev = opts.get('rev')
1019 delete = opts.get('delete')
1024 delete = opts.get('delete')
1020 rename = opts.get('rename')
1025 rename = opts.get('rename')
1021 inactive = opts.get('inactive')
1026 inactive = opts.get('inactive')
1022
1027
1023 def checkformat(mark):
1028 def checkformat(mark):
1024 mark = mark.strip()
1029 mark = mark.strip()
1025 if not mark:
1030 if not mark:
1026 raise error.Abort(_("bookmark names cannot consist entirely of "
1031 raise error.Abort(_("bookmark names cannot consist entirely of "
1027 "whitespace"))
1032 "whitespace"))
1028 scmutil.checknewlabel(repo, mark, 'bookmark')
1033 scmutil.checknewlabel(repo, mark, 'bookmark')
1029 return mark
1034 return mark
1030
1035
1031 def checkconflict(repo, mark, cur, force=False, target=None):
1036 def checkconflict(repo, mark, cur, force=False, target=None):
1032 if mark in marks and not force:
1037 if mark in marks and not force:
1033 if target:
1038 if target:
1034 if marks[mark] == target and target == cur:
1039 if marks[mark] == target and target == cur:
1035 # re-activating a bookmark
1040 # re-activating a bookmark
1036 return
1041 return
1037 anc = repo.changelog.ancestors([repo[target].rev()])
1042 anc = repo.changelog.ancestors([repo[target].rev()])
1038 bmctx = repo[marks[mark]]
1043 bmctx = repo[marks[mark]]
1039 divs = [repo[b].node() for b in marks
1044 divs = [repo[b].node() for b in marks
1040 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
1045 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
1041
1046
1042 # allow resolving a single divergent bookmark even if moving
1047 # allow resolving a single divergent bookmark even if moving
1043 # the bookmark across branches when a revision is specified
1048 # the bookmark across branches when a revision is specified
1044 # that contains a divergent bookmark
1049 # that contains a divergent bookmark
1045 if bmctx.rev() not in anc and target in divs:
1050 if bmctx.rev() not in anc and target in divs:
1046 bookmarks.deletedivergent(repo, [target], mark)
1051 bookmarks.deletedivergent(repo, [target], mark)
1047 return
1052 return
1048
1053
1049 deletefrom = [b for b in divs
1054 deletefrom = [b for b in divs
1050 if repo[b].rev() in anc or b == target]
1055 if repo[b].rev() in anc or b == target]
1051 bookmarks.deletedivergent(repo, deletefrom, mark)
1056 bookmarks.deletedivergent(repo, deletefrom, mark)
1052 if bookmarks.validdest(repo, bmctx, repo[target]):
1057 if bookmarks.validdest(repo, bmctx, repo[target]):
1053 ui.status(_("moving bookmark '%s' forward from %s\n") %
1058 ui.status(_("moving bookmark '%s' forward from %s\n") %
1054 (mark, short(bmctx.node())))
1059 (mark, short(bmctx.node())))
1055 return
1060 return
1056 raise error.Abort(_("bookmark '%s' already exists "
1061 raise error.Abort(_("bookmark '%s' already exists "
1057 "(use -f to force)") % mark)
1062 "(use -f to force)") % mark)
1058 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
1063 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
1059 and not force):
1064 and not force):
1060 raise error.Abort(
1065 raise error.Abort(
1061 _("a bookmark cannot have the name of an existing branch"))
1066 _("a bookmark cannot have the name of an existing branch"))
1062
1067
1063 if delete and rename:
1068 if delete and rename:
1064 raise error.Abort(_("--delete and --rename are incompatible"))
1069 raise error.Abort(_("--delete and --rename are incompatible"))
1065 if delete and rev:
1070 if delete and rev:
1066 raise error.Abort(_("--rev is incompatible with --delete"))
1071 raise error.Abort(_("--rev is incompatible with --delete"))
1067 if rename and rev:
1072 if rename and rev:
1068 raise error.Abort(_("--rev is incompatible with --rename"))
1073 raise error.Abort(_("--rev is incompatible with --rename"))
1069 if not names and (delete or rev):
1074 if not names and (delete or rev):
1070 raise error.Abort(_("bookmark name required"))
1075 raise error.Abort(_("bookmark name required"))
1071
1076
1072 if delete or rename or names or inactive:
1077 if delete or rename or names or inactive:
1073 wlock = lock = tr = None
1078 wlock = lock = tr = None
1074 try:
1079 try:
1075 wlock = repo.wlock()
1080 wlock = repo.wlock()
1076 lock = repo.lock()
1081 lock = repo.lock()
1077 cur = repo.changectx('.').node()
1082 cur = repo.changectx('.').node()
1078 marks = repo._bookmarks
1083 marks = repo._bookmarks
1079 if delete:
1084 if delete:
1080 tr = repo.transaction('bookmark')
1085 tr = repo.transaction('bookmark')
1081 for mark in names:
1086 for mark in names:
1082 if mark not in marks:
1087 if mark not in marks:
1083 raise error.Abort(_("bookmark '%s' does not exist") %
1088 raise error.Abort(_("bookmark '%s' does not exist") %
1084 mark)
1089 mark)
1085 if mark == repo._activebookmark:
1090 if mark == repo._activebookmark:
1086 bookmarks.deactivate(repo)
1091 bookmarks.deactivate(repo)
1087 del marks[mark]
1092 del marks[mark]
1088
1093
1089 elif rename:
1094 elif rename:
1090 tr = repo.transaction('bookmark')
1095 tr = repo.transaction('bookmark')
1091 if not names:
1096 if not names:
1092 raise error.Abort(_("new bookmark name required"))
1097 raise error.Abort(_("new bookmark name required"))
1093 elif len(names) > 1:
1098 elif len(names) > 1:
1094 raise error.Abort(_("only one new bookmark name allowed"))
1099 raise error.Abort(_("only one new bookmark name allowed"))
1095 mark = checkformat(names[0])
1100 mark = checkformat(names[0])
1096 if rename not in marks:
1101 if rename not in marks:
1097 raise error.Abort(_("bookmark '%s' does not exist")
1102 raise error.Abort(_("bookmark '%s' does not exist")
1098 % rename)
1103 % rename)
1099 checkconflict(repo, mark, cur, force)
1104 checkconflict(repo, mark, cur, force)
1100 marks[mark] = marks[rename]
1105 marks[mark] = marks[rename]
1101 if repo._activebookmark == rename and not inactive:
1106 if repo._activebookmark == rename and not inactive:
1102 bookmarks.activate(repo, mark)
1107 bookmarks.activate(repo, mark)
1103 del marks[rename]
1108 del marks[rename]
1104 elif names:
1109 elif names:
1105 tr = repo.transaction('bookmark')
1110 tr = repo.transaction('bookmark')
1106 newact = None
1111 newact = None
1107 for mark in names:
1112 for mark in names:
1108 mark = checkformat(mark)
1113 mark = checkformat(mark)
1109 if newact is None:
1114 if newact is None:
1110 newact = mark
1115 newact = mark
1111 if inactive and mark == repo._activebookmark:
1116 if inactive and mark == repo._activebookmark:
1112 bookmarks.deactivate(repo)
1117 bookmarks.deactivate(repo)
1113 return
1118 return
1114 tgt = cur
1119 tgt = cur
1115 if rev:
1120 if rev:
1116 tgt = scmutil.revsingle(repo, rev).node()
1121 tgt = scmutil.revsingle(repo, rev).node()
1117 checkconflict(repo, mark, cur, force, tgt)
1122 checkconflict(repo, mark, cur, force, tgt)
1118 marks[mark] = tgt
1123 marks[mark] = tgt
1119 if not inactive and cur == marks[newact] and not rev:
1124 if not inactive and cur == marks[newact] and not rev:
1120 bookmarks.activate(repo, newact)
1125 bookmarks.activate(repo, newact)
1121 elif cur != tgt and newact == repo._activebookmark:
1126 elif cur != tgt and newact == repo._activebookmark:
1122 bookmarks.deactivate(repo)
1127 bookmarks.deactivate(repo)
1123 elif inactive:
1128 elif inactive:
1124 if len(marks) == 0:
1129 if len(marks) == 0:
1125 ui.status(_("no bookmarks set\n"))
1130 ui.status(_("no bookmarks set\n"))
1126 elif not repo._activebookmark:
1131 elif not repo._activebookmark:
1127 ui.status(_("no active bookmark\n"))
1132 ui.status(_("no active bookmark\n"))
1128 else:
1133 else:
1129 bookmarks.deactivate(repo)
1134 bookmarks.deactivate(repo)
1130 if tr is not None:
1135 if tr is not None:
1131 marks.recordchange(tr)
1136 marks.recordchange(tr)
1132 tr.close()
1137 tr.close()
1133 finally:
1138 finally:
1134 lockmod.release(tr, lock, wlock)
1139 lockmod.release(tr, lock, wlock)
1135 else: # show bookmarks
1140 else: # show bookmarks
1136 fm = ui.formatter('bookmarks', opts)
1141 fm = ui.formatter('bookmarks', opts)
1137 hexfn = fm.hexfunc
1142 hexfn = fm.hexfunc
1138 marks = repo._bookmarks
1143 marks = repo._bookmarks
1139 if len(marks) == 0 and not fm:
1144 if len(marks) == 0 and not fm:
1140 ui.status(_("no bookmarks set\n"))
1145 ui.status(_("no bookmarks set\n"))
1141 for bmark, n in sorted(marks.iteritems()):
1146 for bmark, n in sorted(marks.iteritems()):
1142 active = repo._activebookmark
1147 active = repo._activebookmark
1143 if bmark == active:
1148 if bmark == active:
1144 prefix, label = '*', activebookmarklabel
1149 prefix, label = '*', activebookmarklabel
1145 else:
1150 else:
1146 prefix, label = ' ', ''
1151 prefix, label = ' ', ''
1147
1152
1148 fm.startitem()
1153 fm.startitem()
1149 if not ui.quiet:
1154 if not ui.quiet:
1150 fm.plain(' %s ' % prefix, label=label)
1155 fm.plain(' %s ' % prefix, label=label)
1151 fm.write('bookmark', '%s', bmark, label=label)
1156 fm.write('bookmark', '%s', bmark, label=label)
1152 pad = " " * (25 - encoding.colwidth(bmark))
1157 pad = " " * (25 - encoding.colwidth(bmark))
1153 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1158 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1154 repo.changelog.rev(n), hexfn(n), label=label)
1159 repo.changelog.rev(n), hexfn(n), label=label)
1155 fm.data(active=(bmark == active))
1160 fm.data(active=(bmark == active))
1156 fm.plain('\n')
1161 fm.plain('\n')
1157 fm.end()
1162 fm.end()
1158
1163
1159 @command('branch',
1164 @command('branch',
1160 [('f', 'force', None,
1165 [('f', 'force', None,
1161 _('set branch name even if it shadows an existing branch')),
1166 _('set branch name even if it shadows an existing branch')),
1162 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1167 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1163 _('[-fC] [NAME]'))
1168 _('[-fC] [NAME]'))
1164 def branch(ui, repo, label=None, **opts):
1169 def branch(ui, repo, label=None, **opts):
1165 """set or show the current branch name
1170 """set or show the current branch name
1166
1171
1167 .. note::
1172 .. note::
1168
1173
1169 Branch names are permanent and global. Use :hg:`bookmark` to create a
1174 Branch names are permanent and global. Use :hg:`bookmark` to create a
1170 light-weight bookmark instead. See :hg:`help glossary` for more
1175 light-weight bookmark instead. See :hg:`help glossary` for more
1171 information about named branches and bookmarks.
1176 information about named branches and bookmarks.
1172
1177
1173 With no argument, show the current branch name. With one argument,
1178 With no argument, show the current branch name. With one argument,
1174 set the working directory branch name (the branch will not exist
1179 set the working directory branch name (the branch will not exist
1175 in the repository until the next commit). Standard practice
1180 in the repository until the next commit). Standard practice
1176 recommends that primary development take place on the 'default'
1181 recommends that primary development take place on the 'default'
1177 branch.
1182 branch.
1178
1183
1179 Unless -f/--force is specified, branch will not let you set a
1184 Unless -f/--force is specified, branch will not let you set a
1180 branch name that already exists.
1185 branch name that already exists.
1181
1186
1182 Use -C/--clean to reset the working directory branch to that of
1187 Use -C/--clean to reset the working directory branch to that of
1183 the parent of the working directory, negating a previous branch
1188 the parent of the working directory, negating a previous branch
1184 change.
1189 change.
1185
1190
1186 Use the command :hg:`update` to switch to an existing branch. Use
1191 Use the command :hg:`update` to switch to an existing branch. Use
1187 :hg:`commit --close-branch` to mark this branch head as closed.
1192 :hg:`commit --close-branch` to mark this branch head as closed.
1188 When all heads of a branch are closed, the branch will be
1193 When all heads of a branch are closed, the branch will be
1189 considered closed.
1194 considered closed.
1190
1195
1191 Returns 0 on success.
1196 Returns 0 on success.
1192 """
1197 """
1193 if label:
1198 if label:
1194 label = label.strip()
1199 label = label.strip()
1195
1200
1196 if not opts.get('clean') and not label:
1201 if not opts.get('clean') and not label:
1197 ui.write("%s\n" % repo.dirstate.branch())
1202 ui.write("%s\n" % repo.dirstate.branch())
1198 return
1203 return
1199
1204
1200 with repo.wlock():
1205 with repo.wlock():
1201 if opts.get('clean'):
1206 if opts.get('clean'):
1202 label = repo[None].p1().branch()
1207 label = repo[None].p1().branch()
1203 repo.dirstate.setbranch(label)
1208 repo.dirstate.setbranch(label)
1204 ui.status(_('reset working directory to branch %s\n') % label)
1209 ui.status(_('reset working directory to branch %s\n') % label)
1205 elif label:
1210 elif label:
1206 if not opts.get('force') and label in repo.branchmap():
1211 if not opts.get('force') and label in repo.branchmap():
1207 if label not in [p.branch() for p in repo[None].parents()]:
1212 if label not in [p.branch() for p in repo[None].parents()]:
1208 raise error.Abort(_('a branch of the same name already'
1213 raise error.Abort(_('a branch of the same name already'
1209 ' exists'),
1214 ' exists'),
1210 # i18n: "it" refers to an existing branch
1215 # i18n: "it" refers to an existing branch
1211 hint=_("use 'hg update' to switch to it"))
1216 hint=_("use 'hg update' to switch to it"))
1212 scmutil.checknewlabel(repo, label, 'branch')
1217 scmutil.checknewlabel(repo, label, 'branch')
1213 repo.dirstate.setbranch(label)
1218 repo.dirstate.setbranch(label)
1214 ui.status(_('marked working directory as branch %s\n') % label)
1219 ui.status(_('marked working directory as branch %s\n') % label)
1215
1220
1216 # find any open named branches aside from default
1221 # find any open named branches aside from default
1217 others = [n for n, h, t, c in repo.branchmap().iterbranches()
1222 others = [n for n, h, t, c in repo.branchmap().iterbranches()
1218 if n != "default" and not c]
1223 if n != "default" and not c]
1219 if not others:
1224 if not others:
1220 ui.status(_('(branches are permanent and global, '
1225 ui.status(_('(branches are permanent and global, '
1221 'did you want a bookmark?)\n'))
1226 'did you want a bookmark?)\n'))
1222
1227
1223 @command('branches',
1228 @command('branches',
1224 [('a', 'active', False,
1229 [('a', 'active', False,
1225 _('show only branches that have unmerged heads (DEPRECATED)')),
1230 _('show only branches that have unmerged heads (DEPRECATED)')),
1226 ('c', 'closed', False, _('show normal and closed branches')),
1231 ('c', 'closed', False, _('show normal and closed branches')),
1227 ] + formatteropts,
1232 ] + formatteropts,
1228 _('[-ac]'))
1233 _('[-ac]'))
1229 def branches(ui, repo, active=False, closed=False, **opts):
1234 def branches(ui, repo, active=False, closed=False, **opts):
1230 """list repository named branches
1235 """list repository named branches
1231
1236
1232 List the repository's named branches, indicating which ones are
1237 List the repository's named branches, indicating which ones are
1233 inactive. If -c/--closed is specified, also list branches which have
1238 inactive. If -c/--closed is specified, also list branches which have
1234 been marked closed (see :hg:`commit --close-branch`).
1239 been marked closed (see :hg:`commit --close-branch`).
1235
1240
1236 Use the command :hg:`update` to switch to an existing branch.
1241 Use the command :hg:`update` to switch to an existing branch.
1237
1242
1238 Returns 0.
1243 Returns 0.
1239 """
1244 """
1240
1245
1241 fm = ui.formatter('branches', opts)
1246 fm = ui.formatter('branches', opts)
1242 hexfunc = fm.hexfunc
1247 hexfunc = fm.hexfunc
1243
1248
1244 allheads = set(repo.heads())
1249 allheads = set(repo.heads())
1245 branches = []
1250 branches = []
1246 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1251 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1247 isactive = not isclosed and bool(set(heads) & allheads)
1252 isactive = not isclosed and bool(set(heads) & allheads)
1248 branches.append((tag, repo[tip], isactive, not isclosed))
1253 branches.append((tag, repo[tip], isactive, not isclosed))
1249 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1254 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1250 reverse=True)
1255 reverse=True)
1251
1256
1252 for tag, ctx, isactive, isopen in branches:
1257 for tag, ctx, isactive, isopen in branches:
1253 if active and not isactive:
1258 if active and not isactive:
1254 continue
1259 continue
1255 if isactive:
1260 if isactive:
1256 label = 'branches.active'
1261 label = 'branches.active'
1257 notice = ''
1262 notice = ''
1258 elif not isopen:
1263 elif not isopen:
1259 if not closed:
1264 if not closed:
1260 continue
1265 continue
1261 label = 'branches.closed'
1266 label = 'branches.closed'
1262 notice = _(' (closed)')
1267 notice = _(' (closed)')
1263 else:
1268 else:
1264 label = 'branches.inactive'
1269 label = 'branches.inactive'
1265 notice = _(' (inactive)')
1270 notice = _(' (inactive)')
1266 current = (tag == repo.dirstate.branch())
1271 current = (tag == repo.dirstate.branch())
1267 if current:
1272 if current:
1268 label = 'branches.current'
1273 label = 'branches.current'
1269
1274
1270 fm.startitem()
1275 fm.startitem()
1271 fm.write('branch', '%s', tag, label=label)
1276 fm.write('branch', '%s', tag, label=label)
1272 rev = ctx.rev()
1277 rev = ctx.rev()
1273 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1278 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1274 fmt = ' ' * padsize + ' %d:%s'
1279 fmt = ' ' * padsize + ' %d:%s'
1275 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1280 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1276 label='log.changeset changeset.%s' % ctx.phasestr())
1281 label='log.changeset changeset.%s' % ctx.phasestr())
1277 fm.data(active=isactive, closed=not isopen, current=current)
1282 fm.data(active=isactive, closed=not isopen, current=current)
1278 if not ui.quiet:
1283 if not ui.quiet:
1279 fm.plain(notice)
1284 fm.plain(notice)
1280 fm.plain('\n')
1285 fm.plain('\n')
1281 fm.end()
1286 fm.end()
1282
1287
1283 @command('bundle',
1288 @command('bundle',
1284 [('f', 'force', None, _('run even when the destination is unrelated')),
1289 [('f', 'force', None, _('run even when the destination is unrelated')),
1285 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1290 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1286 _('REV')),
1291 _('REV')),
1287 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1292 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1288 _('BRANCH')),
1293 _('BRANCH')),
1289 ('', 'base', [],
1294 ('', 'base', [],
1290 _('a base changeset assumed to be available at the destination'),
1295 _('a base changeset assumed to be available at the destination'),
1291 _('REV')),
1296 _('REV')),
1292 ('a', 'all', None, _('bundle all changesets in the repository')),
1297 ('a', 'all', None, _('bundle all changesets in the repository')),
1293 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1298 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1294 ] + remoteopts,
1299 ] + remoteopts,
1295 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1300 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1296 def bundle(ui, repo, fname, dest=None, **opts):
1301 def bundle(ui, repo, fname, dest=None, **opts):
1297 """create a changegroup file
1302 """create a changegroup file
1298
1303
1299 Generate a changegroup file collecting changesets to be added
1304 Generate a changegroup file collecting changesets to be added
1300 to a repository.
1305 to a repository.
1301
1306
1302 To create a bundle containing all changesets, use -a/--all
1307 To create a bundle containing all changesets, use -a/--all
1303 (or --base null). Otherwise, hg assumes the destination will have
1308 (or --base null). Otherwise, hg assumes the destination will have
1304 all the nodes you specify with --base parameters. Otherwise, hg
1309 all the nodes you specify with --base parameters. Otherwise, hg
1305 will assume the repository has all the nodes in destination, or
1310 will assume the repository has all the nodes in destination, or
1306 default-push/default if no destination is specified.
1311 default-push/default if no destination is specified.
1307
1312
1308 You can change bundle format with the -t/--type option. You can
1313 You can change bundle format with the -t/--type option. You can
1309 specify a compression, a bundle version or both using a dash
1314 specify a compression, a bundle version or both using a dash
1310 (comp-version). The available compression methods are: none, bzip2,
1315 (comp-version). The available compression methods are: none, bzip2,
1311 and gzip (by default, bundles are compressed using bzip2). The
1316 and gzip (by default, bundles are compressed using bzip2). The
1312 available formats are: v1, v2 (default to most suitable).
1317 available formats are: v1, v2 (default to most suitable).
1313
1318
1314 The bundle file can then be transferred using conventional means
1319 The bundle file can then be transferred using conventional means
1315 and applied to another repository with the unbundle or pull
1320 and applied to another repository with the unbundle or pull
1316 command. This is useful when direct push and pull are not
1321 command. This is useful when direct push and pull are not
1317 available or when exporting an entire repository is undesirable.
1322 available or when exporting an entire repository is undesirable.
1318
1323
1319 Applying bundles preserves all changeset contents including
1324 Applying bundles preserves all changeset contents including
1320 permissions, copy/rename information, and revision history.
1325 permissions, copy/rename information, and revision history.
1321
1326
1322 Returns 0 on success, 1 if no changes found.
1327 Returns 0 on success, 1 if no changes found.
1323 """
1328 """
1324 revs = None
1329 revs = None
1325 if 'rev' in opts:
1330 if 'rev' in opts:
1326 revs = scmutil.revrange(repo, opts['rev'])
1331 revs = scmutil.revrange(repo, opts['rev'])
1327
1332
1328 bundletype = opts.get('type', 'bzip2').lower()
1333 bundletype = opts.get('type', 'bzip2').lower()
1329 try:
1334 try:
1330 bcompression, cgversion, params = exchange.parsebundlespec(
1335 bcompression, cgversion, params = exchange.parsebundlespec(
1331 repo, bundletype, strict=False)
1336 repo, bundletype, strict=False)
1332 except error.UnsupportedBundleSpecification as e:
1337 except error.UnsupportedBundleSpecification as e:
1333 raise error.Abort(str(e),
1338 raise error.Abort(str(e),
1334 hint=_('see "hg help bundle" for supported '
1339 hint=_('see "hg help bundle" for supported '
1335 'values for --type'))
1340 'values for --type'))
1336
1341
1337 # Packed bundles are a pseudo bundle format for now.
1342 # Packed bundles are a pseudo bundle format for now.
1338 if cgversion == 's1':
1343 if cgversion == 's1':
1339 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1344 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1340 hint=_('use "hg debugcreatestreamclonebundle"'))
1345 hint=_('use "hg debugcreatestreamclonebundle"'))
1341
1346
1342 if opts.get('all'):
1347 if opts.get('all'):
1343 if dest:
1348 if dest:
1344 raise error.Abort(_("--all is incompatible with specifying "
1349 raise error.Abort(_("--all is incompatible with specifying "
1345 "a destination"))
1350 "a destination"))
1346 if opts.get('base'):
1351 if opts.get('base'):
1347 ui.warn(_("ignoring --base because --all was specified\n"))
1352 ui.warn(_("ignoring --base because --all was specified\n"))
1348 base = ['null']
1353 base = ['null']
1349 else:
1354 else:
1350 base = scmutil.revrange(repo, opts.get('base'))
1355 base = scmutil.revrange(repo, opts.get('base'))
1351 # TODO: get desired bundlecaps from command line.
1356 # TODO: get desired bundlecaps from command line.
1352 bundlecaps = None
1357 bundlecaps = None
1353 if base:
1358 if base:
1354 if dest:
1359 if dest:
1355 raise error.Abort(_("--base is incompatible with specifying "
1360 raise error.Abort(_("--base is incompatible with specifying "
1356 "a destination"))
1361 "a destination"))
1357 common = [repo.lookup(rev) for rev in base]
1362 common = [repo.lookup(rev) for rev in base]
1358 heads = revs and map(repo.lookup, revs) or revs
1363 heads = revs and map(repo.lookup, revs) or revs
1359 cg = changegroup.getchangegroup(repo, 'bundle', heads=heads,
1364 cg = changegroup.getchangegroup(repo, 'bundle', heads=heads,
1360 common=common, bundlecaps=bundlecaps,
1365 common=common, bundlecaps=bundlecaps,
1361 version=cgversion)
1366 version=cgversion)
1362 outgoing = None
1367 outgoing = None
1363 else:
1368 else:
1364 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1369 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1365 dest, branches = hg.parseurl(dest, opts.get('branch'))
1370 dest, branches = hg.parseurl(dest, opts.get('branch'))
1366 other = hg.peer(repo, opts, dest)
1371 other = hg.peer(repo, opts, dest)
1367 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1372 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1368 heads = revs and map(repo.lookup, revs) or revs
1373 heads = revs and map(repo.lookup, revs) or revs
1369 outgoing = discovery.findcommonoutgoing(repo, other,
1374 outgoing = discovery.findcommonoutgoing(repo, other,
1370 onlyheads=heads,
1375 onlyheads=heads,
1371 force=opts.get('force'),
1376 force=opts.get('force'),
1372 portable=True)
1377 portable=True)
1373 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1378 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1374 bundlecaps, version=cgversion)
1379 bundlecaps, version=cgversion)
1375 if not cg:
1380 if not cg:
1376 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1381 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1377 return 1
1382 return 1
1378
1383
1379 if cgversion == '01': #bundle1
1384 if cgversion == '01': #bundle1
1380 if bcompression is None:
1385 if bcompression is None:
1381 bcompression = 'UN'
1386 bcompression = 'UN'
1382 bversion = 'HG10' + bcompression
1387 bversion = 'HG10' + bcompression
1383 bcompression = None
1388 bcompression = None
1384 else:
1389 else:
1385 assert cgversion == '02'
1390 assert cgversion == '02'
1386 bversion = 'HG20'
1391 bversion = 'HG20'
1387
1392
1388
1393
1389 changegroup.writebundle(ui, cg, fname, bversion, compression=bcompression)
1394 changegroup.writebundle(ui, cg, fname, bversion, compression=bcompression)
1390
1395
1391 @command('cat',
1396 @command('cat',
1392 [('o', 'output', '',
1397 [('o', 'output', '',
1393 _('print output to file with formatted name'), _('FORMAT')),
1398 _('print output to file with formatted name'), _('FORMAT')),
1394 ('r', 'rev', '', _('print the given revision'), _('REV')),
1399 ('r', 'rev', '', _('print the given revision'), _('REV')),
1395 ('', 'decode', None, _('apply any matching decode filter')),
1400 ('', 'decode', None, _('apply any matching decode filter')),
1396 ] + walkopts,
1401 ] + walkopts,
1397 _('[OPTION]... FILE...'),
1402 _('[OPTION]... FILE...'),
1398 inferrepo=True)
1403 inferrepo=True)
1399 def cat(ui, repo, file1, *pats, **opts):
1404 def cat(ui, repo, file1, *pats, **opts):
1400 """output the current or given revision of files
1405 """output the current or given revision of files
1401
1406
1402 Print the specified files as they were at the given revision. If
1407 Print the specified files as they were at the given revision. If
1403 no revision is given, the parent of the working directory is used.
1408 no revision is given, the parent of the working directory is used.
1404
1409
1405 Output may be to a file, in which case the name of the file is
1410 Output may be to a file, in which case the name of the file is
1406 given using a format string. The formatting rules as follows:
1411 given using a format string. The formatting rules as follows:
1407
1412
1408 :``%%``: literal "%" character
1413 :``%%``: literal "%" character
1409 :``%s``: basename of file being printed
1414 :``%s``: basename of file being printed
1410 :``%d``: dirname of file being printed, or '.' if in repository root
1415 :``%d``: dirname of file being printed, or '.' if in repository root
1411 :``%p``: root-relative path name of file being printed
1416 :``%p``: root-relative path name of file being printed
1412 :``%H``: changeset hash (40 hexadecimal digits)
1417 :``%H``: changeset hash (40 hexadecimal digits)
1413 :``%R``: changeset revision number
1418 :``%R``: changeset revision number
1414 :``%h``: short-form changeset hash (12 hexadecimal digits)
1419 :``%h``: short-form changeset hash (12 hexadecimal digits)
1415 :``%r``: zero-padded changeset revision number
1420 :``%r``: zero-padded changeset revision number
1416 :``%b``: basename of the exporting repository
1421 :``%b``: basename of the exporting repository
1417
1422
1418 Returns 0 on success.
1423 Returns 0 on success.
1419 """
1424 """
1420 ctx = scmutil.revsingle(repo, opts.get('rev'))
1425 ctx = scmutil.revsingle(repo, opts.get('rev'))
1421 m = scmutil.match(ctx, (file1,) + pats, opts)
1426 m = scmutil.match(ctx, (file1,) + pats, opts)
1422
1427
1423 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1428 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1424
1429
1425 @command('^clone',
1430 @command('^clone',
1426 [('U', 'noupdate', None, _('the clone will include an empty working '
1431 [('U', 'noupdate', None, _('the clone will include an empty working '
1427 'directory (only a repository)')),
1432 'directory (only a repository)')),
1428 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1433 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1429 _('REV')),
1434 _('REV')),
1430 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1435 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1431 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1436 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1432 ('', 'pull', None, _('use pull protocol to copy metadata')),
1437 ('', 'pull', None, _('use pull protocol to copy metadata')),
1433 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1438 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1434 ] + remoteopts,
1439 ] + remoteopts,
1435 _('[OPTION]... SOURCE [DEST]'),
1440 _('[OPTION]... SOURCE [DEST]'),
1436 norepo=True)
1441 norepo=True)
1437 def clone(ui, source, dest=None, **opts):
1442 def clone(ui, source, dest=None, **opts):
1438 """make a copy of an existing repository
1443 """make a copy of an existing repository
1439
1444
1440 Create a copy of an existing repository in a new directory.
1445 Create a copy of an existing repository in a new directory.
1441
1446
1442 If no destination directory name is specified, it defaults to the
1447 If no destination directory name is specified, it defaults to the
1443 basename of the source.
1448 basename of the source.
1444
1449
1445 The location of the source is added to the new repository's
1450 The location of the source is added to the new repository's
1446 ``.hg/hgrc`` file, as the default to be used for future pulls.
1451 ``.hg/hgrc`` file, as the default to be used for future pulls.
1447
1452
1448 Only local paths and ``ssh://`` URLs are supported as
1453 Only local paths and ``ssh://`` URLs are supported as
1449 destinations. For ``ssh://`` destinations, no working directory or
1454 destinations. For ``ssh://`` destinations, no working directory or
1450 ``.hg/hgrc`` will be created on the remote side.
1455 ``.hg/hgrc`` will be created on the remote side.
1451
1456
1452 If the source repository has a bookmark called '@' set, that
1457 If the source repository has a bookmark called '@' set, that
1453 revision will be checked out in the new repository by default.
1458 revision will be checked out in the new repository by default.
1454
1459
1455 To check out a particular version, use -u/--update, or
1460 To check out a particular version, use -u/--update, or
1456 -U/--noupdate to create a clone with no working directory.
1461 -U/--noupdate to create a clone with no working directory.
1457
1462
1458 To pull only a subset of changesets, specify one or more revisions
1463 To pull only a subset of changesets, specify one or more revisions
1459 identifiers with -r/--rev or branches with -b/--branch. The
1464 identifiers with -r/--rev or branches with -b/--branch. The
1460 resulting clone will contain only the specified changesets and
1465 resulting clone will contain only the specified changesets and
1461 their ancestors. These options (or 'clone src#rev dest') imply
1466 their ancestors. These options (or 'clone src#rev dest') imply
1462 --pull, even for local source repositories.
1467 --pull, even for local source repositories.
1463
1468
1464 .. note::
1469 .. note::
1465
1470
1466 Specifying a tag will include the tagged changeset but not the
1471 Specifying a tag will include the tagged changeset but not the
1467 changeset containing the tag.
1472 changeset containing the tag.
1468
1473
1469 .. container:: verbose
1474 .. container:: verbose
1470
1475
1471 For efficiency, hardlinks are used for cloning whenever the
1476 For efficiency, hardlinks are used for cloning whenever the
1472 source and destination are on the same filesystem (note this
1477 source and destination are on the same filesystem (note this
1473 applies only to the repository data, not to the working
1478 applies only to the repository data, not to the working
1474 directory). Some filesystems, such as AFS, implement hardlinking
1479 directory). Some filesystems, such as AFS, implement hardlinking
1475 incorrectly, but do not report errors. In these cases, use the
1480 incorrectly, but do not report errors. In these cases, use the
1476 --pull option to avoid hardlinking.
1481 --pull option to avoid hardlinking.
1477
1482
1478 In some cases, you can clone repositories and the working
1483 In some cases, you can clone repositories and the working
1479 directory using full hardlinks with ::
1484 directory using full hardlinks with ::
1480
1485
1481 $ cp -al REPO REPOCLONE
1486 $ cp -al REPO REPOCLONE
1482
1487
1483 This is the fastest way to clone, but it is not always safe. The
1488 This is the fastest way to clone, but it is not always safe. The
1484 operation is not atomic (making sure REPO is not modified during
1489 operation is not atomic (making sure REPO is not modified during
1485 the operation is up to you) and you have to make sure your
1490 the operation is up to you) and you have to make sure your
1486 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1491 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1487 so). Also, this is not compatible with certain extensions that
1492 so). Also, this is not compatible with certain extensions that
1488 place their metadata under the .hg directory, such as mq.
1493 place their metadata under the .hg directory, such as mq.
1489
1494
1490 Mercurial will update the working directory to the first applicable
1495 Mercurial will update the working directory to the first applicable
1491 revision from this list:
1496 revision from this list:
1492
1497
1493 a) null if -U or the source repository has no changesets
1498 a) null if -U or the source repository has no changesets
1494 b) if -u . and the source repository is local, the first parent of
1499 b) if -u . and the source repository is local, the first parent of
1495 the source repository's working directory
1500 the source repository's working directory
1496 c) the changeset specified with -u (if a branch name, this means the
1501 c) the changeset specified with -u (if a branch name, this means the
1497 latest head of that branch)
1502 latest head of that branch)
1498 d) the changeset specified with -r
1503 d) the changeset specified with -r
1499 e) the tipmost head specified with -b
1504 e) the tipmost head specified with -b
1500 f) the tipmost head specified with the url#branch source syntax
1505 f) the tipmost head specified with the url#branch source syntax
1501 g) the revision marked with the '@' bookmark, if present
1506 g) the revision marked with the '@' bookmark, if present
1502 h) the tipmost head of the default branch
1507 h) the tipmost head of the default branch
1503 i) tip
1508 i) tip
1504
1509
1505 When cloning from servers that support it, Mercurial may fetch
1510 When cloning from servers that support it, Mercurial may fetch
1506 pre-generated data from a server-advertised URL. When this is done,
1511 pre-generated data from a server-advertised URL. When this is done,
1507 hooks operating on incoming changesets and changegroups may fire twice,
1512 hooks operating on incoming changesets and changegroups may fire twice,
1508 once for the bundle fetched from the URL and another for any additional
1513 once for the bundle fetched from the URL and another for any additional
1509 data not fetched from this URL. In addition, if an error occurs, the
1514 data not fetched from this URL. In addition, if an error occurs, the
1510 repository may be rolled back to a partial clone. This behavior may
1515 repository may be rolled back to a partial clone. This behavior may
1511 change in future releases. See :hg:`help -e clonebundles` for more.
1516 change in future releases. See :hg:`help -e clonebundles` for more.
1512
1517
1513 Examples:
1518 Examples:
1514
1519
1515 - clone a remote repository to a new directory named hg/::
1520 - clone a remote repository to a new directory named hg/::
1516
1521
1517 hg clone http://selenic.com/hg
1522 hg clone http://selenic.com/hg
1518
1523
1519 - create a lightweight local clone::
1524 - create a lightweight local clone::
1520
1525
1521 hg clone project/ project-feature/
1526 hg clone project/ project-feature/
1522
1527
1523 - clone from an absolute path on an ssh server (note double-slash)::
1528 - clone from an absolute path on an ssh server (note double-slash)::
1524
1529
1525 hg clone ssh://user@server//home/projects/alpha/
1530 hg clone ssh://user@server//home/projects/alpha/
1526
1531
1527 - do a high-speed clone over a LAN while checking out a
1532 - do a high-speed clone over a LAN while checking out a
1528 specified version::
1533 specified version::
1529
1534
1530 hg clone --uncompressed http://server/repo -u 1.5
1535 hg clone --uncompressed http://server/repo -u 1.5
1531
1536
1532 - create a repository without changesets after a particular revision::
1537 - create a repository without changesets after a particular revision::
1533
1538
1534 hg clone -r 04e544 experimental/ good/
1539 hg clone -r 04e544 experimental/ good/
1535
1540
1536 - clone (and track) a particular named branch::
1541 - clone (and track) a particular named branch::
1537
1542
1538 hg clone http://selenic.com/hg#stable
1543 hg clone http://selenic.com/hg#stable
1539
1544
1540 See :hg:`help urls` for details on specifying URLs.
1545 See :hg:`help urls` for details on specifying URLs.
1541
1546
1542 Returns 0 on success.
1547 Returns 0 on success.
1543 """
1548 """
1544 if opts.get('noupdate') and opts.get('updaterev'):
1549 if opts.get('noupdate') and opts.get('updaterev'):
1545 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1550 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1546
1551
1547 r = hg.clone(ui, opts, source, dest,
1552 r = hg.clone(ui, opts, source, dest,
1548 pull=opts.get('pull'),
1553 pull=opts.get('pull'),
1549 stream=opts.get('uncompressed'),
1554 stream=opts.get('uncompressed'),
1550 rev=opts.get('rev'),
1555 rev=opts.get('rev'),
1551 update=opts.get('updaterev') or not opts.get('noupdate'),
1556 update=opts.get('updaterev') or not opts.get('noupdate'),
1552 branch=opts.get('branch'),
1557 branch=opts.get('branch'),
1553 shareopts=opts.get('shareopts'))
1558 shareopts=opts.get('shareopts'))
1554
1559
1555 return r is None
1560 return r is None
1556
1561
1557 @command('^commit|ci',
1562 @command('^commit|ci',
1558 [('A', 'addremove', None,
1563 [('A', 'addremove', None,
1559 _('mark new/missing files as added/removed before committing')),
1564 _('mark new/missing files as added/removed before committing')),
1560 ('', 'close-branch', None,
1565 ('', 'close-branch', None,
1561 _('mark a branch head as closed')),
1566 _('mark a branch head as closed')),
1562 ('', 'amend', None, _('amend the parent of the working directory')),
1567 ('', 'amend', None, _('amend the parent of the working directory')),
1563 ('s', 'secret', None, _('use the secret phase for committing')),
1568 ('s', 'secret', None, _('use the secret phase for committing')),
1564 ('e', 'edit', None, _('invoke editor on commit messages')),
1569 ('e', 'edit', None, _('invoke editor on commit messages')),
1565 ('i', 'interactive', None, _('use interactive mode')),
1570 ('i', 'interactive', None, _('use interactive mode')),
1566 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1571 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1567 _('[OPTION]... [FILE]...'),
1572 _('[OPTION]... [FILE]...'),
1568 inferrepo=True)
1573 inferrepo=True)
1569 def commit(ui, repo, *pats, **opts):
1574 def commit(ui, repo, *pats, **opts):
1570 """commit the specified files or all outstanding changes
1575 """commit the specified files or all outstanding changes
1571
1576
1572 Commit changes to the given files into the repository. Unlike a
1577 Commit changes to the given files into the repository. Unlike a
1573 centralized SCM, this operation is a local operation. See
1578 centralized SCM, this operation is a local operation. See
1574 :hg:`push` for a way to actively distribute your changes.
1579 :hg:`push` for a way to actively distribute your changes.
1575
1580
1576 If a list of files is omitted, all changes reported by :hg:`status`
1581 If a list of files is omitted, all changes reported by :hg:`status`
1577 will be committed.
1582 will be committed.
1578
1583
1579 If you are committing the result of a merge, do not provide any
1584 If you are committing the result of a merge, do not provide any
1580 filenames or -I/-X filters.
1585 filenames or -I/-X filters.
1581
1586
1582 If no commit message is specified, Mercurial starts your
1587 If no commit message is specified, Mercurial starts your
1583 configured editor where you can enter a message. In case your
1588 configured editor where you can enter a message. In case your
1584 commit fails, you will find a backup of your message in
1589 commit fails, you will find a backup of your message in
1585 ``.hg/last-message.txt``.
1590 ``.hg/last-message.txt``.
1586
1591
1587 The --close-branch flag can be used to mark the current branch
1592 The --close-branch flag can be used to mark the current branch
1588 head closed. When all heads of a branch are closed, the branch
1593 head closed. When all heads of a branch are closed, the branch
1589 will be considered closed and no longer listed.
1594 will be considered closed and no longer listed.
1590
1595
1591 The --amend flag can be used to amend the parent of the
1596 The --amend flag can be used to amend the parent of the
1592 working directory with a new commit that contains the changes
1597 working directory with a new commit that contains the changes
1593 in the parent in addition to those currently reported by :hg:`status`,
1598 in the parent in addition to those currently reported by :hg:`status`,
1594 if there are any. The old commit is stored in a backup bundle in
1599 if there are any. The old commit is stored in a backup bundle in
1595 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1600 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1596 on how to restore it).
1601 on how to restore it).
1597
1602
1598 Message, user and date are taken from the amended commit unless
1603 Message, user and date are taken from the amended commit unless
1599 specified. When a message isn't specified on the command line,
1604 specified. When a message isn't specified on the command line,
1600 the editor will open with the message of the amended commit.
1605 the editor will open with the message of the amended commit.
1601
1606
1602 It is not possible to amend public changesets (see :hg:`help phases`)
1607 It is not possible to amend public changesets (see :hg:`help phases`)
1603 or changesets that have children.
1608 or changesets that have children.
1604
1609
1605 See :hg:`help dates` for a list of formats valid for -d/--date.
1610 See :hg:`help dates` for a list of formats valid for -d/--date.
1606
1611
1607 Returns 0 on success, 1 if nothing changed.
1612 Returns 0 on success, 1 if nothing changed.
1608
1613
1609 .. container:: verbose
1614 .. container:: verbose
1610
1615
1611 Examples:
1616 Examples:
1612
1617
1613 - commit all files ending in .py::
1618 - commit all files ending in .py::
1614
1619
1615 hg commit --include "set:**.py"
1620 hg commit --include "set:**.py"
1616
1621
1617 - commit all non-binary files::
1622 - commit all non-binary files::
1618
1623
1619 hg commit --exclude "set:binary()"
1624 hg commit --exclude "set:binary()"
1620
1625
1621 - amend the current commit and set the date to now::
1626 - amend the current commit and set the date to now::
1622
1627
1623 hg commit --amend --date now
1628 hg commit --amend --date now
1624 """
1629 """
1625 wlock = lock = None
1630 wlock = lock = None
1626 try:
1631 try:
1627 wlock = repo.wlock()
1632 wlock = repo.wlock()
1628 lock = repo.lock()
1633 lock = repo.lock()
1629 return _docommit(ui, repo, *pats, **opts)
1634 return _docommit(ui, repo, *pats, **opts)
1630 finally:
1635 finally:
1631 release(lock, wlock)
1636 release(lock, wlock)
1632
1637
1633 def _docommit(ui, repo, *pats, **opts):
1638 def _docommit(ui, repo, *pats, **opts):
1634 if opts.get('interactive'):
1639 if opts.get('interactive'):
1635 opts.pop('interactive')
1640 opts.pop('interactive')
1636 cmdutil.dorecord(ui, repo, commit, None, False,
1641 cmdutil.dorecord(ui, repo, commit, None, False,
1637 cmdutil.recordfilter, *pats, **opts)
1642 cmdutil.recordfilter, *pats, **opts)
1638 return
1643 return
1639
1644
1640 if opts.get('subrepos'):
1645 if opts.get('subrepos'):
1641 if opts.get('amend'):
1646 if opts.get('amend'):
1642 raise error.Abort(_('cannot amend with --subrepos'))
1647 raise error.Abort(_('cannot amend with --subrepos'))
1643 # Let --subrepos on the command line override config setting.
1648 # Let --subrepos on the command line override config setting.
1644 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1649 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1645
1650
1646 cmdutil.checkunfinished(repo, commit=True)
1651 cmdutil.checkunfinished(repo, commit=True)
1647
1652
1648 branch = repo[None].branch()
1653 branch = repo[None].branch()
1649 bheads = repo.branchheads(branch)
1654 bheads = repo.branchheads(branch)
1650
1655
1651 extra = {}
1656 extra = {}
1652 if opts.get('close_branch'):
1657 if opts.get('close_branch'):
1653 extra['close'] = 1
1658 extra['close'] = 1
1654
1659
1655 if not bheads:
1660 if not bheads:
1656 raise error.Abort(_('can only close branch heads'))
1661 raise error.Abort(_('can only close branch heads'))
1657 elif opts.get('amend'):
1662 elif opts.get('amend'):
1658 if repo[None].parents()[0].p1().branch() != branch and \
1663 if repo[None].parents()[0].p1().branch() != branch and \
1659 repo[None].parents()[0].p2().branch() != branch:
1664 repo[None].parents()[0].p2().branch() != branch:
1660 raise error.Abort(_('can only close branch heads'))
1665 raise error.Abort(_('can only close branch heads'))
1661
1666
1662 if opts.get('amend'):
1667 if opts.get('amend'):
1663 if ui.configbool('ui', 'commitsubrepos'):
1668 if ui.configbool('ui', 'commitsubrepos'):
1664 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1669 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1665
1670
1666 old = repo['.']
1671 old = repo['.']
1667 if not old.mutable():
1672 if not old.mutable():
1668 raise error.Abort(_('cannot amend public changesets'))
1673 raise error.Abort(_('cannot amend public changesets'))
1669 if len(repo[None].parents()) > 1:
1674 if len(repo[None].parents()) > 1:
1670 raise error.Abort(_('cannot amend while merging'))
1675 raise error.Abort(_('cannot amend while merging'))
1671 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1676 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1672 if not allowunstable and old.children():
1677 if not allowunstable and old.children():
1673 raise error.Abort(_('cannot amend changeset with children'))
1678 raise error.Abort(_('cannot amend changeset with children'))
1674
1679
1675 newextra = extra.copy()
1680 newextra = extra.copy()
1676 newextra['branch'] = branch
1681 newextra['branch'] = branch
1677 extra = newextra
1682 extra = newextra
1678 # commitfunc is used only for temporary amend commit by cmdutil.amend
1683 # commitfunc is used only for temporary amend commit by cmdutil.amend
1679 def commitfunc(ui, repo, message, match, opts):
1684 def commitfunc(ui, repo, message, match, opts):
1680 return repo.commit(message,
1685 return repo.commit(message,
1681 opts.get('user') or old.user(),
1686 opts.get('user') or old.user(),
1682 opts.get('date') or old.date(),
1687 opts.get('date') or old.date(),
1683 match,
1688 match,
1684 extra=extra)
1689 extra=extra)
1685
1690
1686 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1691 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1687 if node == old.node():
1692 if node == old.node():
1688 ui.status(_("nothing changed\n"))
1693 ui.status(_("nothing changed\n"))
1689 return 1
1694 return 1
1690 else:
1695 else:
1691 def commitfunc(ui, repo, message, match, opts):
1696 def commitfunc(ui, repo, message, match, opts):
1692 backup = ui.backupconfig('phases', 'new-commit')
1697 backup = ui.backupconfig('phases', 'new-commit')
1693 baseui = repo.baseui
1698 baseui = repo.baseui
1694 basebackup = baseui.backupconfig('phases', 'new-commit')
1699 basebackup = baseui.backupconfig('phases', 'new-commit')
1695 try:
1700 try:
1696 if opts.get('secret'):
1701 if opts.get('secret'):
1697 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1702 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1698 # Propagate to subrepos
1703 # Propagate to subrepos
1699 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1704 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1700
1705
1701 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1706 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1702 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1707 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1703 return repo.commit(message, opts.get('user'), opts.get('date'),
1708 return repo.commit(message, opts.get('user'), opts.get('date'),
1704 match,
1709 match,
1705 editor=editor,
1710 editor=editor,
1706 extra=extra)
1711 extra=extra)
1707 finally:
1712 finally:
1708 ui.restoreconfig(backup)
1713 ui.restoreconfig(backup)
1709 repo.baseui.restoreconfig(basebackup)
1714 repo.baseui.restoreconfig(basebackup)
1710
1715
1711
1716
1712 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1717 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1713
1718
1714 if not node:
1719 if not node:
1715 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1720 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1716 if stat[3]:
1721 if stat[3]:
1717 ui.status(_("nothing changed (%d missing files, see "
1722 ui.status(_("nothing changed (%d missing files, see "
1718 "'hg status')\n") % len(stat[3]))
1723 "'hg status')\n") % len(stat[3]))
1719 else:
1724 else:
1720 ui.status(_("nothing changed\n"))
1725 ui.status(_("nothing changed\n"))
1721 return 1
1726 return 1
1722
1727
1723 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1728 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1724
1729
1725 @command('config|showconfig|debugconfig',
1730 @command('config|showconfig|debugconfig',
1726 [('u', 'untrusted', None, _('show untrusted configuration options')),
1731 [('u', 'untrusted', None, _('show untrusted configuration options')),
1727 ('e', 'edit', None, _('edit user config')),
1732 ('e', 'edit', None, _('edit user config')),
1728 ('l', 'local', None, _('edit repository config')),
1733 ('l', 'local', None, _('edit repository config')),
1729 ('g', 'global', None, _('edit global config'))],
1734 ('g', 'global', None, _('edit global config'))],
1730 _('[-u] [NAME]...'),
1735 _('[-u] [NAME]...'),
1731 optionalrepo=True)
1736 optionalrepo=True)
1732 def config(ui, repo, *values, **opts):
1737 def config(ui, repo, *values, **opts):
1733 """show combined config settings from all hgrc files
1738 """show combined config settings from all hgrc files
1734
1739
1735 With no arguments, print names and values of all config items.
1740 With no arguments, print names and values of all config items.
1736
1741
1737 With one argument of the form section.name, print just the value
1742 With one argument of the form section.name, print just the value
1738 of that config item.
1743 of that config item.
1739
1744
1740 With multiple arguments, print names and values of all config
1745 With multiple arguments, print names and values of all config
1741 items with matching section names.
1746 items with matching section names.
1742
1747
1743 With --edit, start an editor on the user-level config file. With
1748 With --edit, start an editor on the user-level config file. With
1744 --global, edit the system-wide config file. With --local, edit the
1749 --global, edit the system-wide config file. With --local, edit the
1745 repository-level config file.
1750 repository-level config file.
1746
1751
1747 With --debug, the source (filename and line number) is printed
1752 With --debug, the source (filename and line number) is printed
1748 for each config item.
1753 for each config item.
1749
1754
1750 See :hg:`help config` for more information about config files.
1755 See :hg:`help config` for more information about config files.
1751
1756
1752 Returns 0 on success, 1 if NAME does not exist.
1757 Returns 0 on success, 1 if NAME does not exist.
1753
1758
1754 """
1759 """
1755
1760
1756 if opts.get('edit') or opts.get('local') or opts.get('global'):
1761 if opts.get('edit') or opts.get('local') or opts.get('global'):
1757 if opts.get('local') and opts.get('global'):
1762 if opts.get('local') and opts.get('global'):
1758 raise error.Abort(_("can't use --local and --global together"))
1763 raise error.Abort(_("can't use --local and --global together"))
1759
1764
1760 if opts.get('local'):
1765 if opts.get('local'):
1761 if not repo:
1766 if not repo:
1762 raise error.Abort(_("can't use --local outside a repository"))
1767 raise error.Abort(_("can't use --local outside a repository"))
1763 paths = [repo.join('hgrc')]
1768 paths = [repo.join('hgrc')]
1764 elif opts.get('global'):
1769 elif opts.get('global'):
1765 paths = scmutil.systemrcpath()
1770 paths = scmutil.systemrcpath()
1766 else:
1771 else:
1767 paths = scmutil.userrcpath()
1772 paths = scmutil.userrcpath()
1768
1773
1769 for f in paths:
1774 for f in paths:
1770 if os.path.exists(f):
1775 if os.path.exists(f):
1771 break
1776 break
1772 else:
1777 else:
1773 if opts.get('global'):
1778 if opts.get('global'):
1774 samplehgrc = uimod.samplehgrcs['global']
1779 samplehgrc = uimod.samplehgrcs['global']
1775 elif opts.get('local'):
1780 elif opts.get('local'):
1776 samplehgrc = uimod.samplehgrcs['local']
1781 samplehgrc = uimod.samplehgrcs['local']
1777 else:
1782 else:
1778 samplehgrc = uimod.samplehgrcs['user']
1783 samplehgrc = uimod.samplehgrcs['user']
1779
1784
1780 f = paths[0]
1785 f = paths[0]
1781 fp = open(f, "w")
1786 fp = open(f, "w")
1782 fp.write(samplehgrc)
1787 fp.write(samplehgrc)
1783 fp.close()
1788 fp.close()
1784
1789
1785 editor = ui.geteditor()
1790 editor = ui.geteditor()
1786 ui.system("%s \"%s\"" % (editor, f),
1791 ui.system("%s \"%s\"" % (editor, f),
1787 onerr=error.Abort, errprefix=_("edit failed"))
1792 onerr=error.Abort, errprefix=_("edit failed"))
1788 return
1793 return
1789
1794
1790 for f in scmutil.rcpath():
1795 for f in scmutil.rcpath():
1791 ui.debug('read config from: %s\n' % f)
1796 ui.debug('read config from: %s\n' % f)
1792 untrusted = bool(opts.get('untrusted'))
1797 untrusted = bool(opts.get('untrusted'))
1793 if values:
1798 if values:
1794 sections = [v for v in values if '.' not in v]
1799 sections = [v for v in values if '.' not in v]
1795 items = [v for v in values if '.' in v]
1800 items = [v for v in values if '.' in v]
1796 if len(items) > 1 or items and sections:
1801 if len(items) > 1 or items and sections:
1797 raise error.Abort(_('only one config item permitted'))
1802 raise error.Abort(_('only one config item permitted'))
1798 matched = False
1803 matched = False
1799 for section, name, value in ui.walkconfig(untrusted=untrusted):
1804 for section, name, value in ui.walkconfig(untrusted=untrusted):
1800 value = str(value).replace('\n', '\\n')
1805 value = str(value).replace('\n', '\\n')
1801 sectname = section + '.' + name
1806 sectname = section + '.' + name
1802 if values:
1807 if values:
1803 for v in values:
1808 for v in values:
1804 if v == section:
1809 if v == section:
1805 ui.debug('%s: ' %
1810 ui.debug('%s: ' %
1806 ui.configsource(section, name, untrusted))
1811 ui.configsource(section, name, untrusted))
1807 ui.write('%s=%s\n' % (sectname, value))
1812 ui.write('%s=%s\n' % (sectname, value))
1808 matched = True
1813 matched = True
1809 elif v == sectname:
1814 elif v == sectname:
1810 ui.debug('%s: ' %
1815 ui.debug('%s: ' %
1811 ui.configsource(section, name, untrusted))
1816 ui.configsource(section, name, untrusted))
1812 ui.write(value, '\n')
1817 ui.write(value, '\n')
1813 matched = True
1818 matched = True
1814 else:
1819 else:
1815 ui.debug('%s: ' %
1820 ui.debug('%s: ' %
1816 ui.configsource(section, name, untrusted))
1821 ui.configsource(section, name, untrusted))
1817 ui.write('%s=%s\n' % (sectname, value))
1822 ui.write('%s=%s\n' % (sectname, value))
1818 matched = True
1823 matched = True
1819 if matched:
1824 if matched:
1820 return 0
1825 return 0
1821 return 1
1826 return 1
1822
1827
1823 @command('copy|cp',
1828 @command('copy|cp',
1824 [('A', 'after', None, _('record a copy that has already occurred')),
1829 [('A', 'after', None, _('record a copy that has already occurred')),
1825 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1830 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1826 ] + walkopts + dryrunopts,
1831 ] + walkopts + dryrunopts,
1827 _('[OPTION]... [SOURCE]... DEST'))
1832 _('[OPTION]... [SOURCE]... DEST'))
1828 def copy(ui, repo, *pats, **opts):
1833 def copy(ui, repo, *pats, **opts):
1829 """mark files as copied for the next commit
1834 """mark files as copied for the next commit
1830
1835
1831 Mark dest as having copies of source files. If dest is a
1836 Mark dest as having copies of source files. If dest is a
1832 directory, copies are put in that directory. If dest is a file,
1837 directory, copies are put in that directory. If dest is a file,
1833 the source must be a single file.
1838 the source must be a single file.
1834
1839
1835 By default, this command copies the contents of files as they
1840 By default, this command copies the contents of files as they
1836 exist in the working directory. If invoked with -A/--after, the
1841 exist in the working directory. If invoked with -A/--after, the
1837 operation is recorded, but no copying is performed.
1842 operation is recorded, but no copying is performed.
1838
1843
1839 This command takes effect with the next commit. To undo a copy
1844 This command takes effect with the next commit. To undo a copy
1840 before that, see :hg:`revert`.
1845 before that, see :hg:`revert`.
1841
1846
1842 Returns 0 on success, 1 if errors are encountered.
1847 Returns 0 on success, 1 if errors are encountered.
1843 """
1848 """
1844 with repo.wlock(False):
1849 with repo.wlock(False):
1845 return cmdutil.copy(ui, repo, pats, opts)
1850 return cmdutil.copy(ui, repo, pats, opts)
1846
1851
1847 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
1852 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
1848 def debugancestor(ui, repo, *args):
1853 def debugancestor(ui, repo, *args):
1849 """find the ancestor revision of two revisions in a given index"""
1854 """find the ancestor revision of two revisions in a given index"""
1850 if len(args) == 3:
1855 if len(args) == 3:
1851 index, rev1, rev2 = args
1856 index, rev1, rev2 = args
1852 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1857 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1853 lookup = r.lookup
1858 lookup = r.lookup
1854 elif len(args) == 2:
1859 elif len(args) == 2:
1855 if not repo:
1860 if not repo:
1856 raise error.Abort(_("there is no Mercurial repository here "
1861 raise error.Abort(_("there is no Mercurial repository here "
1857 "(.hg not found)"))
1862 "(.hg not found)"))
1858 rev1, rev2 = args
1863 rev1, rev2 = args
1859 r = repo.changelog
1864 r = repo.changelog
1860 lookup = repo.lookup
1865 lookup = repo.lookup
1861 else:
1866 else:
1862 raise error.Abort(_('either two or three arguments required'))
1867 raise error.Abort(_('either two or three arguments required'))
1863 a = r.ancestor(lookup(rev1), lookup(rev2))
1868 a = r.ancestor(lookup(rev1), lookup(rev2))
1864 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1869 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1865
1870
1866 @command('debugbuilddag',
1871 @command('debugbuilddag',
1867 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1872 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1868 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1873 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1869 ('n', 'new-file', None, _('add new file at each rev'))],
1874 ('n', 'new-file', None, _('add new file at each rev'))],
1870 _('[OPTION]... [TEXT]'))
1875 _('[OPTION]... [TEXT]'))
1871 def debugbuilddag(ui, repo, text=None,
1876 def debugbuilddag(ui, repo, text=None,
1872 mergeable_file=False,
1877 mergeable_file=False,
1873 overwritten_file=False,
1878 overwritten_file=False,
1874 new_file=False):
1879 new_file=False):
1875 """builds a repo with a given DAG from scratch in the current empty repo
1880 """builds a repo with a given DAG from scratch in the current empty repo
1876
1881
1877 The description of the DAG is read from stdin if not given on the
1882 The description of the DAG is read from stdin if not given on the
1878 command line.
1883 command line.
1879
1884
1880 Elements:
1885 Elements:
1881
1886
1882 - "+n" is a linear run of n nodes based on the current default parent
1887 - "+n" is a linear run of n nodes based on the current default parent
1883 - "." is a single node based on the current default parent
1888 - "." is a single node based on the current default parent
1884 - "$" resets the default parent to null (implied at the start);
1889 - "$" resets the default parent to null (implied at the start);
1885 otherwise the default parent is always the last node created
1890 otherwise the default parent is always the last node created
1886 - "<p" sets the default parent to the backref p
1891 - "<p" sets the default parent to the backref p
1887 - "*p" is a fork at parent p, which is a backref
1892 - "*p" is a fork at parent p, which is a backref
1888 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1893 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1889 - "/p2" is a merge of the preceding node and p2
1894 - "/p2" is a merge of the preceding node and p2
1890 - ":tag" defines a local tag for the preceding node
1895 - ":tag" defines a local tag for the preceding node
1891 - "@branch" sets the named branch for subsequent nodes
1896 - "@branch" sets the named branch for subsequent nodes
1892 - "#...\\n" is a comment up to the end of the line
1897 - "#...\\n" is a comment up to the end of the line
1893
1898
1894 Whitespace between the above elements is ignored.
1899 Whitespace between the above elements is ignored.
1895
1900
1896 A backref is either
1901 A backref is either
1897
1902
1898 - a number n, which references the node curr-n, where curr is the current
1903 - a number n, which references the node curr-n, where curr is the current
1899 node, or
1904 node, or
1900 - the name of a local tag you placed earlier using ":tag", or
1905 - the name of a local tag you placed earlier using ":tag", or
1901 - empty to denote the default parent.
1906 - empty to denote the default parent.
1902
1907
1903 All string valued-elements are either strictly alphanumeric, or must
1908 All string valued-elements are either strictly alphanumeric, or must
1904 be enclosed in double quotes ("..."), with "\\" as escape character.
1909 be enclosed in double quotes ("..."), with "\\" as escape character.
1905 """
1910 """
1906
1911
1907 if text is None:
1912 if text is None:
1908 ui.status(_("reading DAG from stdin\n"))
1913 ui.status(_("reading DAG from stdin\n"))
1909 text = ui.fin.read()
1914 text = ui.fin.read()
1910
1915
1911 cl = repo.changelog
1916 cl = repo.changelog
1912 if len(cl) > 0:
1917 if len(cl) > 0:
1913 raise error.Abort(_('repository is not empty'))
1918 raise error.Abort(_('repository is not empty'))
1914
1919
1915 # determine number of revs in DAG
1920 # determine number of revs in DAG
1916 total = 0
1921 total = 0
1917 for type, data in dagparser.parsedag(text):
1922 for type, data in dagparser.parsedag(text):
1918 if type == 'n':
1923 if type == 'n':
1919 total += 1
1924 total += 1
1920
1925
1921 if mergeable_file:
1926 if mergeable_file:
1922 linesperrev = 2
1927 linesperrev = 2
1923 # make a file with k lines per rev
1928 # make a file with k lines per rev
1924 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1929 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1925 initialmergedlines.append("")
1930 initialmergedlines.append("")
1926
1931
1927 tags = []
1932 tags = []
1928
1933
1929 lock = tr = None
1934 lock = tr = None
1930 try:
1935 try:
1931 lock = repo.lock()
1936 lock = repo.lock()
1932 tr = repo.transaction("builddag")
1937 tr = repo.transaction("builddag")
1933
1938
1934 at = -1
1939 at = -1
1935 atbranch = 'default'
1940 atbranch = 'default'
1936 nodeids = []
1941 nodeids = []
1937 id = 0
1942 id = 0
1938 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1943 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1939 for type, data in dagparser.parsedag(text):
1944 for type, data in dagparser.parsedag(text):
1940 if type == 'n':
1945 if type == 'n':
1941 ui.note(('node %s\n' % str(data)))
1946 ui.note(('node %s\n' % str(data)))
1942 id, ps = data
1947 id, ps = data
1943
1948
1944 files = []
1949 files = []
1945 fctxs = {}
1950 fctxs = {}
1946
1951
1947 p2 = None
1952 p2 = None
1948 if mergeable_file:
1953 if mergeable_file:
1949 fn = "mf"
1954 fn = "mf"
1950 p1 = repo[ps[0]]
1955 p1 = repo[ps[0]]
1951 if len(ps) > 1:
1956 if len(ps) > 1:
1952 p2 = repo[ps[1]]
1957 p2 = repo[ps[1]]
1953 pa = p1.ancestor(p2)
1958 pa = p1.ancestor(p2)
1954 base, local, other = [x[fn].data() for x in (pa, p1,
1959 base, local, other = [x[fn].data() for x in (pa, p1,
1955 p2)]
1960 p2)]
1956 m3 = simplemerge.Merge3Text(base, local, other)
1961 m3 = simplemerge.Merge3Text(base, local, other)
1957 ml = [l.strip() for l in m3.merge_lines()]
1962 ml = [l.strip() for l in m3.merge_lines()]
1958 ml.append("")
1963 ml.append("")
1959 elif at > 0:
1964 elif at > 0:
1960 ml = p1[fn].data().split("\n")
1965 ml = p1[fn].data().split("\n")
1961 else:
1966 else:
1962 ml = initialmergedlines
1967 ml = initialmergedlines
1963 ml[id * linesperrev] += " r%i" % id
1968 ml[id * linesperrev] += " r%i" % id
1964 mergedtext = "\n".join(ml)
1969 mergedtext = "\n".join(ml)
1965 files.append(fn)
1970 files.append(fn)
1966 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
1971 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
1967
1972
1968 if overwritten_file:
1973 if overwritten_file:
1969 fn = "of"
1974 fn = "of"
1970 files.append(fn)
1975 files.append(fn)
1971 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1976 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1972
1977
1973 if new_file:
1978 if new_file:
1974 fn = "nf%i" % id
1979 fn = "nf%i" % id
1975 files.append(fn)
1980 files.append(fn)
1976 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1981 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1977 if len(ps) > 1:
1982 if len(ps) > 1:
1978 if not p2:
1983 if not p2:
1979 p2 = repo[ps[1]]
1984 p2 = repo[ps[1]]
1980 for fn in p2:
1985 for fn in p2:
1981 if fn.startswith("nf"):
1986 if fn.startswith("nf"):
1982 files.append(fn)
1987 files.append(fn)
1983 fctxs[fn] = p2[fn]
1988 fctxs[fn] = p2[fn]
1984
1989
1985 def fctxfn(repo, cx, path):
1990 def fctxfn(repo, cx, path):
1986 return fctxs.get(path)
1991 return fctxs.get(path)
1987
1992
1988 if len(ps) == 0 or ps[0] < 0:
1993 if len(ps) == 0 or ps[0] < 0:
1989 pars = [None, None]
1994 pars = [None, None]
1990 elif len(ps) == 1:
1995 elif len(ps) == 1:
1991 pars = [nodeids[ps[0]], None]
1996 pars = [nodeids[ps[0]], None]
1992 else:
1997 else:
1993 pars = [nodeids[p] for p in ps]
1998 pars = [nodeids[p] for p in ps]
1994 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1999 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1995 date=(id, 0),
2000 date=(id, 0),
1996 user="debugbuilddag",
2001 user="debugbuilddag",
1997 extra={'branch': atbranch})
2002 extra={'branch': atbranch})
1998 nodeid = repo.commitctx(cx)
2003 nodeid = repo.commitctx(cx)
1999 nodeids.append(nodeid)
2004 nodeids.append(nodeid)
2000 at = id
2005 at = id
2001 elif type == 'l':
2006 elif type == 'l':
2002 id, name = data
2007 id, name = data
2003 ui.note(('tag %s\n' % name))
2008 ui.note(('tag %s\n' % name))
2004 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
2009 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
2005 elif type == 'a':
2010 elif type == 'a':
2006 ui.note(('branch %s\n' % data))
2011 ui.note(('branch %s\n' % data))
2007 atbranch = data
2012 atbranch = data
2008 ui.progress(_('building'), id, unit=_('revisions'), total=total)
2013 ui.progress(_('building'), id, unit=_('revisions'), total=total)
2009 tr.close()
2014 tr.close()
2010
2015
2011 if tags:
2016 if tags:
2012 repo.vfs.write("localtags", "".join(tags))
2017 repo.vfs.write("localtags", "".join(tags))
2013 finally:
2018 finally:
2014 ui.progress(_('building'), None)
2019 ui.progress(_('building'), None)
2015 release(tr, lock)
2020 release(tr, lock)
2016
2021
2017 @command('debugbundle',
2022 @command('debugbundle',
2018 [('a', 'all', None, _('show all details')),
2023 [('a', 'all', None, _('show all details')),
2019 ('', 'spec', None, _('print the bundlespec of the bundle'))],
2024 ('', 'spec', None, _('print the bundlespec of the bundle'))],
2020 _('FILE'),
2025 _('FILE'),
2021 norepo=True)
2026 norepo=True)
2022 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
2027 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
2023 """lists the contents of a bundle"""
2028 """lists the contents of a bundle"""
2024 with hg.openpath(ui, bundlepath) as f:
2029 with hg.openpath(ui, bundlepath) as f:
2025 if spec:
2030 if spec:
2026 spec = exchange.getbundlespec(ui, f)
2031 spec = exchange.getbundlespec(ui, f)
2027 ui.write('%s\n' % spec)
2032 ui.write('%s\n' % spec)
2028 return
2033 return
2029
2034
2030 gen = exchange.readbundle(ui, f, bundlepath)
2035 gen = exchange.readbundle(ui, f, bundlepath)
2031 if isinstance(gen, bundle2.unbundle20):
2036 if isinstance(gen, bundle2.unbundle20):
2032 return _debugbundle2(ui, gen, all=all, **opts)
2037 return _debugbundle2(ui, gen, all=all, **opts)
2033 if all:
2038 if all:
2034 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
2039 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
2035
2040
2036 def showchunks(named):
2041 def showchunks(named):
2037 ui.write("\n%s\n" % named)
2042 ui.write("\n%s\n" % named)
2038 chain = None
2043 chain = None
2039 while True:
2044 while True:
2040 chunkdata = gen.deltachunk(chain)
2045 chunkdata = gen.deltachunk(chain)
2041 if not chunkdata:
2046 if not chunkdata:
2042 break
2047 break
2043 node = chunkdata['node']
2048 node = chunkdata['node']
2044 p1 = chunkdata['p1']
2049 p1 = chunkdata['p1']
2045 p2 = chunkdata['p2']
2050 p2 = chunkdata['p2']
2046 cs = chunkdata['cs']
2051 cs = chunkdata['cs']
2047 deltabase = chunkdata['deltabase']
2052 deltabase = chunkdata['deltabase']
2048 delta = chunkdata['delta']
2053 delta = chunkdata['delta']
2049 ui.write("%s %s %s %s %s %s\n" %
2054 ui.write("%s %s %s %s %s %s\n" %
2050 (hex(node), hex(p1), hex(p2),
2055 (hex(node), hex(p1), hex(p2),
2051 hex(cs), hex(deltabase), len(delta)))
2056 hex(cs), hex(deltabase), len(delta)))
2052 chain = node
2057 chain = node
2053
2058
2054 chunkdata = gen.changelogheader()
2059 chunkdata = gen.changelogheader()
2055 showchunks("changelog")
2060 showchunks("changelog")
2056 chunkdata = gen.manifestheader()
2061 chunkdata = gen.manifestheader()
2057 showchunks("manifest")
2062 showchunks("manifest")
2058 while True:
2063 while True:
2059 chunkdata = gen.filelogheader()
2064 chunkdata = gen.filelogheader()
2060 if not chunkdata:
2065 if not chunkdata:
2061 break
2066 break
2062 fname = chunkdata['filename']
2067 fname = chunkdata['filename']
2063 showchunks(fname)
2068 showchunks(fname)
2064 else:
2069 else:
2065 if isinstance(gen, bundle2.unbundle20):
2070 if isinstance(gen, bundle2.unbundle20):
2066 raise error.Abort(_('use debugbundle2 for this file'))
2071 raise error.Abort(_('use debugbundle2 for this file'))
2067 chunkdata = gen.changelogheader()
2072 chunkdata = gen.changelogheader()
2068 chain = None
2073 chain = None
2069 while True:
2074 while True:
2070 chunkdata = gen.deltachunk(chain)
2075 chunkdata = gen.deltachunk(chain)
2071 if not chunkdata:
2076 if not chunkdata:
2072 break
2077 break
2073 node = chunkdata['node']
2078 node = chunkdata['node']
2074 ui.write("%s\n" % hex(node))
2079 ui.write("%s\n" % hex(node))
2075 chain = node
2080 chain = node
2076
2081
2077 def _debugbundle2(ui, gen, **opts):
2082 def _debugbundle2(ui, gen, **opts):
2078 """lists the contents of a bundle2"""
2083 """lists the contents of a bundle2"""
2079 if not isinstance(gen, bundle2.unbundle20):
2084 if not isinstance(gen, bundle2.unbundle20):
2080 raise error.Abort(_('not a bundle2 file'))
2085 raise error.Abort(_('not a bundle2 file'))
2081 ui.write(('Stream params: %s\n' % repr(gen.params)))
2086 ui.write(('Stream params: %s\n' % repr(gen.params)))
2082 for part in gen.iterparts():
2087 for part in gen.iterparts():
2083 ui.write('%s -- %r\n' % (part.type, repr(part.params)))
2088 ui.write('%s -- %r\n' % (part.type, repr(part.params)))
2084 if part.type == 'changegroup':
2089 if part.type == 'changegroup':
2085 version = part.params.get('version', '01')
2090 version = part.params.get('version', '01')
2086 cg = changegroup.getunbundler(version, part, 'UN')
2091 cg = changegroup.getunbundler(version, part, 'UN')
2087 chunkdata = cg.changelogheader()
2092 chunkdata = cg.changelogheader()
2088 chain = None
2093 chain = None
2089 while True:
2094 while True:
2090 chunkdata = cg.deltachunk(chain)
2095 chunkdata = cg.deltachunk(chain)
2091 if not chunkdata:
2096 if not chunkdata:
2092 break
2097 break
2093 node = chunkdata['node']
2098 node = chunkdata['node']
2094 ui.write(" %s\n" % hex(node))
2099 ui.write(" %s\n" % hex(node))
2095 chain = node
2100 chain = node
2096
2101
2097 @command('debugcreatestreamclonebundle', [], 'FILE')
2102 @command('debugcreatestreamclonebundle', [], 'FILE')
2098 def debugcreatestreamclonebundle(ui, repo, fname):
2103 def debugcreatestreamclonebundle(ui, repo, fname):
2099 """create a stream clone bundle file
2104 """create a stream clone bundle file
2100
2105
2101 Stream bundles are special bundles that are essentially archives of
2106 Stream bundles are special bundles that are essentially archives of
2102 revlog files. They are commonly used for cloning very quickly.
2107 revlog files. They are commonly used for cloning very quickly.
2103 """
2108 """
2104 requirements, gen = streamclone.generatebundlev1(repo)
2109 requirements, gen = streamclone.generatebundlev1(repo)
2105 changegroup.writechunks(ui, gen, fname)
2110 changegroup.writechunks(ui, gen, fname)
2106
2111
2107 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
2112 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
2108
2113
2109 @command('debugapplystreamclonebundle', [], 'FILE')
2114 @command('debugapplystreamclonebundle', [], 'FILE')
2110 def debugapplystreamclonebundle(ui, repo, fname):
2115 def debugapplystreamclonebundle(ui, repo, fname):
2111 """apply a stream clone bundle file"""
2116 """apply a stream clone bundle file"""
2112 f = hg.openpath(ui, fname)
2117 f = hg.openpath(ui, fname)
2113 gen = exchange.readbundle(ui, f, fname)
2118 gen = exchange.readbundle(ui, f, fname)
2114 gen.apply(repo)
2119 gen.apply(repo)
2115
2120
2116 @command('debugcheckstate', [], '')
2121 @command('debugcheckstate', [], '')
2117 def debugcheckstate(ui, repo):
2122 def debugcheckstate(ui, repo):
2118 """validate the correctness of the current dirstate"""
2123 """validate the correctness of the current dirstate"""
2119 parent1, parent2 = repo.dirstate.parents()
2124 parent1, parent2 = repo.dirstate.parents()
2120 m1 = repo[parent1].manifest()
2125 m1 = repo[parent1].manifest()
2121 m2 = repo[parent2].manifest()
2126 m2 = repo[parent2].manifest()
2122 errors = 0
2127 errors = 0
2123 for f in repo.dirstate:
2128 for f in repo.dirstate:
2124 state = repo.dirstate[f]
2129 state = repo.dirstate[f]
2125 if state in "nr" and f not in m1:
2130 if state in "nr" and f not in m1:
2126 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
2131 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
2127 errors += 1
2132 errors += 1
2128 if state in "a" and f in m1:
2133 if state in "a" and f in m1:
2129 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
2134 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
2130 errors += 1
2135 errors += 1
2131 if state in "m" and f not in m1 and f not in m2:
2136 if state in "m" and f not in m1 and f not in m2:
2132 ui.warn(_("%s in state %s, but not in either manifest\n") %
2137 ui.warn(_("%s in state %s, but not in either manifest\n") %
2133 (f, state))
2138 (f, state))
2134 errors += 1
2139 errors += 1
2135 for f in m1:
2140 for f in m1:
2136 state = repo.dirstate[f]
2141 state = repo.dirstate[f]
2137 if state not in "nrm":
2142 if state not in "nrm":
2138 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
2143 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
2139 errors += 1
2144 errors += 1
2140 if errors:
2145 if errors:
2141 error = _(".hg/dirstate inconsistent with current parent's manifest")
2146 error = _(".hg/dirstate inconsistent with current parent's manifest")
2142 raise error.Abort(error)
2147 raise error.Abort(error)
2143
2148
2144 @command('debugcommands', [], _('[COMMAND]'), norepo=True)
2149 @command('debugcommands', [], _('[COMMAND]'), norepo=True)
2145 def debugcommands(ui, cmd='', *args):
2150 def debugcommands(ui, cmd='', *args):
2146 """list all available commands and options"""
2151 """list all available commands and options"""
2147 for cmd, vals in sorted(table.iteritems()):
2152 for cmd, vals in sorted(table.iteritems()):
2148 cmd = cmd.split('|')[0].strip('^')
2153 cmd = cmd.split('|')[0].strip('^')
2149 opts = ', '.join([i[1] for i in vals[1]])
2154 opts = ', '.join([i[1] for i in vals[1]])
2150 ui.write('%s: %s\n' % (cmd, opts))
2155 ui.write('%s: %s\n' % (cmd, opts))
2151
2156
2152 @command('debugcomplete',
2157 @command('debugcomplete',
2153 [('o', 'options', None, _('show the command options'))],
2158 [('o', 'options', None, _('show the command options'))],
2154 _('[-o] CMD'),
2159 _('[-o] CMD'),
2155 norepo=True)
2160 norepo=True)
2156 def debugcomplete(ui, cmd='', **opts):
2161 def debugcomplete(ui, cmd='', **opts):
2157 """returns the completion list associated with the given command"""
2162 """returns the completion list associated with the given command"""
2158
2163
2159 if opts.get('options'):
2164 if opts.get('options'):
2160 options = []
2165 options = []
2161 otables = [globalopts]
2166 otables = [globalopts]
2162 if cmd:
2167 if cmd:
2163 aliases, entry = cmdutil.findcmd(cmd, table, False)
2168 aliases, entry = cmdutil.findcmd(cmd, table, False)
2164 otables.append(entry[1])
2169 otables.append(entry[1])
2165 for t in otables:
2170 for t in otables:
2166 for o in t:
2171 for o in t:
2167 if "(DEPRECATED)" in o[3]:
2172 if "(DEPRECATED)" in o[3]:
2168 continue
2173 continue
2169 if o[0]:
2174 if o[0]:
2170 options.append('-%s' % o[0])
2175 options.append('-%s' % o[0])
2171 options.append('--%s' % o[1])
2176 options.append('--%s' % o[1])
2172 ui.write("%s\n" % "\n".join(options))
2177 ui.write("%s\n" % "\n".join(options))
2173 return
2178 return
2174
2179
2175 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2180 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2176 if ui.verbose:
2181 if ui.verbose:
2177 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
2182 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
2178 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
2183 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
2179
2184
2180 @command('debugdag',
2185 @command('debugdag',
2181 [('t', 'tags', None, _('use tags as labels')),
2186 [('t', 'tags', None, _('use tags as labels')),
2182 ('b', 'branches', None, _('annotate with branch names')),
2187 ('b', 'branches', None, _('annotate with branch names')),
2183 ('', 'dots', None, _('use dots for runs')),
2188 ('', 'dots', None, _('use dots for runs')),
2184 ('s', 'spaces', None, _('separate elements by spaces'))],
2189 ('s', 'spaces', None, _('separate elements by spaces'))],
2185 _('[OPTION]... [FILE [REV]...]'),
2190 _('[OPTION]... [FILE [REV]...]'),
2186 optionalrepo=True)
2191 optionalrepo=True)
2187 def debugdag(ui, repo, file_=None, *revs, **opts):
2192 def debugdag(ui, repo, file_=None, *revs, **opts):
2188 """format the changelog or an index DAG as a concise textual description
2193 """format the changelog or an index DAG as a concise textual description
2189
2194
2190 If you pass a revlog index, the revlog's DAG is emitted. If you list
2195 If you pass a revlog index, the revlog's DAG is emitted. If you list
2191 revision numbers, they get labeled in the output as rN.
2196 revision numbers, they get labeled in the output as rN.
2192
2197
2193 Otherwise, the changelog DAG of the current repo is emitted.
2198 Otherwise, the changelog DAG of the current repo is emitted.
2194 """
2199 """
2195 spaces = opts.get('spaces')
2200 spaces = opts.get('spaces')
2196 dots = opts.get('dots')
2201 dots = opts.get('dots')
2197 if file_:
2202 if file_:
2198 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2203 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2199 revs = set((int(r) for r in revs))
2204 revs = set((int(r) for r in revs))
2200 def events():
2205 def events():
2201 for r in rlog:
2206 for r in rlog:
2202 yield 'n', (r, list(p for p in rlog.parentrevs(r)
2207 yield 'n', (r, list(p for p in rlog.parentrevs(r)
2203 if p != -1))
2208 if p != -1))
2204 if r in revs:
2209 if r in revs:
2205 yield 'l', (r, "r%i" % r)
2210 yield 'l', (r, "r%i" % r)
2206 elif repo:
2211 elif repo:
2207 cl = repo.changelog
2212 cl = repo.changelog
2208 tags = opts.get('tags')
2213 tags = opts.get('tags')
2209 branches = opts.get('branches')
2214 branches = opts.get('branches')
2210 if tags:
2215 if tags:
2211 labels = {}
2216 labels = {}
2212 for l, n in repo.tags().items():
2217 for l, n in repo.tags().items():
2213 labels.setdefault(cl.rev(n), []).append(l)
2218 labels.setdefault(cl.rev(n), []).append(l)
2214 def events():
2219 def events():
2215 b = "default"
2220 b = "default"
2216 for r in cl:
2221 for r in cl:
2217 if branches:
2222 if branches:
2218 newb = cl.read(cl.node(r))[5]['branch']
2223 newb = cl.read(cl.node(r))[5]['branch']
2219 if newb != b:
2224 if newb != b:
2220 yield 'a', newb
2225 yield 'a', newb
2221 b = newb
2226 b = newb
2222 yield 'n', (r, list(p for p in cl.parentrevs(r)
2227 yield 'n', (r, list(p for p in cl.parentrevs(r)
2223 if p != -1))
2228 if p != -1))
2224 if tags:
2229 if tags:
2225 ls = labels.get(r)
2230 ls = labels.get(r)
2226 if ls:
2231 if ls:
2227 for l in ls:
2232 for l in ls:
2228 yield 'l', (r, l)
2233 yield 'l', (r, l)
2229 else:
2234 else:
2230 raise error.Abort(_('need repo for changelog dag'))
2235 raise error.Abort(_('need repo for changelog dag'))
2231
2236
2232 for line in dagparser.dagtextlines(events(),
2237 for line in dagparser.dagtextlines(events(),
2233 addspaces=spaces,
2238 addspaces=spaces,
2234 wraplabels=True,
2239 wraplabels=True,
2235 wrapannotations=True,
2240 wrapannotations=True,
2236 wrapnonlinear=dots,
2241 wrapnonlinear=dots,
2237 usedots=dots,
2242 usedots=dots,
2238 maxlinewidth=70):
2243 maxlinewidth=70):
2239 ui.write(line)
2244 ui.write(line)
2240 ui.write("\n")
2245 ui.write("\n")
2241
2246
2242 @command('debugdata', debugrevlogopts, _('-c|-m|FILE REV'))
2247 @command('debugdata', debugrevlogopts, _('-c|-m|FILE REV'))
2243 def debugdata(ui, repo, file_, rev=None, **opts):
2248 def debugdata(ui, repo, file_, rev=None, **opts):
2244 """dump the contents of a data file revision"""
2249 """dump the contents of a data file revision"""
2245 if opts.get('changelog') or opts.get('manifest'):
2250 if opts.get('changelog') or opts.get('manifest'):
2246 file_, rev = None, file_
2251 file_, rev = None, file_
2247 elif rev is None:
2252 elif rev is None:
2248 raise error.CommandError('debugdata', _('invalid arguments'))
2253 raise error.CommandError('debugdata', _('invalid arguments'))
2249 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
2254 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
2250 try:
2255 try:
2251 ui.write(r.revision(r.lookup(rev)))
2256 ui.write(r.revision(r.lookup(rev)))
2252 except KeyError:
2257 except KeyError:
2253 raise error.Abort(_('invalid revision identifier %s') % rev)
2258 raise error.Abort(_('invalid revision identifier %s') % rev)
2254
2259
2255 @command('debugdate',
2260 @command('debugdate',
2256 [('e', 'extended', None, _('try extended date formats'))],
2261 [('e', 'extended', None, _('try extended date formats'))],
2257 _('[-e] DATE [RANGE]'),
2262 _('[-e] DATE [RANGE]'),
2258 norepo=True, optionalrepo=True)
2263 norepo=True, optionalrepo=True)
2259 def debugdate(ui, date, range=None, **opts):
2264 def debugdate(ui, date, range=None, **opts):
2260 """parse and display a date"""
2265 """parse and display a date"""
2261 if opts["extended"]:
2266 if opts["extended"]:
2262 d = util.parsedate(date, util.extendeddateformats)
2267 d = util.parsedate(date, util.extendeddateformats)
2263 else:
2268 else:
2264 d = util.parsedate(date)
2269 d = util.parsedate(date)
2265 ui.write(("internal: %s %s\n") % d)
2270 ui.write(("internal: %s %s\n") % d)
2266 ui.write(("standard: %s\n") % util.datestr(d))
2271 ui.write(("standard: %s\n") % util.datestr(d))
2267 if range:
2272 if range:
2268 m = util.matchdate(range)
2273 m = util.matchdate(range)
2269 ui.write(("match: %s\n") % m(d[0]))
2274 ui.write(("match: %s\n") % m(d[0]))
2270
2275
2271 @command('debugdiscovery',
2276 @command('debugdiscovery',
2272 [('', 'old', None, _('use old-style discovery')),
2277 [('', 'old', None, _('use old-style discovery')),
2273 ('', 'nonheads', None,
2278 ('', 'nonheads', None,
2274 _('use old-style discovery with non-heads included')),
2279 _('use old-style discovery with non-heads included')),
2275 ] + remoteopts,
2280 ] + remoteopts,
2276 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
2281 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
2277 def debugdiscovery(ui, repo, remoteurl="default", **opts):
2282 def debugdiscovery(ui, repo, remoteurl="default", **opts):
2278 """runs the changeset discovery protocol in isolation"""
2283 """runs the changeset discovery protocol in isolation"""
2279 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
2284 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
2280 opts.get('branch'))
2285 opts.get('branch'))
2281 remote = hg.peer(repo, opts, remoteurl)
2286 remote = hg.peer(repo, opts, remoteurl)
2282 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
2287 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
2283
2288
2284 # make sure tests are repeatable
2289 # make sure tests are repeatable
2285 random.seed(12323)
2290 random.seed(12323)
2286
2291
2287 def doit(localheads, remoteheads, remote=remote):
2292 def doit(localheads, remoteheads, remote=remote):
2288 if opts.get('old'):
2293 if opts.get('old'):
2289 if localheads:
2294 if localheads:
2290 raise error.Abort('cannot use localheads with old style '
2295 raise error.Abort('cannot use localheads with old style '
2291 'discovery')
2296 'discovery')
2292 if not util.safehasattr(remote, 'branches'):
2297 if not util.safehasattr(remote, 'branches'):
2293 # enable in-client legacy support
2298 # enable in-client legacy support
2294 remote = localrepo.locallegacypeer(remote.local())
2299 remote = localrepo.locallegacypeer(remote.local())
2295 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
2300 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
2296 force=True)
2301 force=True)
2297 common = set(common)
2302 common = set(common)
2298 if not opts.get('nonheads'):
2303 if not opts.get('nonheads'):
2299 ui.write(("unpruned common: %s\n") %
2304 ui.write(("unpruned common: %s\n") %
2300 " ".join(sorted(short(n) for n in common)))
2305 " ".join(sorted(short(n) for n in common)))
2301 dag = dagutil.revlogdag(repo.changelog)
2306 dag = dagutil.revlogdag(repo.changelog)
2302 all = dag.ancestorset(dag.internalizeall(common))
2307 all = dag.ancestorset(dag.internalizeall(common))
2303 common = dag.externalizeall(dag.headsetofconnecteds(all))
2308 common = dag.externalizeall(dag.headsetofconnecteds(all))
2304 else:
2309 else:
2305 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
2310 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
2306 common = set(common)
2311 common = set(common)
2307 rheads = set(hds)
2312 rheads = set(hds)
2308 lheads = set(repo.heads())
2313 lheads = set(repo.heads())
2309 ui.write(("common heads: %s\n") %
2314 ui.write(("common heads: %s\n") %
2310 " ".join(sorted(short(n) for n in common)))
2315 " ".join(sorted(short(n) for n in common)))
2311 if lheads <= common:
2316 if lheads <= common:
2312 ui.write(("local is subset\n"))
2317 ui.write(("local is subset\n"))
2313 elif rheads <= common:
2318 elif rheads <= common:
2314 ui.write(("remote is subset\n"))
2319 ui.write(("remote is subset\n"))
2315
2320
2316 serverlogs = opts.get('serverlog')
2321 serverlogs = opts.get('serverlog')
2317 if serverlogs:
2322 if serverlogs:
2318 for filename in serverlogs:
2323 for filename in serverlogs:
2319 with open(filename, 'r') as logfile:
2324 with open(filename, 'r') as logfile:
2320 line = logfile.readline()
2325 line = logfile.readline()
2321 while line:
2326 while line:
2322 parts = line.strip().split(';')
2327 parts = line.strip().split(';')
2323 op = parts[1]
2328 op = parts[1]
2324 if op == 'cg':
2329 if op == 'cg':
2325 pass
2330 pass
2326 elif op == 'cgss':
2331 elif op == 'cgss':
2327 doit(parts[2].split(' '), parts[3].split(' '))
2332 doit(parts[2].split(' '), parts[3].split(' '))
2328 elif op == 'unb':
2333 elif op == 'unb':
2329 doit(parts[3].split(' '), parts[2].split(' '))
2334 doit(parts[3].split(' '), parts[2].split(' '))
2330 line = logfile.readline()
2335 line = logfile.readline()
2331 else:
2336 else:
2332 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2337 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2333 opts.get('remote_head'))
2338 opts.get('remote_head'))
2334 localrevs = opts.get('local_head')
2339 localrevs = opts.get('local_head')
2335 doit(localrevs, remoterevs)
2340 doit(localrevs, remoterevs)
2336
2341
2337 @command('debugextensions', formatteropts, [], norepo=True)
2342 @command('debugextensions', formatteropts, [], norepo=True)
2338 def debugextensions(ui, **opts):
2343 def debugextensions(ui, **opts):
2339 '''show information about active extensions'''
2344 '''show information about active extensions'''
2340 exts = extensions.extensions(ui)
2345 exts = extensions.extensions(ui)
2341 fm = ui.formatter('debugextensions', opts)
2346 fm = ui.formatter('debugextensions', opts)
2342 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
2347 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
2343 extsource = extmod.__file__
2348 extsource = extmod.__file__
2344 exttestedwith = getattr(extmod, 'testedwith', None)
2349 exttestedwith = getattr(extmod, 'testedwith', None)
2345 if exttestedwith is not None:
2350 if exttestedwith is not None:
2346 exttestedwith = exttestedwith.split()
2351 exttestedwith = exttestedwith.split()
2347 extbuglink = getattr(extmod, 'buglink', None)
2352 extbuglink = getattr(extmod, 'buglink', None)
2348
2353
2349 fm.startitem()
2354 fm.startitem()
2350
2355
2351 if ui.quiet or ui.verbose:
2356 if ui.quiet or ui.verbose:
2352 fm.write('name', '%s\n', extname)
2357 fm.write('name', '%s\n', extname)
2353 else:
2358 else:
2354 fm.write('name', '%s', extname)
2359 fm.write('name', '%s', extname)
2355 if not exttestedwith:
2360 if not exttestedwith:
2356 fm.plain(_(' (untested!)\n'))
2361 fm.plain(_(' (untested!)\n'))
2357 else:
2362 else:
2358 if exttestedwith == ['internal'] or \
2363 if exttestedwith == ['internal'] or \
2359 util.version() in exttestedwith:
2364 util.version() in exttestedwith:
2360 fm.plain('\n')
2365 fm.plain('\n')
2361 else:
2366 else:
2362 lasttestedversion = exttestedwith[-1]
2367 lasttestedversion = exttestedwith[-1]
2363 fm.plain(' (%s!)\n' % lasttestedversion)
2368 fm.plain(' (%s!)\n' % lasttestedversion)
2364
2369
2365 fm.condwrite(ui.verbose and extsource, 'source',
2370 fm.condwrite(ui.verbose and extsource, 'source',
2366 _(' location: %s\n'), extsource or "")
2371 _(' location: %s\n'), extsource or "")
2367
2372
2368 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
2373 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
2369 _(' tested with: %s\n'), ' '.join(exttestedwith or []))
2374 _(' tested with: %s\n'), ' '.join(exttestedwith or []))
2370
2375
2371 fm.condwrite(ui.verbose and extbuglink, 'buglink',
2376 fm.condwrite(ui.verbose and extbuglink, 'buglink',
2372 _(' bug reporting: %s\n'), extbuglink or "")
2377 _(' bug reporting: %s\n'), extbuglink or "")
2373
2378
2374 fm.end()
2379 fm.end()
2375
2380
2376 @command('debugfileset',
2381 @command('debugfileset',
2377 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2382 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2378 _('[-r REV] FILESPEC'))
2383 _('[-r REV] FILESPEC'))
2379 def debugfileset(ui, repo, expr, **opts):
2384 def debugfileset(ui, repo, expr, **opts):
2380 '''parse and apply a fileset specification'''
2385 '''parse and apply a fileset specification'''
2381 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2386 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2382 if ui.verbose:
2387 if ui.verbose:
2383 tree = fileset.parse(expr)
2388 tree = fileset.parse(expr)
2384 ui.note(fileset.prettyformat(tree), "\n")
2389 ui.note(fileset.prettyformat(tree), "\n")
2385
2390
2386 for f in ctx.getfileset(expr):
2391 for f in ctx.getfileset(expr):
2387 ui.write("%s\n" % f)
2392 ui.write("%s\n" % f)
2388
2393
2389 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
2394 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
2390 def debugfsinfo(ui, path="."):
2395 def debugfsinfo(ui, path="."):
2391 """show information detected about current filesystem"""
2396 """show information detected about current filesystem"""
2392 util.writefile('.debugfsinfo', '')
2397 util.writefile('.debugfsinfo', '')
2393 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2398 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2394 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2399 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2395 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2400 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2396 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2401 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2397 and 'yes' or 'no'))
2402 and 'yes' or 'no'))
2398 os.unlink('.debugfsinfo')
2403 os.unlink('.debugfsinfo')
2399
2404
2400 @command('debuggetbundle',
2405 @command('debuggetbundle',
2401 [('H', 'head', [], _('id of head node'), _('ID')),
2406 [('H', 'head', [], _('id of head node'), _('ID')),
2402 ('C', 'common', [], _('id of common node'), _('ID')),
2407 ('C', 'common', [], _('id of common node'), _('ID')),
2403 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2408 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2404 _('REPO FILE [-H|-C ID]...'),
2409 _('REPO FILE [-H|-C ID]...'),
2405 norepo=True)
2410 norepo=True)
2406 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2411 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2407 """retrieves a bundle from a repo
2412 """retrieves a bundle from a repo
2408
2413
2409 Every ID must be a full-length hex node id string. Saves the bundle to the
2414 Every ID must be a full-length hex node id string. Saves the bundle to the
2410 given file.
2415 given file.
2411 """
2416 """
2412 repo = hg.peer(ui, opts, repopath)
2417 repo = hg.peer(ui, opts, repopath)
2413 if not repo.capable('getbundle'):
2418 if not repo.capable('getbundle'):
2414 raise error.Abort("getbundle() not supported by target repository")
2419 raise error.Abort("getbundle() not supported by target repository")
2415 args = {}
2420 args = {}
2416 if common:
2421 if common:
2417 args['common'] = [bin(s) for s in common]
2422 args['common'] = [bin(s) for s in common]
2418 if head:
2423 if head:
2419 args['heads'] = [bin(s) for s in head]
2424 args['heads'] = [bin(s) for s in head]
2420 # TODO: get desired bundlecaps from command line.
2425 # TODO: get desired bundlecaps from command line.
2421 args['bundlecaps'] = None
2426 args['bundlecaps'] = None
2422 bundle = repo.getbundle('debug', **args)
2427 bundle = repo.getbundle('debug', **args)
2423
2428
2424 bundletype = opts.get('type', 'bzip2').lower()
2429 bundletype = opts.get('type', 'bzip2').lower()
2425 btypes = {'none': 'HG10UN',
2430 btypes = {'none': 'HG10UN',
2426 'bzip2': 'HG10BZ',
2431 'bzip2': 'HG10BZ',
2427 'gzip': 'HG10GZ',
2432 'gzip': 'HG10GZ',
2428 'bundle2': 'HG20'}
2433 'bundle2': 'HG20'}
2429 bundletype = btypes.get(bundletype)
2434 bundletype = btypes.get(bundletype)
2430 if bundletype not in changegroup.bundletypes:
2435 if bundletype not in changegroup.bundletypes:
2431 raise error.Abort(_('unknown bundle type specified with --type'))
2436 raise error.Abort(_('unknown bundle type specified with --type'))
2432 changegroup.writebundle(ui, bundle, bundlepath, bundletype)
2437 changegroup.writebundle(ui, bundle, bundlepath, bundletype)
2433
2438
2434 @command('debugignore', [], '[FILE]')
2439 @command('debugignore', [], '[FILE]')
2435 def debugignore(ui, repo, *files, **opts):
2440 def debugignore(ui, repo, *files, **opts):
2436 """display the combined ignore pattern and information about ignored files
2441 """display the combined ignore pattern and information about ignored files
2437
2442
2438 With no argument display the combined ignore pattern.
2443 With no argument display the combined ignore pattern.
2439
2444
2440 Given space separated file names, shows if the given file is ignored and
2445 Given space separated file names, shows if the given file is ignored and
2441 if so, show the ignore rule (file and line number) that matched it.
2446 if so, show the ignore rule (file and line number) that matched it.
2442 """
2447 """
2443 ignore = repo.dirstate._ignore
2448 ignore = repo.dirstate._ignore
2444 if not files:
2449 if not files:
2445 # Show all the patterns
2450 # Show all the patterns
2446 includepat = getattr(ignore, 'includepat', None)
2451 includepat = getattr(ignore, 'includepat', None)
2447 if includepat is not None:
2452 if includepat is not None:
2448 ui.write("%s\n" % includepat)
2453 ui.write("%s\n" % includepat)
2449 else:
2454 else:
2450 raise error.Abort(_("no ignore patterns found"))
2455 raise error.Abort(_("no ignore patterns found"))
2451 else:
2456 else:
2452 for f in files:
2457 for f in files:
2453 ignored = None
2458 ignored = None
2454 ignoredata = None
2459 ignoredata = None
2455 if f != '.':
2460 if f != '.':
2456 if ignore(f):
2461 if ignore(f):
2457 ignored = f
2462 ignored = f
2458 ignoredata = repo.dirstate._ignorefileandline(f)
2463 ignoredata = repo.dirstate._ignorefileandline(f)
2459 else:
2464 else:
2460 for p in util.finddirs(f):
2465 for p in util.finddirs(f):
2461 if ignore(p):
2466 if ignore(p):
2462 ignored = p
2467 ignored = p
2463 ignoredata = repo.dirstate._ignorefileandline(p)
2468 ignoredata = repo.dirstate._ignorefileandline(p)
2464 break
2469 break
2465 if ignored:
2470 if ignored:
2466 if ignored == f:
2471 if ignored == f:
2467 ui.write("%s is ignored\n" % f)
2472 ui.write("%s is ignored\n" % f)
2468 else:
2473 else:
2469 ui.write("%s is ignored because of containing folder %s\n"
2474 ui.write("%s is ignored because of containing folder %s\n"
2470 % (f, ignored))
2475 % (f, ignored))
2471 ignorefile, lineno, line = ignoredata
2476 ignorefile, lineno, line = ignoredata
2472 ui.write("(ignore rule in %s, line %d: '%s')\n"
2477 ui.write("(ignore rule in %s, line %d: '%s')\n"
2473 % (ignorefile, lineno, line))
2478 % (ignorefile, lineno, line))
2474 else:
2479 else:
2475 ui.write("%s is not ignored\n" % f)
2480 ui.write("%s is not ignored\n" % f)
2476
2481
2477 @command('debugindex', debugrevlogopts +
2482 @command('debugindex', debugrevlogopts +
2478 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2483 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2479 _('[-f FORMAT] -c|-m|FILE'),
2484 _('[-f FORMAT] -c|-m|FILE'),
2480 optionalrepo=True)
2485 optionalrepo=True)
2481 def debugindex(ui, repo, file_=None, **opts):
2486 def debugindex(ui, repo, file_=None, **opts):
2482 """dump the contents of an index file"""
2487 """dump the contents of an index file"""
2483 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2488 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2484 format = opts.get('format', 0)
2489 format = opts.get('format', 0)
2485 if format not in (0, 1):
2490 if format not in (0, 1):
2486 raise error.Abort(_("unknown format %d") % format)
2491 raise error.Abort(_("unknown format %d") % format)
2487
2492
2488 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2493 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2489 if generaldelta:
2494 if generaldelta:
2490 basehdr = ' delta'
2495 basehdr = ' delta'
2491 else:
2496 else:
2492 basehdr = ' base'
2497 basehdr = ' base'
2493
2498
2494 if ui.debugflag:
2499 if ui.debugflag:
2495 shortfn = hex
2500 shortfn = hex
2496 else:
2501 else:
2497 shortfn = short
2502 shortfn = short
2498
2503
2499 # There might not be anything in r, so have a sane default
2504 # There might not be anything in r, so have a sane default
2500 idlen = 12
2505 idlen = 12
2501 for i in r:
2506 for i in r:
2502 idlen = len(shortfn(r.node(i)))
2507 idlen = len(shortfn(r.node(i)))
2503 break
2508 break
2504
2509
2505 if format == 0:
2510 if format == 0:
2506 ui.write(" rev offset length " + basehdr + " linkrev"
2511 ui.write(" rev offset length " + basehdr + " linkrev"
2507 " %s %s p2\n" % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
2512 " %s %s p2\n" % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
2508 elif format == 1:
2513 elif format == 1:
2509 ui.write(" rev flag offset length"
2514 ui.write(" rev flag offset length"
2510 " size " + basehdr + " link p1 p2"
2515 " size " + basehdr + " link p1 p2"
2511 " %s\n" % "nodeid".rjust(idlen))
2516 " %s\n" % "nodeid".rjust(idlen))
2512
2517
2513 for i in r:
2518 for i in r:
2514 node = r.node(i)
2519 node = r.node(i)
2515 if generaldelta:
2520 if generaldelta:
2516 base = r.deltaparent(i)
2521 base = r.deltaparent(i)
2517 else:
2522 else:
2518 base = r.chainbase(i)
2523 base = r.chainbase(i)
2519 if format == 0:
2524 if format == 0:
2520 try:
2525 try:
2521 pp = r.parents(node)
2526 pp = r.parents(node)
2522 except Exception:
2527 except Exception:
2523 pp = [nullid, nullid]
2528 pp = [nullid, nullid]
2524 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2529 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2525 i, r.start(i), r.length(i), base, r.linkrev(i),
2530 i, r.start(i), r.length(i), base, r.linkrev(i),
2526 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
2531 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
2527 elif format == 1:
2532 elif format == 1:
2528 pr = r.parentrevs(i)
2533 pr = r.parentrevs(i)
2529 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2534 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2530 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2535 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2531 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
2536 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
2532
2537
2533 @command('debugindexdot', debugrevlogopts,
2538 @command('debugindexdot', debugrevlogopts,
2534 _('-c|-m|FILE'), optionalrepo=True)
2539 _('-c|-m|FILE'), optionalrepo=True)
2535 def debugindexdot(ui, repo, file_=None, **opts):
2540 def debugindexdot(ui, repo, file_=None, **opts):
2536 """dump an index DAG as a graphviz dot file"""
2541 """dump an index DAG as a graphviz dot file"""
2537 r = cmdutil.openrevlog(repo, 'debugindexdot', file_, opts)
2542 r = cmdutil.openrevlog(repo, 'debugindexdot', file_, opts)
2538 ui.write(("digraph G {\n"))
2543 ui.write(("digraph G {\n"))
2539 for i in r:
2544 for i in r:
2540 node = r.node(i)
2545 node = r.node(i)
2541 pp = r.parents(node)
2546 pp = r.parents(node)
2542 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2547 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2543 if pp[1] != nullid:
2548 if pp[1] != nullid:
2544 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2549 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2545 ui.write("}\n")
2550 ui.write("}\n")
2546
2551
2547 @command('debugdeltachain',
2552 @command('debugdeltachain',
2548 debugrevlogopts + formatteropts,
2553 debugrevlogopts + formatteropts,
2549 _('-c|-m|FILE'),
2554 _('-c|-m|FILE'),
2550 optionalrepo=True)
2555 optionalrepo=True)
2551 def debugdeltachain(ui, repo, file_=None, **opts):
2556 def debugdeltachain(ui, repo, file_=None, **opts):
2552 """dump information about delta chains in a revlog
2557 """dump information about delta chains in a revlog
2553
2558
2554 Output can be templatized. Available template keywords are:
2559 Output can be templatized. Available template keywords are:
2555
2560
2556 rev revision number
2561 rev revision number
2557 chainid delta chain identifier (numbered by unique base)
2562 chainid delta chain identifier (numbered by unique base)
2558 chainlen delta chain length to this revision
2563 chainlen delta chain length to this revision
2559 prevrev previous revision in delta chain
2564 prevrev previous revision in delta chain
2560 deltatype role of delta / how it was computed
2565 deltatype role of delta / how it was computed
2561 compsize compressed size of revision
2566 compsize compressed size of revision
2562 uncompsize uncompressed size of revision
2567 uncompsize uncompressed size of revision
2563 chainsize total size of compressed revisions in chain
2568 chainsize total size of compressed revisions in chain
2564 chainratio total chain size divided by uncompressed revision size
2569 chainratio total chain size divided by uncompressed revision size
2565 (new delta chains typically start at ratio 2.00)
2570 (new delta chains typically start at ratio 2.00)
2566 lindist linear distance from base revision in delta chain to end
2571 lindist linear distance from base revision in delta chain to end
2567 of this revision
2572 of this revision
2568 extradist total size of revisions not part of this delta chain from
2573 extradist total size of revisions not part of this delta chain from
2569 base of delta chain to end of this revision; a measurement
2574 base of delta chain to end of this revision; a measurement
2570 of how much extra data we need to read/seek across to read
2575 of how much extra data we need to read/seek across to read
2571 the delta chain for this revision
2576 the delta chain for this revision
2572 extraratio extradist divided by chainsize; another representation of
2577 extraratio extradist divided by chainsize; another representation of
2573 how much unrelated data is needed to load this delta chain
2578 how much unrelated data is needed to load this delta chain
2574 """
2579 """
2575 r = cmdutil.openrevlog(repo, 'debugdeltachain', file_, opts)
2580 r = cmdutil.openrevlog(repo, 'debugdeltachain', file_, opts)
2576 index = r.index
2581 index = r.index
2577 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2582 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2578
2583
2579 def revinfo(rev):
2584 def revinfo(rev):
2580 e = index[rev]
2585 e = index[rev]
2581 compsize = e[1]
2586 compsize = e[1]
2582 uncompsize = e[2]
2587 uncompsize = e[2]
2583 chainsize = 0
2588 chainsize = 0
2584
2589
2585 if generaldelta:
2590 if generaldelta:
2586 if e[3] == e[5]:
2591 if e[3] == e[5]:
2587 deltatype = 'p1'
2592 deltatype = 'p1'
2588 elif e[3] == e[6]:
2593 elif e[3] == e[6]:
2589 deltatype = 'p2'
2594 deltatype = 'p2'
2590 elif e[3] == rev - 1:
2595 elif e[3] == rev - 1:
2591 deltatype = 'prev'
2596 deltatype = 'prev'
2592 elif e[3] == rev:
2597 elif e[3] == rev:
2593 deltatype = 'base'
2598 deltatype = 'base'
2594 else:
2599 else:
2595 deltatype = 'other'
2600 deltatype = 'other'
2596 else:
2601 else:
2597 if e[3] == rev:
2602 if e[3] == rev:
2598 deltatype = 'base'
2603 deltatype = 'base'
2599 else:
2604 else:
2600 deltatype = 'prev'
2605 deltatype = 'prev'
2601
2606
2602 chain = r._deltachain(rev)[0]
2607 chain = r._deltachain(rev)[0]
2603 for iterrev in chain:
2608 for iterrev in chain:
2604 e = index[iterrev]
2609 e = index[iterrev]
2605 chainsize += e[1]
2610 chainsize += e[1]
2606
2611
2607 return compsize, uncompsize, deltatype, chain, chainsize
2612 return compsize, uncompsize, deltatype, chain, chainsize
2608
2613
2609 fm = ui.formatter('debugdeltachain', opts)
2614 fm = ui.formatter('debugdeltachain', opts)
2610
2615
2611 fm.plain(' rev chain# chainlen prev delta '
2616 fm.plain(' rev chain# chainlen prev delta '
2612 'size rawsize chainsize ratio lindist extradist '
2617 'size rawsize chainsize ratio lindist extradist '
2613 'extraratio\n')
2618 'extraratio\n')
2614
2619
2615 chainbases = {}
2620 chainbases = {}
2616 for rev in r:
2621 for rev in r:
2617 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
2622 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
2618 chainbase = chain[0]
2623 chainbase = chain[0]
2619 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
2624 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
2620 basestart = r.start(chainbase)
2625 basestart = r.start(chainbase)
2621 revstart = r.start(rev)
2626 revstart = r.start(rev)
2622 lineardist = revstart + comp - basestart
2627 lineardist = revstart + comp - basestart
2623 extradist = lineardist - chainsize
2628 extradist = lineardist - chainsize
2624 try:
2629 try:
2625 prevrev = chain[-2]
2630 prevrev = chain[-2]
2626 except IndexError:
2631 except IndexError:
2627 prevrev = -1
2632 prevrev = -1
2628
2633
2629 chainratio = float(chainsize) / float(uncomp)
2634 chainratio = float(chainsize) / float(uncomp)
2630 extraratio = float(extradist) / float(chainsize)
2635 extraratio = float(extradist) / float(chainsize)
2631
2636
2632 fm.startitem()
2637 fm.startitem()
2633 fm.write('rev chainid chainlen prevrev deltatype compsize '
2638 fm.write('rev chainid chainlen prevrev deltatype compsize '
2634 'uncompsize chainsize chainratio lindist extradist '
2639 'uncompsize chainsize chainratio lindist extradist '
2635 'extraratio',
2640 'extraratio',
2636 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f\n',
2641 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f\n',
2637 rev, chainid, len(chain), prevrev, deltatype, comp,
2642 rev, chainid, len(chain), prevrev, deltatype, comp,
2638 uncomp, chainsize, chainratio, lineardist, extradist,
2643 uncomp, chainsize, chainratio, lineardist, extradist,
2639 extraratio,
2644 extraratio,
2640 rev=rev, chainid=chainid, chainlen=len(chain),
2645 rev=rev, chainid=chainid, chainlen=len(chain),
2641 prevrev=prevrev, deltatype=deltatype, compsize=comp,
2646 prevrev=prevrev, deltatype=deltatype, compsize=comp,
2642 uncompsize=uncomp, chainsize=chainsize,
2647 uncompsize=uncomp, chainsize=chainsize,
2643 chainratio=chainratio, lindist=lineardist,
2648 chainratio=chainratio, lindist=lineardist,
2644 extradist=extradist, extraratio=extraratio)
2649 extradist=extradist, extraratio=extraratio)
2645
2650
2646 fm.end()
2651 fm.end()
2647
2652
2648 @command('debuginstall', [], '', norepo=True)
2653 @command('debuginstall', [], '', norepo=True)
2649 def debuginstall(ui):
2654 def debuginstall(ui):
2650 '''test Mercurial installation
2655 '''test Mercurial installation
2651
2656
2652 Returns 0 on success.
2657 Returns 0 on success.
2653 '''
2658 '''
2654
2659
2655 def writetemp(contents):
2660 def writetemp(contents):
2656 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2661 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2657 f = os.fdopen(fd, "wb")
2662 f = os.fdopen(fd, "wb")
2658 f.write(contents)
2663 f.write(contents)
2659 f.close()
2664 f.close()
2660 return name
2665 return name
2661
2666
2662 problems = 0
2667 problems = 0
2663
2668
2664 # encoding
2669 # encoding
2665 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2670 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2666 try:
2671 try:
2667 encoding.fromlocal("test")
2672 encoding.fromlocal("test")
2668 except error.Abort as inst:
2673 except error.Abort as inst:
2669 ui.write(" %s\n" % inst)
2674 ui.write(" %s\n" % inst)
2670 ui.write(_(" (check that your locale is properly set)\n"))
2675 ui.write(_(" (check that your locale is properly set)\n"))
2671 problems += 1
2676 problems += 1
2672
2677
2673 # Python
2678 # Python
2674 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2679 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2675 ui.status(_("checking Python version (%s)\n")
2680 ui.status(_("checking Python version (%s)\n")
2676 % ("%s.%s.%s" % sys.version_info[:3]))
2681 % ("%s.%s.%s" % sys.version_info[:3]))
2677 ui.status(_("checking Python lib (%s)...\n")
2682 ui.status(_("checking Python lib (%s)...\n")
2678 % os.path.dirname(os.__file__))
2683 % os.path.dirname(os.__file__))
2679
2684
2680 # compiled modules
2685 # compiled modules
2681 ui.status(_("checking installed modules (%s)...\n")
2686 ui.status(_("checking installed modules (%s)...\n")
2682 % os.path.dirname(__file__))
2687 % os.path.dirname(__file__))
2683 try:
2688 try:
2684 import bdiff, mpatch, base85, osutil
2689 import bdiff, mpatch, base85, osutil
2685 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2690 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2686 except Exception as inst:
2691 except Exception as inst:
2687 ui.write(" %s\n" % inst)
2692 ui.write(" %s\n" % inst)
2688 ui.write(_(" One or more extensions could not be found"))
2693 ui.write(_(" One or more extensions could not be found"))
2689 ui.write(_(" (check that you compiled the extensions)\n"))
2694 ui.write(_(" (check that you compiled the extensions)\n"))
2690 problems += 1
2695 problems += 1
2691
2696
2692 # templates
2697 # templates
2693 import templater
2698 import templater
2694 p = templater.templatepaths()
2699 p = templater.templatepaths()
2695 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2700 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2696 if p:
2701 if p:
2697 m = templater.templatepath("map-cmdline.default")
2702 m = templater.templatepath("map-cmdline.default")
2698 if m:
2703 if m:
2699 # template found, check if it is working
2704 # template found, check if it is working
2700 try:
2705 try:
2701 templater.templater(m)
2706 templater.templater(m)
2702 except Exception as inst:
2707 except Exception as inst:
2703 ui.write(" %s\n" % inst)
2708 ui.write(" %s\n" % inst)
2704 p = None
2709 p = None
2705 else:
2710 else:
2706 ui.write(_(" template 'default' not found\n"))
2711 ui.write(_(" template 'default' not found\n"))
2707 p = None
2712 p = None
2708 else:
2713 else:
2709 ui.write(_(" no template directories found\n"))
2714 ui.write(_(" no template directories found\n"))
2710 if not p:
2715 if not p:
2711 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2716 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2712 problems += 1
2717 problems += 1
2713
2718
2714 # editor
2719 # editor
2715 ui.status(_("checking commit editor...\n"))
2720 ui.status(_("checking commit editor...\n"))
2716 editor = ui.geteditor()
2721 editor = ui.geteditor()
2717 editor = util.expandpath(editor)
2722 editor = util.expandpath(editor)
2718 cmdpath = util.findexe(shlex.split(editor)[0])
2723 cmdpath = util.findexe(shlex.split(editor)[0])
2719 if not cmdpath:
2724 if not cmdpath:
2720 if editor == 'vi':
2725 if editor == 'vi':
2721 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2726 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2722 ui.write(_(" (specify a commit editor in your configuration"
2727 ui.write(_(" (specify a commit editor in your configuration"
2723 " file)\n"))
2728 " file)\n"))
2724 else:
2729 else:
2725 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2730 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2726 ui.write(_(" (specify a commit editor in your configuration"
2731 ui.write(_(" (specify a commit editor in your configuration"
2727 " file)\n"))
2732 " file)\n"))
2728 problems += 1
2733 problems += 1
2729
2734
2730 # check username
2735 # check username
2731 ui.status(_("checking username...\n"))
2736 ui.status(_("checking username...\n"))
2732 try:
2737 try:
2733 ui.username()
2738 ui.username()
2734 except error.Abort as e:
2739 except error.Abort as e:
2735 ui.write(" %s\n" % e)
2740 ui.write(" %s\n" % e)
2736 ui.write(_(" (specify a username in your configuration file)\n"))
2741 ui.write(_(" (specify a username in your configuration file)\n"))
2737 problems += 1
2742 problems += 1
2738
2743
2739 if not problems:
2744 if not problems:
2740 ui.status(_("no problems detected\n"))
2745 ui.status(_("no problems detected\n"))
2741 else:
2746 else:
2742 ui.write(_("%s problems detected,"
2747 ui.write(_("%s problems detected,"
2743 " please check your install!\n") % problems)
2748 " please check your install!\n") % problems)
2744
2749
2745 return problems
2750 return problems
2746
2751
2747 @command('debugknown', [], _('REPO ID...'), norepo=True)
2752 @command('debugknown', [], _('REPO ID...'), norepo=True)
2748 def debugknown(ui, repopath, *ids, **opts):
2753 def debugknown(ui, repopath, *ids, **opts):
2749 """test whether node ids are known to a repo
2754 """test whether node ids are known to a repo
2750
2755
2751 Every ID must be a full-length hex node id string. Returns a list of 0s
2756 Every ID must be a full-length hex node id string. Returns a list of 0s
2752 and 1s indicating unknown/known.
2757 and 1s indicating unknown/known.
2753 """
2758 """
2754 repo = hg.peer(ui, opts, repopath)
2759 repo = hg.peer(ui, opts, repopath)
2755 if not repo.capable('known'):
2760 if not repo.capable('known'):
2756 raise error.Abort("known() not supported by target repository")
2761 raise error.Abort("known() not supported by target repository")
2757 flags = repo.known([bin(s) for s in ids])
2762 flags = repo.known([bin(s) for s in ids])
2758 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2763 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2759
2764
2760 @command('debuglabelcomplete', [], _('LABEL...'))
2765 @command('debuglabelcomplete', [], _('LABEL...'))
2761 def debuglabelcomplete(ui, repo, *args):
2766 def debuglabelcomplete(ui, repo, *args):
2762 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2767 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2763 debugnamecomplete(ui, repo, *args)
2768 debugnamecomplete(ui, repo, *args)
2764
2769
2765 @command('debugmergestate', [], '')
2770 @command('debugmergestate', [], '')
2766 def debugmergestate(ui, repo, *args):
2771 def debugmergestate(ui, repo, *args):
2767 """print merge state
2772 """print merge state
2768
2773
2769 Use --verbose to print out information about whether v1 or v2 merge state
2774 Use --verbose to print out information about whether v1 or v2 merge state
2770 was chosen."""
2775 was chosen."""
2771 def _hashornull(h):
2776 def _hashornull(h):
2772 if h == nullhex:
2777 if h == nullhex:
2773 return 'null'
2778 return 'null'
2774 else:
2779 else:
2775 return h
2780 return h
2776
2781
2777 def printrecords(version):
2782 def printrecords(version):
2778 ui.write(('* version %s records\n') % version)
2783 ui.write(('* version %s records\n') % version)
2779 if version == 1:
2784 if version == 1:
2780 records = v1records
2785 records = v1records
2781 else:
2786 else:
2782 records = v2records
2787 records = v2records
2783
2788
2784 for rtype, record in records:
2789 for rtype, record in records:
2785 # pretty print some record types
2790 # pretty print some record types
2786 if rtype == 'L':
2791 if rtype == 'L':
2787 ui.write(('local: %s\n') % record)
2792 ui.write(('local: %s\n') % record)
2788 elif rtype == 'O':
2793 elif rtype == 'O':
2789 ui.write(('other: %s\n') % record)
2794 ui.write(('other: %s\n') % record)
2790 elif rtype == 'm':
2795 elif rtype == 'm':
2791 driver, mdstate = record.split('\0', 1)
2796 driver, mdstate = record.split('\0', 1)
2792 ui.write(('merge driver: %s (state "%s")\n')
2797 ui.write(('merge driver: %s (state "%s")\n')
2793 % (driver, mdstate))
2798 % (driver, mdstate))
2794 elif rtype in 'FDC':
2799 elif rtype in 'FDC':
2795 r = record.split('\0')
2800 r = record.split('\0')
2796 f, state, hash, lfile, afile, anode, ofile = r[0:7]
2801 f, state, hash, lfile, afile, anode, ofile = r[0:7]
2797 if version == 1:
2802 if version == 1:
2798 onode = 'not stored in v1 format'
2803 onode = 'not stored in v1 format'
2799 flags = r[7]
2804 flags = r[7]
2800 else:
2805 else:
2801 onode, flags = r[7:9]
2806 onode, flags = r[7:9]
2802 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
2807 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
2803 % (f, rtype, state, _hashornull(hash)))
2808 % (f, rtype, state, _hashornull(hash)))
2804 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
2809 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
2805 ui.write((' ancestor path: %s (node %s)\n')
2810 ui.write((' ancestor path: %s (node %s)\n')
2806 % (afile, _hashornull(anode)))
2811 % (afile, _hashornull(anode)))
2807 ui.write((' other path: %s (node %s)\n')
2812 ui.write((' other path: %s (node %s)\n')
2808 % (ofile, _hashornull(onode)))
2813 % (ofile, _hashornull(onode)))
2809 else:
2814 else:
2810 ui.write(('unrecognized entry: %s\t%s\n')
2815 ui.write(('unrecognized entry: %s\t%s\n')
2811 % (rtype, record.replace('\0', '\t')))
2816 % (rtype, record.replace('\0', '\t')))
2812
2817
2813 # Avoid mergestate.read() since it may raise an exception for unsupported
2818 # Avoid mergestate.read() since it may raise an exception for unsupported
2814 # merge state records. We shouldn't be doing this, but this is OK since this
2819 # merge state records. We shouldn't be doing this, but this is OK since this
2815 # command is pretty low-level.
2820 # command is pretty low-level.
2816 ms = mergemod.mergestate(repo)
2821 ms = mergemod.mergestate(repo)
2817
2822
2818 # sort so that reasonable information is on top
2823 # sort so that reasonable information is on top
2819 v1records = ms._readrecordsv1()
2824 v1records = ms._readrecordsv1()
2820 v2records = ms._readrecordsv2()
2825 v2records = ms._readrecordsv2()
2821 order = 'LOm'
2826 order = 'LOm'
2822 def key(r):
2827 def key(r):
2823 idx = order.find(r[0])
2828 idx = order.find(r[0])
2824 if idx == -1:
2829 if idx == -1:
2825 return (1, r[1])
2830 return (1, r[1])
2826 else:
2831 else:
2827 return (0, idx)
2832 return (0, idx)
2828 v1records.sort(key=key)
2833 v1records.sort(key=key)
2829 v2records.sort(key=key)
2834 v2records.sort(key=key)
2830
2835
2831 if not v1records and not v2records:
2836 if not v1records and not v2records:
2832 ui.write(('no merge state found\n'))
2837 ui.write(('no merge state found\n'))
2833 elif not v2records:
2838 elif not v2records:
2834 ui.note(('no version 2 merge state\n'))
2839 ui.note(('no version 2 merge state\n'))
2835 printrecords(1)
2840 printrecords(1)
2836 elif ms._v1v2match(v1records, v2records):
2841 elif ms._v1v2match(v1records, v2records):
2837 ui.note(('v1 and v2 states match: using v2\n'))
2842 ui.note(('v1 and v2 states match: using v2\n'))
2838 printrecords(2)
2843 printrecords(2)
2839 else:
2844 else:
2840 ui.note(('v1 and v2 states mismatch: using v1\n'))
2845 ui.note(('v1 and v2 states mismatch: using v1\n'))
2841 printrecords(1)
2846 printrecords(1)
2842 if ui.verbose:
2847 if ui.verbose:
2843 printrecords(2)
2848 printrecords(2)
2844
2849
2845 @command('debugnamecomplete', [], _('NAME...'))
2850 @command('debugnamecomplete', [], _('NAME...'))
2846 def debugnamecomplete(ui, repo, *args):
2851 def debugnamecomplete(ui, repo, *args):
2847 '''complete "names" - tags, open branch names, bookmark names'''
2852 '''complete "names" - tags, open branch names, bookmark names'''
2848
2853
2849 names = set()
2854 names = set()
2850 # since we previously only listed open branches, we will handle that
2855 # since we previously only listed open branches, we will handle that
2851 # specially (after this for loop)
2856 # specially (after this for loop)
2852 for name, ns in repo.names.iteritems():
2857 for name, ns in repo.names.iteritems():
2853 if name != 'branches':
2858 if name != 'branches':
2854 names.update(ns.listnames(repo))
2859 names.update(ns.listnames(repo))
2855 names.update(tag for (tag, heads, tip, closed)
2860 names.update(tag for (tag, heads, tip, closed)
2856 in repo.branchmap().iterbranches() if not closed)
2861 in repo.branchmap().iterbranches() if not closed)
2857 completions = set()
2862 completions = set()
2858 if not args:
2863 if not args:
2859 args = ['']
2864 args = ['']
2860 for a in args:
2865 for a in args:
2861 completions.update(n for n in names if n.startswith(a))
2866 completions.update(n for n in names if n.startswith(a))
2862 ui.write('\n'.join(sorted(completions)))
2867 ui.write('\n'.join(sorted(completions)))
2863 ui.write('\n')
2868 ui.write('\n')
2864
2869
2865 @command('debuglocks',
2870 @command('debuglocks',
2866 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
2871 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
2867 ('W', 'force-wlock', None,
2872 ('W', 'force-wlock', None,
2868 _('free the working state lock (DANGEROUS)'))],
2873 _('free the working state lock (DANGEROUS)'))],
2869 _('[OPTION]...'))
2874 _('[OPTION]...'))
2870 def debuglocks(ui, repo, **opts):
2875 def debuglocks(ui, repo, **opts):
2871 """show or modify state of locks
2876 """show or modify state of locks
2872
2877
2873 By default, this command will show which locks are held. This
2878 By default, this command will show which locks are held. This
2874 includes the user and process holding the lock, the amount of time
2879 includes the user and process holding the lock, the amount of time
2875 the lock has been held, and the machine name where the process is
2880 the lock has been held, and the machine name where the process is
2876 running if it's not local.
2881 running if it's not local.
2877
2882
2878 Locks protect the integrity of Mercurial's data, so should be
2883 Locks protect the integrity of Mercurial's data, so should be
2879 treated with care. System crashes or other interruptions may cause
2884 treated with care. System crashes or other interruptions may cause
2880 locks to not be properly released, though Mercurial will usually
2885 locks to not be properly released, though Mercurial will usually
2881 detect and remove such stale locks automatically.
2886 detect and remove such stale locks automatically.
2882
2887
2883 However, detecting stale locks may not always be possible (for
2888 However, detecting stale locks may not always be possible (for
2884 instance, on a shared filesystem). Removing locks may also be
2889 instance, on a shared filesystem). Removing locks may also be
2885 blocked by filesystem permissions.
2890 blocked by filesystem permissions.
2886
2891
2887 Returns 0 if no locks are held.
2892 Returns 0 if no locks are held.
2888
2893
2889 """
2894 """
2890
2895
2891 if opts.get('force_lock'):
2896 if opts.get('force_lock'):
2892 repo.svfs.unlink('lock')
2897 repo.svfs.unlink('lock')
2893 if opts.get('force_wlock'):
2898 if opts.get('force_wlock'):
2894 repo.vfs.unlink('wlock')
2899 repo.vfs.unlink('wlock')
2895 if opts.get('force_lock') or opts.get('force_lock'):
2900 if opts.get('force_lock') or opts.get('force_lock'):
2896 return 0
2901 return 0
2897
2902
2898 now = time.time()
2903 now = time.time()
2899 held = 0
2904 held = 0
2900
2905
2901 def report(vfs, name, method):
2906 def report(vfs, name, method):
2902 # this causes stale locks to get reaped for more accurate reporting
2907 # this causes stale locks to get reaped for more accurate reporting
2903 try:
2908 try:
2904 l = method(False)
2909 l = method(False)
2905 except error.LockHeld:
2910 except error.LockHeld:
2906 l = None
2911 l = None
2907
2912
2908 if l:
2913 if l:
2909 l.release()
2914 l.release()
2910 else:
2915 else:
2911 try:
2916 try:
2912 stat = vfs.lstat(name)
2917 stat = vfs.lstat(name)
2913 age = now - stat.st_mtime
2918 age = now - stat.st_mtime
2914 user = util.username(stat.st_uid)
2919 user = util.username(stat.st_uid)
2915 locker = vfs.readlock(name)
2920 locker = vfs.readlock(name)
2916 if ":" in locker:
2921 if ":" in locker:
2917 host, pid = locker.split(':')
2922 host, pid = locker.split(':')
2918 if host == socket.gethostname():
2923 if host == socket.gethostname():
2919 locker = 'user %s, process %s' % (user, pid)
2924 locker = 'user %s, process %s' % (user, pid)
2920 else:
2925 else:
2921 locker = 'user %s, process %s, host %s' \
2926 locker = 'user %s, process %s, host %s' \
2922 % (user, pid, host)
2927 % (user, pid, host)
2923 ui.write("%-6s %s (%ds)\n" % (name + ":", locker, age))
2928 ui.write("%-6s %s (%ds)\n" % (name + ":", locker, age))
2924 return 1
2929 return 1
2925 except OSError as e:
2930 except OSError as e:
2926 if e.errno != errno.ENOENT:
2931 if e.errno != errno.ENOENT:
2927 raise
2932 raise
2928
2933
2929 ui.write("%-6s free\n" % (name + ":"))
2934 ui.write("%-6s free\n" % (name + ":"))
2930 return 0
2935 return 0
2931
2936
2932 held += report(repo.svfs, "lock", repo.lock)
2937 held += report(repo.svfs, "lock", repo.lock)
2933 held += report(repo.vfs, "wlock", repo.wlock)
2938 held += report(repo.vfs, "wlock", repo.wlock)
2934
2939
2935 return held
2940 return held
2936
2941
2937 @command('debugobsolete',
2942 @command('debugobsolete',
2938 [('', 'flags', 0, _('markers flag')),
2943 [('', 'flags', 0, _('markers flag')),
2939 ('', 'record-parents', False,
2944 ('', 'record-parents', False,
2940 _('record parent information for the precursor')),
2945 _('record parent information for the precursor')),
2941 ('r', 'rev', [], _('display markers relevant to REV')),
2946 ('r', 'rev', [], _('display markers relevant to REV')),
2942 ] + commitopts2,
2947 ] + commitopts2,
2943 _('[OBSOLETED [REPLACEMENT ...]]'))
2948 _('[OBSOLETED [REPLACEMENT ...]]'))
2944 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2949 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2945 """create arbitrary obsolete marker
2950 """create arbitrary obsolete marker
2946
2951
2947 With no arguments, displays the list of obsolescence markers."""
2952 With no arguments, displays the list of obsolescence markers."""
2948
2953
2949 def parsenodeid(s):
2954 def parsenodeid(s):
2950 try:
2955 try:
2951 # We do not use revsingle/revrange functions here to accept
2956 # We do not use revsingle/revrange functions here to accept
2952 # arbitrary node identifiers, possibly not present in the
2957 # arbitrary node identifiers, possibly not present in the
2953 # local repository.
2958 # local repository.
2954 n = bin(s)
2959 n = bin(s)
2955 if len(n) != len(nullid):
2960 if len(n) != len(nullid):
2956 raise TypeError()
2961 raise TypeError()
2957 return n
2962 return n
2958 except TypeError:
2963 except TypeError:
2959 raise error.Abort('changeset references must be full hexadecimal '
2964 raise error.Abort('changeset references must be full hexadecimal '
2960 'node identifiers')
2965 'node identifiers')
2961
2966
2962 if precursor is not None:
2967 if precursor is not None:
2963 if opts['rev']:
2968 if opts['rev']:
2964 raise error.Abort('cannot select revision when creating marker')
2969 raise error.Abort('cannot select revision when creating marker')
2965 metadata = {}
2970 metadata = {}
2966 metadata['user'] = opts['user'] or ui.username()
2971 metadata['user'] = opts['user'] or ui.username()
2967 succs = tuple(parsenodeid(succ) for succ in successors)
2972 succs = tuple(parsenodeid(succ) for succ in successors)
2968 l = repo.lock()
2973 l = repo.lock()
2969 try:
2974 try:
2970 tr = repo.transaction('debugobsolete')
2975 tr = repo.transaction('debugobsolete')
2971 try:
2976 try:
2972 date = opts.get('date')
2977 date = opts.get('date')
2973 if date:
2978 if date:
2974 date = util.parsedate(date)
2979 date = util.parsedate(date)
2975 else:
2980 else:
2976 date = None
2981 date = None
2977 prec = parsenodeid(precursor)
2982 prec = parsenodeid(precursor)
2978 parents = None
2983 parents = None
2979 if opts['record_parents']:
2984 if opts['record_parents']:
2980 if prec not in repo.unfiltered():
2985 if prec not in repo.unfiltered():
2981 raise error.Abort('cannot used --record-parents on '
2986 raise error.Abort('cannot used --record-parents on '
2982 'unknown changesets')
2987 'unknown changesets')
2983 parents = repo.unfiltered()[prec].parents()
2988 parents = repo.unfiltered()[prec].parents()
2984 parents = tuple(p.node() for p in parents)
2989 parents = tuple(p.node() for p in parents)
2985 repo.obsstore.create(tr, prec, succs, opts['flags'],
2990 repo.obsstore.create(tr, prec, succs, opts['flags'],
2986 parents=parents, date=date,
2991 parents=parents, date=date,
2987 metadata=metadata)
2992 metadata=metadata)
2988 tr.close()
2993 tr.close()
2989 except ValueError as exc:
2994 except ValueError as exc:
2990 raise error.Abort(_('bad obsmarker input: %s') % exc)
2995 raise error.Abort(_('bad obsmarker input: %s') % exc)
2991 finally:
2996 finally:
2992 tr.release()
2997 tr.release()
2993 finally:
2998 finally:
2994 l.release()
2999 l.release()
2995 else:
3000 else:
2996 if opts['rev']:
3001 if opts['rev']:
2997 revs = scmutil.revrange(repo, opts['rev'])
3002 revs = scmutil.revrange(repo, opts['rev'])
2998 nodes = [repo[r].node() for r in revs]
3003 nodes = [repo[r].node() for r in revs]
2999 markers = list(obsolete.getmarkers(repo, nodes=nodes))
3004 markers = list(obsolete.getmarkers(repo, nodes=nodes))
3000 markers.sort(key=lambda x: x._data)
3005 markers.sort(key=lambda x: x._data)
3001 else:
3006 else:
3002 markers = obsolete.getmarkers(repo)
3007 markers = obsolete.getmarkers(repo)
3003
3008
3004 for m in markers:
3009 for m in markers:
3005 cmdutil.showmarker(ui, m)
3010 cmdutil.showmarker(ui, m)
3006
3011
3007 @command('debugpathcomplete',
3012 @command('debugpathcomplete',
3008 [('f', 'full', None, _('complete an entire path')),
3013 [('f', 'full', None, _('complete an entire path')),
3009 ('n', 'normal', None, _('show only normal files')),
3014 ('n', 'normal', None, _('show only normal files')),
3010 ('a', 'added', None, _('show only added files')),
3015 ('a', 'added', None, _('show only added files')),
3011 ('r', 'removed', None, _('show only removed files'))],
3016 ('r', 'removed', None, _('show only removed files'))],
3012 _('FILESPEC...'))
3017 _('FILESPEC...'))
3013 def debugpathcomplete(ui, repo, *specs, **opts):
3018 def debugpathcomplete(ui, repo, *specs, **opts):
3014 '''complete part or all of a tracked path
3019 '''complete part or all of a tracked path
3015
3020
3016 This command supports shells that offer path name completion. It
3021 This command supports shells that offer path name completion. It
3017 currently completes only files already known to the dirstate.
3022 currently completes only files already known to the dirstate.
3018
3023
3019 Completion extends only to the next path segment unless
3024 Completion extends only to the next path segment unless
3020 --full is specified, in which case entire paths are used.'''
3025 --full is specified, in which case entire paths are used.'''
3021
3026
3022 def complete(path, acceptable):
3027 def complete(path, acceptable):
3023 dirstate = repo.dirstate
3028 dirstate = repo.dirstate
3024 spec = os.path.normpath(os.path.join(os.getcwd(), path))
3029 spec = os.path.normpath(os.path.join(os.getcwd(), path))
3025 rootdir = repo.root + os.sep
3030 rootdir = repo.root + os.sep
3026 if spec != repo.root and not spec.startswith(rootdir):
3031 if spec != repo.root and not spec.startswith(rootdir):
3027 return [], []
3032 return [], []
3028 if os.path.isdir(spec):
3033 if os.path.isdir(spec):
3029 spec += '/'
3034 spec += '/'
3030 spec = spec[len(rootdir):]
3035 spec = spec[len(rootdir):]
3031 fixpaths = os.sep != '/'
3036 fixpaths = os.sep != '/'
3032 if fixpaths:
3037 if fixpaths:
3033 spec = spec.replace(os.sep, '/')
3038 spec = spec.replace(os.sep, '/')
3034 speclen = len(spec)
3039 speclen = len(spec)
3035 fullpaths = opts['full']
3040 fullpaths = opts['full']
3036 files, dirs = set(), set()
3041 files, dirs = set(), set()
3037 adddir, addfile = dirs.add, files.add
3042 adddir, addfile = dirs.add, files.add
3038 for f, st in dirstate.iteritems():
3043 for f, st in dirstate.iteritems():
3039 if f.startswith(spec) and st[0] in acceptable:
3044 if f.startswith(spec) and st[0] in acceptable:
3040 if fixpaths:
3045 if fixpaths:
3041 f = f.replace('/', os.sep)
3046 f = f.replace('/', os.sep)
3042 if fullpaths:
3047 if fullpaths:
3043 addfile(f)
3048 addfile(f)
3044 continue
3049 continue
3045 s = f.find(os.sep, speclen)
3050 s = f.find(os.sep, speclen)
3046 if s >= 0:
3051 if s >= 0:
3047 adddir(f[:s])
3052 adddir(f[:s])
3048 else:
3053 else:
3049 addfile(f)
3054 addfile(f)
3050 return files, dirs
3055 return files, dirs
3051
3056
3052 acceptable = ''
3057 acceptable = ''
3053 if opts['normal']:
3058 if opts['normal']:
3054 acceptable += 'nm'
3059 acceptable += 'nm'
3055 if opts['added']:
3060 if opts['added']:
3056 acceptable += 'a'
3061 acceptable += 'a'
3057 if opts['removed']:
3062 if opts['removed']:
3058 acceptable += 'r'
3063 acceptable += 'r'
3059 cwd = repo.getcwd()
3064 cwd = repo.getcwd()
3060 if not specs:
3065 if not specs:
3061 specs = ['.']
3066 specs = ['.']
3062
3067
3063 files, dirs = set(), set()
3068 files, dirs = set(), set()
3064 for spec in specs:
3069 for spec in specs:
3065 f, d = complete(spec, acceptable or 'nmar')
3070 f, d = complete(spec, acceptable or 'nmar')
3066 files.update(f)
3071 files.update(f)
3067 dirs.update(d)
3072 dirs.update(d)
3068 files.update(dirs)
3073 files.update(dirs)
3069 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
3074 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
3070 ui.write('\n')
3075 ui.write('\n')
3071
3076
3072 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
3077 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
3073 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
3078 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
3074 '''access the pushkey key/value protocol
3079 '''access the pushkey key/value protocol
3075
3080
3076 With two args, list the keys in the given namespace.
3081 With two args, list the keys in the given namespace.
3077
3082
3078 With five args, set a key to new if it currently is set to old.
3083 With five args, set a key to new if it currently is set to old.
3079 Reports success or failure.
3084 Reports success or failure.
3080 '''
3085 '''
3081
3086
3082 target = hg.peer(ui, {}, repopath)
3087 target = hg.peer(ui, {}, repopath)
3083 if keyinfo:
3088 if keyinfo:
3084 key, old, new = keyinfo
3089 key, old, new = keyinfo
3085 r = target.pushkey(namespace, key, old, new)
3090 r = target.pushkey(namespace, key, old, new)
3086 ui.status(str(r) + '\n')
3091 ui.status(str(r) + '\n')
3087 return not r
3092 return not r
3088 else:
3093 else:
3089 for k, v in sorted(target.listkeys(namespace).iteritems()):
3094 for k, v in sorted(target.listkeys(namespace).iteritems()):
3090 ui.write("%s\t%s\n" % (k.encode('string-escape'),
3095 ui.write("%s\t%s\n" % (k.encode('string-escape'),
3091 v.encode('string-escape')))
3096 v.encode('string-escape')))
3092
3097
3093 @command('debugpvec', [], _('A B'))
3098 @command('debugpvec', [], _('A B'))
3094 def debugpvec(ui, repo, a, b=None):
3099 def debugpvec(ui, repo, a, b=None):
3095 ca = scmutil.revsingle(repo, a)
3100 ca = scmutil.revsingle(repo, a)
3096 cb = scmutil.revsingle(repo, b)
3101 cb = scmutil.revsingle(repo, b)
3097 pa = pvec.ctxpvec(ca)
3102 pa = pvec.ctxpvec(ca)
3098 pb = pvec.ctxpvec(cb)
3103 pb = pvec.ctxpvec(cb)
3099 if pa == pb:
3104 if pa == pb:
3100 rel = "="
3105 rel = "="
3101 elif pa > pb:
3106 elif pa > pb:
3102 rel = ">"
3107 rel = ">"
3103 elif pa < pb:
3108 elif pa < pb:
3104 rel = "<"
3109 rel = "<"
3105 elif pa | pb:
3110 elif pa | pb:
3106 rel = "|"
3111 rel = "|"
3107 ui.write(_("a: %s\n") % pa)
3112 ui.write(_("a: %s\n") % pa)
3108 ui.write(_("b: %s\n") % pb)
3113 ui.write(_("b: %s\n") % pb)
3109 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
3114 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
3110 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
3115 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
3111 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
3116 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
3112 pa.distance(pb), rel))
3117 pa.distance(pb), rel))
3113
3118
3114 @command('debugrebuilddirstate|debugrebuildstate',
3119 @command('debugrebuilddirstate|debugrebuildstate',
3115 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
3120 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
3116 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
3121 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
3117 'the working copy parent')),
3122 'the working copy parent')),
3118 ],
3123 ],
3119 _('[-r REV]'))
3124 _('[-r REV]'))
3120 def debugrebuilddirstate(ui, repo, rev, **opts):
3125 def debugrebuilddirstate(ui, repo, rev, **opts):
3121 """rebuild the dirstate as it would look like for the given revision
3126 """rebuild the dirstate as it would look like for the given revision
3122
3127
3123 If no revision is specified the first current parent will be used.
3128 If no revision is specified the first current parent will be used.
3124
3129
3125 The dirstate will be set to the files of the given revision.
3130 The dirstate will be set to the files of the given revision.
3126 The actual working directory content or existing dirstate
3131 The actual working directory content or existing dirstate
3127 information such as adds or removes is not considered.
3132 information such as adds or removes is not considered.
3128
3133
3129 ``minimal`` will only rebuild the dirstate status for files that claim to be
3134 ``minimal`` will only rebuild the dirstate status for files that claim to be
3130 tracked but are not in the parent manifest, or that exist in the parent
3135 tracked but are not in the parent manifest, or that exist in the parent
3131 manifest but are not in the dirstate. It will not change adds, removes, or
3136 manifest but are not in the dirstate. It will not change adds, removes, or
3132 modified files that are in the working copy parent.
3137 modified files that are in the working copy parent.
3133
3138
3134 One use of this command is to make the next :hg:`status` invocation
3139 One use of this command is to make the next :hg:`status` invocation
3135 check the actual file content.
3140 check the actual file content.
3136 """
3141 """
3137 ctx = scmutil.revsingle(repo, rev)
3142 ctx = scmutil.revsingle(repo, rev)
3138 with repo.wlock():
3143 with repo.wlock():
3139 dirstate = repo.dirstate
3144 dirstate = repo.dirstate
3140 changedfiles = None
3145 changedfiles = None
3141 # See command doc for what minimal does.
3146 # See command doc for what minimal does.
3142 if opts.get('minimal'):
3147 if opts.get('minimal'):
3143 manifestfiles = set(ctx.manifest().keys())
3148 manifestfiles = set(ctx.manifest().keys())
3144 dirstatefiles = set(dirstate)
3149 dirstatefiles = set(dirstate)
3145 manifestonly = manifestfiles - dirstatefiles
3150 manifestonly = manifestfiles - dirstatefiles
3146 dsonly = dirstatefiles - manifestfiles
3151 dsonly = dirstatefiles - manifestfiles
3147 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
3152 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
3148 changedfiles = manifestonly | dsnotadded
3153 changedfiles = manifestonly | dsnotadded
3149
3154
3150 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
3155 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
3151
3156
3152 @command('debugrebuildfncache', [], '')
3157 @command('debugrebuildfncache', [], '')
3153 def debugrebuildfncache(ui, repo):
3158 def debugrebuildfncache(ui, repo):
3154 """rebuild the fncache file"""
3159 """rebuild the fncache file"""
3155 repair.rebuildfncache(ui, repo)
3160 repair.rebuildfncache(ui, repo)
3156
3161
3157 @command('debugrename',
3162 @command('debugrename',
3158 [('r', 'rev', '', _('revision to debug'), _('REV'))],
3163 [('r', 'rev', '', _('revision to debug'), _('REV'))],
3159 _('[-r REV] FILE'))
3164 _('[-r REV] FILE'))
3160 def debugrename(ui, repo, file1, *pats, **opts):
3165 def debugrename(ui, repo, file1, *pats, **opts):
3161 """dump rename information"""
3166 """dump rename information"""
3162
3167
3163 ctx = scmutil.revsingle(repo, opts.get('rev'))
3168 ctx = scmutil.revsingle(repo, opts.get('rev'))
3164 m = scmutil.match(ctx, (file1,) + pats, opts)
3169 m = scmutil.match(ctx, (file1,) + pats, opts)
3165 for abs in ctx.walk(m):
3170 for abs in ctx.walk(m):
3166 fctx = ctx[abs]
3171 fctx = ctx[abs]
3167 o = fctx.filelog().renamed(fctx.filenode())
3172 o = fctx.filelog().renamed(fctx.filenode())
3168 rel = m.rel(abs)
3173 rel = m.rel(abs)
3169 if o:
3174 if o:
3170 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
3175 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
3171 else:
3176 else:
3172 ui.write(_("%s not renamed\n") % rel)
3177 ui.write(_("%s not renamed\n") % rel)
3173
3178
3174 @command('debugrevlog', debugrevlogopts +
3179 @command('debugrevlog', debugrevlogopts +
3175 [('d', 'dump', False, _('dump index data'))],
3180 [('d', 'dump', False, _('dump index data'))],
3176 _('-c|-m|FILE'),
3181 _('-c|-m|FILE'),
3177 optionalrepo=True)
3182 optionalrepo=True)
3178 def debugrevlog(ui, repo, file_=None, **opts):
3183 def debugrevlog(ui, repo, file_=None, **opts):
3179 """show data and statistics about a revlog"""
3184 """show data and statistics about a revlog"""
3180 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
3185 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
3181
3186
3182 if opts.get("dump"):
3187 if opts.get("dump"):
3183 numrevs = len(r)
3188 numrevs = len(r)
3184 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
3189 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
3185 " rawsize totalsize compression heads chainlen\n")
3190 " rawsize totalsize compression heads chainlen\n")
3186 ts = 0
3191 ts = 0
3187 heads = set()
3192 heads = set()
3188
3193
3189 for rev in xrange(numrevs):
3194 for rev in xrange(numrevs):
3190 dbase = r.deltaparent(rev)
3195 dbase = r.deltaparent(rev)
3191 if dbase == -1:
3196 if dbase == -1:
3192 dbase = rev
3197 dbase = rev
3193 cbase = r.chainbase(rev)
3198 cbase = r.chainbase(rev)
3194 clen = r.chainlen(rev)
3199 clen = r.chainlen(rev)
3195 p1, p2 = r.parentrevs(rev)
3200 p1, p2 = r.parentrevs(rev)
3196 rs = r.rawsize(rev)
3201 rs = r.rawsize(rev)
3197 ts = ts + rs
3202 ts = ts + rs
3198 heads -= set(r.parentrevs(rev))
3203 heads -= set(r.parentrevs(rev))
3199 heads.add(rev)
3204 heads.add(rev)
3200 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
3205 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
3201 "%11d %5d %8d\n" %
3206 "%11d %5d %8d\n" %
3202 (rev, p1, p2, r.start(rev), r.end(rev),
3207 (rev, p1, p2, r.start(rev), r.end(rev),
3203 r.start(dbase), r.start(cbase),
3208 r.start(dbase), r.start(cbase),
3204 r.start(p1), r.start(p2),
3209 r.start(p1), r.start(p2),
3205 rs, ts, ts / r.end(rev), len(heads), clen))
3210 rs, ts, ts / r.end(rev), len(heads), clen))
3206 return 0
3211 return 0
3207
3212
3208 v = r.version
3213 v = r.version
3209 format = v & 0xFFFF
3214 format = v & 0xFFFF
3210 flags = []
3215 flags = []
3211 gdelta = False
3216 gdelta = False
3212 if v & revlog.REVLOGNGINLINEDATA:
3217 if v & revlog.REVLOGNGINLINEDATA:
3213 flags.append('inline')
3218 flags.append('inline')
3214 if v & revlog.REVLOGGENERALDELTA:
3219 if v & revlog.REVLOGGENERALDELTA:
3215 gdelta = True
3220 gdelta = True
3216 flags.append('generaldelta')
3221 flags.append('generaldelta')
3217 if not flags:
3222 if not flags:
3218 flags = ['(none)']
3223 flags = ['(none)']
3219
3224
3220 nummerges = 0
3225 nummerges = 0
3221 numfull = 0
3226 numfull = 0
3222 numprev = 0
3227 numprev = 0
3223 nump1 = 0
3228 nump1 = 0
3224 nump2 = 0
3229 nump2 = 0
3225 numother = 0
3230 numother = 0
3226 nump1prev = 0
3231 nump1prev = 0
3227 nump2prev = 0
3232 nump2prev = 0
3228 chainlengths = []
3233 chainlengths = []
3229
3234
3230 datasize = [None, 0, 0L]
3235 datasize = [None, 0, 0L]
3231 fullsize = [None, 0, 0L]
3236 fullsize = [None, 0, 0L]
3232 deltasize = [None, 0, 0L]
3237 deltasize = [None, 0, 0L]
3233
3238
3234 def addsize(size, l):
3239 def addsize(size, l):
3235 if l[0] is None or size < l[0]:
3240 if l[0] is None or size < l[0]:
3236 l[0] = size
3241 l[0] = size
3237 if size > l[1]:
3242 if size > l[1]:
3238 l[1] = size
3243 l[1] = size
3239 l[2] += size
3244 l[2] += size
3240
3245
3241 numrevs = len(r)
3246 numrevs = len(r)
3242 for rev in xrange(numrevs):
3247 for rev in xrange(numrevs):
3243 p1, p2 = r.parentrevs(rev)
3248 p1, p2 = r.parentrevs(rev)
3244 delta = r.deltaparent(rev)
3249 delta = r.deltaparent(rev)
3245 if format > 0:
3250 if format > 0:
3246 addsize(r.rawsize(rev), datasize)
3251 addsize(r.rawsize(rev), datasize)
3247 if p2 != nullrev:
3252 if p2 != nullrev:
3248 nummerges += 1
3253 nummerges += 1
3249 size = r.length(rev)
3254 size = r.length(rev)
3250 if delta == nullrev:
3255 if delta == nullrev:
3251 chainlengths.append(0)
3256 chainlengths.append(0)
3252 numfull += 1
3257 numfull += 1
3253 addsize(size, fullsize)
3258 addsize(size, fullsize)
3254 else:
3259 else:
3255 chainlengths.append(chainlengths[delta] + 1)
3260 chainlengths.append(chainlengths[delta] + 1)
3256 addsize(size, deltasize)
3261 addsize(size, deltasize)
3257 if delta == rev - 1:
3262 if delta == rev - 1:
3258 numprev += 1
3263 numprev += 1
3259 if delta == p1:
3264 if delta == p1:
3260 nump1prev += 1
3265 nump1prev += 1
3261 elif delta == p2:
3266 elif delta == p2:
3262 nump2prev += 1
3267 nump2prev += 1
3263 elif delta == p1:
3268 elif delta == p1:
3264 nump1 += 1
3269 nump1 += 1
3265 elif delta == p2:
3270 elif delta == p2:
3266 nump2 += 1
3271 nump2 += 1
3267 elif delta != nullrev:
3272 elif delta != nullrev:
3268 numother += 1
3273 numother += 1
3269
3274
3270 # Adjust size min value for empty cases
3275 # Adjust size min value for empty cases
3271 for size in (datasize, fullsize, deltasize):
3276 for size in (datasize, fullsize, deltasize):
3272 if size[0] is None:
3277 if size[0] is None:
3273 size[0] = 0
3278 size[0] = 0
3274
3279
3275 numdeltas = numrevs - numfull
3280 numdeltas = numrevs - numfull
3276 numoprev = numprev - nump1prev - nump2prev
3281 numoprev = numprev - nump1prev - nump2prev
3277 totalrawsize = datasize[2]
3282 totalrawsize = datasize[2]
3278 datasize[2] /= numrevs
3283 datasize[2] /= numrevs
3279 fulltotal = fullsize[2]
3284 fulltotal = fullsize[2]
3280 fullsize[2] /= numfull
3285 fullsize[2] /= numfull
3281 deltatotal = deltasize[2]
3286 deltatotal = deltasize[2]
3282 if numrevs - numfull > 0:
3287 if numrevs - numfull > 0:
3283 deltasize[2] /= numrevs - numfull
3288 deltasize[2] /= numrevs - numfull
3284 totalsize = fulltotal + deltatotal
3289 totalsize = fulltotal + deltatotal
3285 avgchainlen = sum(chainlengths) / numrevs
3290 avgchainlen = sum(chainlengths) / numrevs
3286 maxchainlen = max(chainlengths)
3291 maxchainlen = max(chainlengths)
3287 compratio = 1
3292 compratio = 1
3288 if totalsize:
3293 if totalsize:
3289 compratio = totalrawsize / totalsize
3294 compratio = totalrawsize / totalsize
3290
3295
3291 basedfmtstr = '%%%dd\n'
3296 basedfmtstr = '%%%dd\n'
3292 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
3297 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
3293
3298
3294 def dfmtstr(max):
3299 def dfmtstr(max):
3295 return basedfmtstr % len(str(max))
3300 return basedfmtstr % len(str(max))
3296 def pcfmtstr(max, padding=0):
3301 def pcfmtstr(max, padding=0):
3297 return basepcfmtstr % (len(str(max)), ' ' * padding)
3302 return basepcfmtstr % (len(str(max)), ' ' * padding)
3298
3303
3299 def pcfmt(value, total):
3304 def pcfmt(value, total):
3300 if total:
3305 if total:
3301 return (value, 100 * float(value) / total)
3306 return (value, 100 * float(value) / total)
3302 else:
3307 else:
3303 return value, 100.0
3308 return value, 100.0
3304
3309
3305 ui.write(('format : %d\n') % format)
3310 ui.write(('format : %d\n') % format)
3306 ui.write(('flags : %s\n') % ', '.join(flags))
3311 ui.write(('flags : %s\n') % ', '.join(flags))
3307
3312
3308 ui.write('\n')
3313 ui.write('\n')
3309 fmt = pcfmtstr(totalsize)
3314 fmt = pcfmtstr(totalsize)
3310 fmt2 = dfmtstr(totalsize)
3315 fmt2 = dfmtstr(totalsize)
3311 ui.write(('revisions : ') + fmt2 % numrevs)
3316 ui.write(('revisions : ') + fmt2 % numrevs)
3312 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
3317 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
3313 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
3318 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
3314 ui.write(('revisions : ') + fmt2 % numrevs)
3319 ui.write(('revisions : ') + fmt2 % numrevs)
3315 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
3320 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
3316 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
3321 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
3317 ui.write(('revision size : ') + fmt2 % totalsize)
3322 ui.write(('revision size : ') + fmt2 % totalsize)
3318 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
3323 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
3319 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
3324 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
3320
3325
3321 ui.write('\n')
3326 ui.write('\n')
3322 fmt = dfmtstr(max(avgchainlen, compratio))
3327 fmt = dfmtstr(max(avgchainlen, compratio))
3323 ui.write(('avg chain length : ') + fmt % avgchainlen)
3328 ui.write(('avg chain length : ') + fmt % avgchainlen)
3324 ui.write(('max chain length : ') + fmt % maxchainlen)
3329 ui.write(('max chain length : ') + fmt % maxchainlen)
3325 ui.write(('compression ratio : ') + fmt % compratio)
3330 ui.write(('compression ratio : ') + fmt % compratio)
3326
3331
3327 if format > 0:
3332 if format > 0:
3328 ui.write('\n')
3333 ui.write('\n')
3329 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
3334 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
3330 % tuple(datasize))
3335 % tuple(datasize))
3331 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
3336 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
3332 % tuple(fullsize))
3337 % tuple(fullsize))
3333 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
3338 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
3334 % tuple(deltasize))
3339 % tuple(deltasize))
3335
3340
3336 if numdeltas > 0:
3341 if numdeltas > 0:
3337 ui.write('\n')
3342 ui.write('\n')
3338 fmt = pcfmtstr(numdeltas)
3343 fmt = pcfmtstr(numdeltas)
3339 fmt2 = pcfmtstr(numdeltas, 4)
3344 fmt2 = pcfmtstr(numdeltas, 4)
3340 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
3345 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
3341 if numprev > 0:
3346 if numprev > 0:
3342 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
3347 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
3343 numprev))
3348 numprev))
3344 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
3349 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
3345 numprev))
3350 numprev))
3346 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
3351 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
3347 numprev))
3352 numprev))
3348 if gdelta:
3353 if gdelta:
3349 ui.write(('deltas against p1 : ')
3354 ui.write(('deltas against p1 : ')
3350 + fmt % pcfmt(nump1, numdeltas))
3355 + fmt % pcfmt(nump1, numdeltas))
3351 ui.write(('deltas against p2 : ')
3356 ui.write(('deltas against p2 : ')
3352 + fmt % pcfmt(nump2, numdeltas))
3357 + fmt % pcfmt(nump2, numdeltas))
3353 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
3358 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
3354 numdeltas))
3359 numdeltas))
3355
3360
3356 @command('debugrevspec',
3361 @command('debugrevspec',
3357 [('', 'optimize', None, _('print parsed tree after optimizing'))],
3362 [('', 'optimize', None, _('print parsed tree after optimizing'))],
3358 ('REVSPEC'))
3363 ('REVSPEC'))
3359 def debugrevspec(ui, repo, expr, **opts):
3364 def debugrevspec(ui, repo, expr, **opts):
3360 """parse and apply a revision specification
3365 """parse and apply a revision specification
3361
3366
3362 Use --verbose to print the parsed tree before and after aliases
3367 Use --verbose to print the parsed tree before and after aliases
3363 expansion.
3368 expansion.
3364 """
3369 """
3365 if ui.verbose:
3370 if ui.verbose:
3366 tree = revset.parse(expr, lookup=repo.__contains__)
3371 tree = revset.parse(expr, lookup=repo.__contains__)
3367 ui.note(revset.prettyformat(tree), "\n")
3372 ui.note(revset.prettyformat(tree), "\n")
3368 newtree = revset.findaliases(ui, tree)
3373 newtree = revset.findaliases(ui, tree)
3369 if newtree != tree:
3374 if newtree != tree:
3370 ui.note(revset.prettyformat(newtree), "\n")
3375 ui.note(revset.prettyformat(newtree), "\n")
3371 tree = newtree
3376 tree = newtree
3372 newtree = revset.foldconcat(tree)
3377 newtree = revset.foldconcat(tree)
3373 if newtree != tree:
3378 if newtree != tree:
3374 ui.note(revset.prettyformat(newtree), "\n")
3379 ui.note(revset.prettyformat(newtree), "\n")
3375 if opts["optimize"]:
3380 if opts["optimize"]:
3376 weight, optimizedtree = revset.optimize(newtree, True)
3381 weight, optimizedtree = revset.optimize(newtree, True)
3377 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
3382 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
3378 func = revset.match(ui, expr, repo)
3383 func = revset.match(ui, expr, repo)
3379 revs = func(repo)
3384 revs = func(repo)
3380 if ui.verbose:
3385 if ui.verbose:
3381 ui.note("* set:\n", revset.prettyformatset(revs), "\n")
3386 ui.note("* set:\n", revset.prettyformatset(revs), "\n")
3382 for c in revs:
3387 for c in revs:
3383 ui.write("%s\n" % c)
3388 ui.write("%s\n" % c)
3384
3389
3385 @command('debugsetparents', [], _('REV1 [REV2]'))
3390 @command('debugsetparents', [], _('REV1 [REV2]'))
3386 def debugsetparents(ui, repo, rev1, rev2=None):
3391 def debugsetparents(ui, repo, rev1, rev2=None):
3387 """manually set the parents of the current working directory
3392 """manually set the parents of the current working directory
3388
3393
3389 This is useful for writing repository conversion tools, but should
3394 This is useful for writing repository conversion tools, but should
3390 be used with care. For example, neither the working directory nor the
3395 be used with care. For example, neither the working directory nor the
3391 dirstate is updated, so file status may be incorrect after running this
3396 dirstate is updated, so file status may be incorrect after running this
3392 command.
3397 command.
3393
3398
3394 Returns 0 on success.
3399 Returns 0 on success.
3395 """
3400 """
3396
3401
3397 r1 = scmutil.revsingle(repo, rev1).node()
3402 r1 = scmutil.revsingle(repo, rev1).node()
3398 r2 = scmutil.revsingle(repo, rev2, 'null').node()
3403 r2 = scmutil.revsingle(repo, rev2, 'null').node()
3399
3404
3400 with repo.wlock():
3405 with repo.wlock():
3401 repo.dirstate.beginparentchange()
3406 repo.dirstate.beginparentchange()
3402 repo.setparents(r1, r2)
3407 repo.setparents(r1, r2)
3403 repo.dirstate.endparentchange()
3408 repo.dirstate.endparentchange()
3404
3409
3405 @command('debugdirstate|debugstate',
3410 @command('debugdirstate|debugstate',
3406 [('', 'nodates', None, _('do not display the saved mtime')),
3411 [('', 'nodates', None, _('do not display the saved mtime')),
3407 ('', 'datesort', None, _('sort by saved mtime'))],
3412 ('', 'datesort', None, _('sort by saved mtime'))],
3408 _('[OPTION]...'))
3413 _('[OPTION]...'))
3409 def debugstate(ui, repo, **opts):
3414 def debugstate(ui, repo, **opts):
3410 """show the contents of the current dirstate"""
3415 """show the contents of the current dirstate"""
3411
3416
3412 nodates = opts.get('nodates')
3417 nodates = opts.get('nodates')
3413 datesort = opts.get('datesort')
3418 datesort = opts.get('datesort')
3414
3419
3415 timestr = ""
3420 timestr = ""
3416 if datesort:
3421 if datesort:
3417 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
3422 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
3418 else:
3423 else:
3419 keyfunc = None # sort by filename
3424 keyfunc = None # sort by filename
3420 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
3425 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
3421 if ent[3] == -1:
3426 if ent[3] == -1:
3422 timestr = 'unset '
3427 timestr = 'unset '
3423 elif nodates:
3428 elif nodates:
3424 timestr = 'set '
3429 timestr = 'set '
3425 else:
3430 else:
3426 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
3431 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
3427 time.localtime(ent[3]))
3432 time.localtime(ent[3]))
3428 if ent[1] & 0o20000:
3433 if ent[1] & 0o20000:
3429 mode = 'lnk'
3434 mode = 'lnk'
3430 else:
3435 else:
3431 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
3436 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
3432 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
3437 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
3433 for f in repo.dirstate.copies():
3438 for f in repo.dirstate.copies():
3434 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
3439 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
3435
3440
3436 @command('debugsub',
3441 @command('debugsub',
3437 [('r', 'rev', '',
3442 [('r', 'rev', '',
3438 _('revision to check'), _('REV'))],
3443 _('revision to check'), _('REV'))],
3439 _('[-r REV] [REV]'))
3444 _('[-r REV] [REV]'))
3440 def debugsub(ui, repo, rev=None):
3445 def debugsub(ui, repo, rev=None):
3441 ctx = scmutil.revsingle(repo, rev, None)
3446 ctx = scmutil.revsingle(repo, rev, None)
3442 for k, v in sorted(ctx.substate.items()):
3447 for k, v in sorted(ctx.substate.items()):
3443 ui.write(('path %s\n') % k)
3448 ui.write(('path %s\n') % k)
3444 ui.write((' source %s\n') % v[0])
3449 ui.write((' source %s\n') % v[0])
3445 ui.write((' revision %s\n') % v[1])
3450 ui.write((' revision %s\n') % v[1])
3446
3451
3447 @command('debugsuccessorssets',
3452 @command('debugsuccessorssets',
3448 [],
3453 [],
3449 _('[REV]'))
3454 _('[REV]'))
3450 def debugsuccessorssets(ui, repo, *revs):
3455 def debugsuccessorssets(ui, repo, *revs):
3451 """show set of successors for revision
3456 """show set of successors for revision
3452
3457
3453 A successors set of changeset A is a consistent group of revisions that
3458 A successors set of changeset A is a consistent group of revisions that
3454 succeed A. It contains non-obsolete changesets only.
3459 succeed A. It contains non-obsolete changesets only.
3455
3460
3456 In most cases a changeset A has a single successors set containing a single
3461 In most cases a changeset A has a single successors set containing a single
3457 successor (changeset A replaced by A').
3462 successor (changeset A replaced by A').
3458
3463
3459 A changeset that is made obsolete with no successors are called "pruned".
3464 A changeset that is made obsolete with no successors are called "pruned".
3460 Such changesets have no successors sets at all.
3465 Such changesets have no successors sets at all.
3461
3466
3462 A changeset that has been "split" will have a successors set containing
3467 A changeset that has been "split" will have a successors set containing
3463 more than one successor.
3468 more than one successor.
3464
3469
3465 A changeset that has been rewritten in multiple different ways is called
3470 A changeset that has been rewritten in multiple different ways is called
3466 "divergent". Such changesets have multiple successor sets (each of which
3471 "divergent". Such changesets have multiple successor sets (each of which
3467 may also be split, i.e. have multiple successors).
3472 may also be split, i.e. have multiple successors).
3468
3473
3469 Results are displayed as follows::
3474 Results are displayed as follows::
3470
3475
3471 <rev1>
3476 <rev1>
3472 <successors-1A>
3477 <successors-1A>
3473 <rev2>
3478 <rev2>
3474 <successors-2A>
3479 <successors-2A>
3475 <successors-2B1> <successors-2B2> <successors-2B3>
3480 <successors-2B1> <successors-2B2> <successors-2B3>
3476
3481
3477 Here rev2 has two possible (i.e. divergent) successors sets. The first
3482 Here rev2 has two possible (i.e. divergent) successors sets. The first
3478 holds one element, whereas the second holds three (i.e. the changeset has
3483 holds one element, whereas the second holds three (i.e. the changeset has
3479 been split).
3484 been split).
3480 """
3485 """
3481 # passed to successorssets caching computation from one call to another
3486 # passed to successorssets caching computation from one call to another
3482 cache = {}
3487 cache = {}
3483 ctx2str = str
3488 ctx2str = str
3484 node2str = short
3489 node2str = short
3485 if ui.debug():
3490 if ui.debug():
3486 def ctx2str(ctx):
3491 def ctx2str(ctx):
3487 return ctx.hex()
3492 return ctx.hex()
3488 node2str = hex
3493 node2str = hex
3489 for rev in scmutil.revrange(repo, revs):
3494 for rev in scmutil.revrange(repo, revs):
3490 ctx = repo[rev]
3495 ctx = repo[rev]
3491 ui.write('%s\n'% ctx2str(ctx))
3496 ui.write('%s\n'% ctx2str(ctx))
3492 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
3497 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
3493 if succsset:
3498 if succsset:
3494 ui.write(' ')
3499 ui.write(' ')
3495 ui.write(node2str(succsset[0]))
3500 ui.write(node2str(succsset[0]))
3496 for node in succsset[1:]:
3501 for node in succsset[1:]:
3497 ui.write(' ')
3502 ui.write(' ')
3498 ui.write(node2str(node))
3503 ui.write(node2str(node))
3499 ui.write('\n')
3504 ui.write('\n')
3500
3505
3501 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'), inferrepo=True)
3506 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'), inferrepo=True)
3502 def debugwalk(ui, repo, *pats, **opts):
3507 def debugwalk(ui, repo, *pats, **opts):
3503 """show how files match on given patterns"""
3508 """show how files match on given patterns"""
3504 m = scmutil.match(repo[None], pats, opts)
3509 m = scmutil.match(repo[None], pats, opts)
3505 items = list(repo.walk(m))
3510 items = list(repo.walk(m))
3506 if not items:
3511 if not items:
3507 return
3512 return
3508 f = lambda fn: fn
3513 f = lambda fn: fn
3509 if ui.configbool('ui', 'slash') and os.sep != '/':
3514 if ui.configbool('ui', 'slash') and os.sep != '/':
3510 f = lambda fn: util.normpath(fn)
3515 f = lambda fn: util.normpath(fn)
3511 fmt = 'f %%-%ds %%-%ds %%s' % (
3516 fmt = 'f %%-%ds %%-%ds %%s' % (
3512 max([len(abs) for abs in items]),
3517 max([len(abs) for abs in items]),
3513 max([len(m.rel(abs)) for abs in items]))
3518 max([len(m.rel(abs)) for abs in items]))
3514 for abs in items:
3519 for abs in items:
3515 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
3520 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
3516 ui.write("%s\n" % line.rstrip())
3521 ui.write("%s\n" % line.rstrip())
3517
3522
3518 @command('debugwireargs',
3523 @command('debugwireargs',
3519 [('', 'three', '', 'three'),
3524 [('', 'three', '', 'three'),
3520 ('', 'four', '', 'four'),
3525 ('', 'four', '', 'four'),
3521 ('', 'five', '', 'five'),
3526 ('', 'five', '', 'five'),
3522 ] + remoteopts,
3527 ] + remoteopts,
3523 _('REPO [OPTIONS]... [ONE [TWO]]'),
3528 _('REPO [OPTIONS]... [ONE [TWO]]'),
3524 norepo=True)
3529 norepo=True)
3525 def debugwireargs(ui, repopath, *vals, **opts):
3530 def debugwireargs(ui, repopath, *vals, **opts):
3526 repo = hg.peer(ui, opts, repopath)
3531 repo = hg.peer(ui, opts, repopath)
3527 for opt in remoteopts:
3532 for opt in remoteopts:
3528 del opts[opt[1]]
3533 del opts[opt[1]]
3529 args = {}
3534 args = {}
3530 for k, v in opts.iteritems():
3535 for k, v in opts.iteritems():
3531 if v:
3536 if v:
3532 args[k] = v
3537 args[k] = v
3533 # run twice to check that we don't mess up the stream for the next command
3538 # run twice to check that we don't mess up the stream for the next command
3534 res1 = repo.debugwireargs(*vals, **args)
3539 res1 = repo.debugwireargs(*vals, **args)
3535 res2 = repo.debugwireargs(*vals, **args)
3540 res2 = repo.debugwireargs(*vals, **args)
3536 ui.write("%s\n" % res1)
3541 ui.write("%s\n" % res1)
3537 if res1 != res2:
3542 if res1 != res2:
3538 ui.warn("%s\n" % res2)
3543 ui.warn("%s\n" % res2)
3539
3544
3540 @command('^diff',
3545 @command('^diff',
3541 [('r', 'rev', [], _('revision'), _('REV')),
3546 [('r', 'rev', [], _('revision'), _('REV')),
3542 ('c', 'change', '', _('change made by revision'), _('REV'))
3547 ('c', 'change', '', _('change made by revision'), _('REV'))
3543 ] + diffopts + diffopts2 + walkopts + subrepoopts,
3548 ] + diffopts + diffopts2 + walkopts + subrepoopts,
3544 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
3549 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
3545 inferrepo=True)
3550 inferrepo=True)
3546 def diff(ui, repo, *pats, **opts):
3551 def diff(ui, repo, *pats, **opts):
3547 """diff repository (or selected files)
3552 """diff repository (or selected files)
3548
3553
3549 Show differences between revisions for the specified files.
3554 Show differences between revisions for the specified files.
3550
3555
3551 Differences between files are shown using the unified diff format.
3556 Differences between files are shown using the unified diff format.
3552
3557
3553 .. note::
3558 .. note::
3554
3559
3555 :hg:`diff` may generate unexpected results for merges, as it will
3560 :hg:`diff` may generate unexpected results for merges, as it will
3556 default to comparing against the working directory's first
3561 default to comparing against the working directory's first
3557 parent changeset if no revisions are specified.
3562 parent changeset if no revisions are specified.
3558
3563
3559 When two revision arguments are given, then changes are shown
3564 When two revision arguments are given, then changes are shown
3560 between those revisions. If only one revision is specified then
3565 between those revisions. If only one revision is specified then
3561 that revision is compared to the working directory, and, when no
3566 that revision is compared to the working directory, and, when no
3562 revisions are specified, the working directory files are compared
3567 revisions are specified, the working directory files are compared
3563 to its first parent.
3568 to its first parent.
3564
3569
3565 Alternatively you can specify -c/--change with a revision to see
3570 Alternatively you can specify -c/--change with a revision to see
3566 the changes in that changeset relative to its first parent.
3571 the changes in that changeset relative to its first parent.
3567
3572
3568 Without the -a/--text option, diff will avoid generating diffs of
3573 Without the -a/--text option, diff will avoid generating diffs of
3569 files it detects as binary. With -a, diff will generate a diff
3574 files it detects as binary. With -a, diff will generate a diff
3570 anyway, probably with undesirable results.
3575 anyway, probably with undesirable results.
3571
3576
3572 Use the -g/--git option to generate diffs in the git extended diff
3577 Use the -g/--git option to generate diffs in the git extended diff
3573 format. For more information, read :hg:`help diffs`.
3578 format. For more information, read :hg:`help diffs`.
3574
3579
3575 .. container:: verbose
3580 .. container:: verbose
3576
3581
3577 Examples:
3582 Examples:
3578
3583
3579 - compare a file in the current working directory to its parent::
3584 - compare a file in the current working directory to its parent::
3580
3585
3581 hg diff foo.c
3586 hg diff foo.c
3582
3587
3583 - compare two historical versions of a directory, with rename info::
3588 - compare two historical versions of a directory, with rename info::
3584
3589
3585 hg diff --git -r 1.0:1.2 lib/
3590 hg diff --git -r 1.0:1.2 lib/
3586
3591
3587 - get change stats relative to the last change on some date::
3592 - get change stats relative to the last change on some date::
3588
3593
3589 hg diff --stat -r "date('may 2')"
3594 hg diff --stat -r "date('may 2')"
3590
3595
3591 - diff all newly-added files that contain a keyword::
3596 - diff all newly-added files that contain a keyword::
3592
3597
3593 hg diff "set:added() and grep(GNU)"
3598 hg diff "set:added() and grep(GNU)"
3594
3599
3595 - compare a revision and its parents::
3600 - compare a revision and its parents::
3596
3601
3597 hg diff -c 9353 # compare against first parent
3602 hg diff -c 9353 # compare against first parent
3598 hg diff -r 9353^:9353 # same using revset syntax
3603 hg diff -r 9353^:9353 # same using revset syntax
3599 hg diff -r 9353^2:9353 # compare against the second parent
3604 hg diff -r 9353^2:9353 # compare against the second parent
3600
3605
3601 Returns 0 on success.
3606 Returns 0 on success.
3602 """
3607 """
3603
3608
3604 revs = opts.get('rev')
3609 revs = opts.get('rev')
3605 change = opts.get('change')
3610 change = opts.get('change')
3606 stat = opts.get('stat')
3611 stat = opts.get('stat')
3607 reverse = opts.get('reverse')
3612 reverse = opts.get('reverse')
3608
3613
3609 if revs and change:
3614 if revs and change:
3610 msg = _('cannot specify --rev and --change at the same time')
3615 msg = _('cannot specify --rev and --change at the same time')
3611 raise error.Abort(msg)
3616 raise error.Abort(msg)
3612 elif change:
3617 elif change:
3613 node2 = scmutil.revsingle(repo, change, None).node()
3618 node2 = scmutil.revsingle(repo, change, None).node()
3614 node1 = repo[node2].p1().node()
3619 node1 = repo[node2].p1().node()
3615 else:
3620 else:
3616 node1, node2 = scmutil.revpair(repo, revs)
3621 node1, node2 = scmutil.revpair(repo, revs)
3617
3622
3618 if reverse:
3623 if reverse:
3619 node1, node2 = node2, node1
3624 node1, node2 = node2, node1
3620
3625
3621 diffopts = patch.diffallopts(ui, opts)
3626 diffopts = patch.diffallopts(ui, opts)
3622 m = scmutil.match(repo[node2], pats, opts)
3627 m = scmutil.match(repo[node2], pats, opts)
3623 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
3628 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
3624 listsubrepos=opts.get('subrepos'),
3629 listsubrepos=opts.get('subrepos'),
3625 root=opts.get('root'))
3630 root=opts.get('root'))
3626
3631
3627 @command('^export',
3632 @command('^export',
3628 [('o', 'output', '',
3633 [('o', 'output', '',
3629 _('print output to file with formatted name'), _('FORMAT')),
3634 _('print output to file with formatted name'), _('FORMAT')),
3630 ('', 'switch-parent', None, _('diff against the second parent')),
3635 ('', 'switch-parent', None, _('diff against the second parent')),
3631 ('r', 'rev', [], _('revisions to export'), _('REV')),
3636 ('r', 'rev', [], _('revisions to export'), _('REV')),
3632 ] + diffopts,
3637 ] + diffopts,
3633 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
3638 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
3634 def export(ui, repo, *changesets, **opts):
3639 def export(ui, repo, *changesets, **opts):
3635 """dump the header and diffs for one or more changesets
3640 """dump the header and diffs for one or more changesets
3636
3641
3637 Print the changeset header and diffs for one or more revisions.
3642 Print the changeset header and diffs for one or more revisions.
3638 If no revision is given, the parent of the working directory is used.
3643 If no revision is given, the parent of the working directory is used.
3639
3644
3640 The information shown in the changeset header is: author, date,
3645 The information shown in the changeset header is: author, date,
3641 branch name (if non-default), changeset hash, parent(s) and commit
3646 branch name (if non-default), changeset hash, parent(s) and commit
3642 comment.
3647 comment.
3643
3648
3644 .. note::
3649 .. note::
3645
3650
3646 :hg:`export` may generate unexpected diff output for merge
3651 :hg:`export` may generate unexpected diff output for merge
3647 changesets, as it will compare the merge changeset against its
3652 changesets, as it will compare the merge changeset against its
3648 first parent only.
3653 first parent only.
3649
3654
3650 Output may be to a file, in which case the name of the file is
3655 Output may be to a file, in which case the name of the file is
3651 given using a format string. The formatting rules are as follows:
3656 given using a format string. The formatting rules are as follows:
3652
3657
3653 :``%%``: literal "%" character
3658 :``%%``: literal "%" character
3654 :``%H``: changeset hash (40 hexadecimal digits)
3659 :``%H``: changeset hash (40 hexadecimal digits)
3655 :``%N``: number of patches being generated
3660 :``%N``: number of patches being generated
3656 :``%R``: changeset revision number
3661 :``%R``: changeset revision number
3657 :``%b``: basename of the exporting repository
3662 :``%b``: basename of the exporting repository
3658 :``%h``: short-form changeset hash (12 hexadecimal digits)
3663 :``%h``: short-form changeset hash (12 hexadecimal digits)
3659 :``%m``: first line of the commit message (only alphanumeric characters)
3664 :``%m``: first line of the commit message (only alphanumeric characters)
3660 :``%n``: zero-padded sequence number, starting at 1
3665 :``%n``: zero-padded sequence number, starting at 1
3661 :``%r``: zero-padded changeset revision number
3666 :``%r``: zero-padded changeset revision number
3662
3667
3663 Without the -a/--text option, export will avoid generating diffs
3668 Without the -a/--text option, export will avoid generating diffs
3664 of files it detects as binary. With -a, export will generate a
3669 of files it detects as binary. With -a, export will generate a
3665 diff anyway, probably with undesirable results.
3670 diff anyway, probably with undesirable results.
3666
3671
3667 Use the -g/--git option to generate diffs in the git extended diff
3672 Use the -g/--git option to generate diffs in the git extended diff
3668 format. See :hg:`help diffs` for more information.
3673 format. See :hg:`help diffs` for more information.
3669
3674
3670 With the --switch-parent option, the diff will be against the
3675 With the --switch-parent option, the diff will be against the
3671 second parent. It can be useful to review a merge.
3676 second parent. It can be useful to review a merge.
3672
3677
3673 .. container:: verbose
3678 .. container:: verbose
3674
3679
3675 Examples:
3680 Examples:
3676
3681
3677 - use export and import to transplant a bugfix to the current
3682 - use export and import to transplant a bugfix to the current
3678 branch::
3683 branch::
3679
3684
3680 hg export -r 9353 | hg import -
3685 hg export -r 9353 | hg import -
3681
3686
3682 - export all the changesets between two revisions to a file with
3687 - export all the changesets between two revisions to a file with
3683 rename information::
3688 rename information::
3684
3689
3685 hg export --git -r 123:150 > changes.txt
3690 hg export --git -r 123:150 > changes.txt
3686
3691
3687 - split outgoing changes into a series of patches with
3692 - split outgoing changes into a series of patches with
3688 descriptive names::
3693 descriptive names::
3689
3694
3690 hg export -r "outgoing()" -o "%n-%m.patch"
3695 hg export -r "outgoing()" -o "%n-%m.patch"
3691
3696
3692 Returns 0 on success.
3697 Returns 0 on success.
3693 """
3698 """
3694 changesets += tuple(opts.get('rev', []))
3699 changesets += tuple(opts.get('rev', []))
3695 if not changesets:
3700 if not changesets:
3696 changesets = ['.']
3701 changesets = ['.']
3697 revs = scmutil.revrange(repo, changesets)
3702 revs = scmutil.revrange(repo, changesets)
3698 if not revs:
3703 if not revs:
3699 raise error.Abort(_("export requires at least one changeset"))
3704 raise error.Abort(_("export requires at least one changeset"))
3700 if len(revs) > 1:
3705 if len(revs) > 1:
3701 ui.note(_('exporting patches:\n'))
3706 ui.note(_('exporting patches:\n'))
3702 else:
3707 else:
3703 ui.note(_('exporting patch:\n'))
3708 ui.note(_('exporting patch:\n'))
3704 cmdutil.export(repo, revs, template=opts.get('output'),
3709 cmdutil.export(repo, revs, template=opts.get('output'),
3705 switch_parent=opts.get('switch_parent'),
3710 switch_parent=opts.get('switch_parent'),
3706 opts=patch.diffallopts(ui, opts))
3711 opts=patch.diffallopts(ui, opts))
3707
3712
3708 @command('files',
3713 @command('files',
3709 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3714 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3710 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3715 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3711 ] + walkopts + formatteropts + subrepoopts,
3716 ] + walkopts + formatteropts + subrepoopts,
3712 _('[OPTION]... [PATTERN]...'))
3717 _('[OPTION]... [PATTERN]...'))
3713 def files(ui, repo, *pats, **opts):
3718 def files(ui, repo, *pats, **opts):
3714 """list tracked files
3719 """list tracked files
3715
3720
3716 Print files under Mercurial control in the working directory or
3721 Print files under Mercurial control in the working directory or
3717 specified revision whose names match the given patterns (excluding
3722 specified revision whose names match the given patterns (excluding
3718 removed files).
3723 removed files).
3719
3724
3720 If no patterns are given to match, this command prints the names
3725 If no patterns are given to match, this command prints the names
3721 of all files under Mercurial control in the working directory.
3726 of all files under Mercurial control in the working directory.
3722
3727
3723 .. container:: verbose
3728 .. container:: verbose
3724
3729
3725 Examples:
3730 Examples:
3726
3731
3727 - list all files under the current directory::
3732 - list all files under the current directory::
3728
3733
3729 hg files .
3734 hg files .
3730
3735
3731 - shows sizes and flags for current revision::
3736 - shows sizes and flags for current revision::
3732
3737
3733 hg files -vr .
3738 hg files -vr .
3734
3739
3735 - list all files named README::
3740 - list all files named README::
3736
3741
3737 hg files -I "**/README"
3742 hg files -I "**/README"
3738
3743
3739 - list all binary files::
3744 - list all binary files::
3740
3745
3741 hg files "set:binary()"
3746 hg files "set:binary()"
3742
3747
3743 - find files containing a regular expression::
3748 - find files containing a regular expression::
3744
3749
3745 hg files "set:grep('bob')"
3750 hg files "set:grep('bob')"
3746
3751
3747 - search tracked file contents with xargs and grep::
3752 - search tracked file contents with xargs and grep::
3748
3753
3749 hg files -0 | xargs -0 grep foo
3754 hg files -0 | xargs -0 grep foo
3750
3755
3751 See :hg:`help patterns` and :hg:`help filesets` for more information
3756 See :hg:`help patterns` and :hg:`help filesets` for more information
3752 on specifying file patterns.
3757 on specifying file patterns.
3753
3758
3754 Returns 0 if a match is found, 1 otherwise.
3759 Returns 0 if a match is found, 1 otherwise.
3755
3760
3756 """
3761 """
3757 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3762 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3758
3763
3759 end = '\n'
3764 end = '\n'
3760 if opts.get('print0'):
3765 if opts.get('print0'):
3761 end = '\0'
3766 end = '\0'
3762 fm = ui.formatter('files', opts)
3767 fm = ui.formatter('files', opts)
3763 fmt = '%s' + end
3768 fmt = '%s' + end
3764
3769
3765 m = scmutil.match(ctx, pats, opts)
3770 m = scmutil.match(ctx, pats, opts)
3766 ret = cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
3771 ret = cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
3767
3772
3768 fm.end()
3773 fm.end()
3769
3774
3770 return ret
3775 return ret
3771
3776
3772 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
3777 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
3773 def forget(ui, repo, *pats, **opts):
3778 def forget(ui, repo, *pats, **opts):
3774 """forget the specified files on the next commit
3779 """forget the specified files on the next commit
3775
3780
3776 Mark the specified files so they will no longer be tracked
3781 Mark the specified files so they will no longer be tracked
3777 after the next commit.
3782 after the next commit.
3778
3783
3779 This only removes files from the current branch, not from the
3784 This only removes files from the current branch, not from the
3780 entire project history, and it does not delete them from the
3785 entire project history, and it does not delete them from the
3781 working directory.
3786 working directory.
3782
3787
3783 To delete the file from the working directory, see :hg:`remove`.
3788 To delete the file from the working directory, see :hg:`remove`.
3784
3789
3785 To undo a forget before the next commit, see :hg:`add`.
3790 To undo a forget before the next commit, see :hg:`add`.
3786
3791
3787 .. container:: verbose
3792 .. container:: verbose
3788
3793
3789 Examples:
3794 Examples:
3790
3795
3791 - forget newly-added binary files::
3796 - forget newly-added binary files::
3792
3797
3793 hg forget "set:added() and binary()"
3798 hg forget "set:added() and binary()"
3794
3799
3795 - forget files that would be excluded by .hgignore::
3800 - forget files that would be excluded by .hgignore::
3796
3801
3797 hg forget "set:hgignore()"
3802 hg forget "set:hgignore()"
3798
3803
3799 Returns 0 on success.
3804 Returns 0 on success.
3800 """
3805 """
3801
3806
3802 if not pats:
3807 if not pats:
3803 raise error.Abort(_('no files specified'))
3808 raise error.Abort(_('no files specified'))
3804
3809
3805 m = scmutil.match(repo[None], pats, opts)
3810 m = scmutil.match(repo[None], pats, opts)
3806 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3811 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3807 return rejected and 1 or 0
3812 return rejected and 1 or 0
3808
3813
3809 @command(
3814 @command(
3810 'graft',
3815 'graft',
3811 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3816 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3812 ('c', 'continue', False, _('resume interrupted graft')),
3817 ('c', 'continue', False, _('resume interrupted graft')),
3813 ('e', 'edit', False, _('invoke editor on commit messages')),
3818 ('e', 'edit', False, _('invoke editor on commit messages')),
3814 ('', 'log', None, _('append graft info to log message')),
3819 ('', 'log', None, _('append graft info to log message')),
3815 ('f', 'force', False, _('force graft')),
3820 ('f', 'force', False, _('force graft')),
3816 ('D', 'currentdate', False,
3821 ('D', 'currentdate', False,
3817 _('record the current date as commit date')),
3822 _('record the current date as commit date')),
3818 ('U', 'currentuser', False,
3823 ('U', 'currentuser', False,
3819 _('record the current user as committer'), _('DATE'))]
3824 _('record the current user as committer'), _('DATE'))]
3820 + commitopts2 + mergetoolopts + dryrunopts,
3825 + commitopts2 + mergetoolopts + dryrunopts,
3821 _('[OPTION]... [-r] REV...'))
3826 _('[OPTION]... [-r] REV...'))
3822 def graft(ui, repo, *revs, **opts):
3827 def graft(ui, repo, *revs, **opts):
3823 '''copy changes from other branches onto the current branch
3828 '''copy changes from other branches onto the current branch
3824
3829
3825 This command uses Mercurial's merge logic to copy individual
3830 This command uses Mercurial's merge logic to copy individual
3826 changes from other branches without merging branches in the
3831 changes from other branches without merging branches in the
3827 history graph. This is sometimes known as 'backporting' or
3832 history graph. This is sometimes known as 'backporting' or
3828 'cherry-picking'. By default, graft will copy user, date, and
3833 'cherry-picking'. By default, graft will copy user, date, and
3829 description from the source changesets.
3834 description from the source changesets.
3830
3835
3831 Changesets that are ancestors of the current revision, that have
3836 Changesets that are ancestors of the current revision, that have
3832 already been grafted, or that are merges will be skipped.
3837 already been grafted, or that are merges will be skipped.
3833
3838
3834 If --log is specified, log messages will have a comment appended
3839 If --log is specified, log messages will have a comment appended
3835 of the form::
3840 of the form::
3836
3841
3837 (grafted from CHANGESETHASH)
3842 (grafted from CHANGESETHASH)
3838
3843
3839 If --force is specified, revisions will be grafted even if they
3844 If --force is specified, revisions will be grafted even if they
3840 are already ancestors of or have been grafted to the destination.
3845 are already ancestors of or have been grafted to the destination.
3841 This is useful when the revisions have since been backed out.
3846 This is useful when the revisions have since been backed out.
3842
3847
3843 If a graft merge results in conflicts, the graft process is
3848 If a graft merge results in conflicts, the graft process is
3844 interrupted so that the current merge can be manually resolved.
3849 interrupted so that the current merge can be manually resolved.
3845 Once all conflicts are addressed, the graft process can be
3850 Once all conflicts are addressed, the graft process can be
3846 continued with the -c/--continue option.
3851 continued with the -c/--continue option.
3847
3852
3848 .. note::
3853 .. note::
3849
3854
3850 The -c/--continue option does not reapply earlier options, except
3855 The -c/--continue option does not reapply earlier options, except
3851 for --force.
3856 for --force.
3852
3857
3853 .. container:: verbose
3858 .. container:: verbose
3854
3859
3855 Examples:
3860 Examples:
3856
3861
3857 - copy a single change to the stable branch and edit its description::
3862 - copy a single change to the stable branch and edit its description::
3858
3863
3859 hg update stable
3864 hg update stable
3860 hg graft --edit 9393
3865 hg graft --edit 9393
3861
3866
3862 - graft a range of changesets with one exception, updating dates::
3867 - graft a range of changesets with one exception, updating dates::
3863
3868
3864 hg graft -D "2085::2093 and not 2091"
3869 hg graft -D "2085::2093 and not 2091"
3865
3870
3866 - continue a graft after resolving conflicts::
3871 - continue a graft after resolving conflicts::
3867
3872
3868 hg graft -c
3873 hg graft -c
3869
3874
3870 - show the source of a grafted changeset::
3875 - show the source of a grafted changeset::
3871
3876
3872 hg log --debug -r .
3877 hg log --debug -r .
3873
3878
3874 - show revisions sorted by date::
3879 - show revisions sorted by date::
3875
3880
3876 hg log -r 'sort(all(), date)'
3881 hg log -r 'sort(all(), date)'
3877
3882
3878 See :hg:`help revisions` and :hg:`help revsets` for more about
3883 See :hg:`help revisions` and :hg:`help revsets` for more about
3879 specifying revisions.
3884 specifying revisions.
3880
3885
3881 Returns 0 on successful completion.
3886 Returns 0 on successful completion.
3882 '''
3887 '''
3883 with repo.wlock():
3888 with repo.wlock():
3884 return _dograft(ui, repo, *revs, **opts)
3889 return _dograft(ui, repo, *revs, **opts)
3885
3890
3886 def _dograft(ui, repo, *revs, **opts):
3891 def _dograft(ui, repo, *revs, **opts):
3887 revs = list(revs)
3892 revs = list(revs)
3888 revs.extend(opts['rev'])
3893 revs.extend(opts['rev'])
3889
3894
3890 if not opts.get('user') and opts.get('currentuser'):
3895 if not opts.get('user') and opts.get('currentuser'):
3891 opts['user'] = ui.username()
3896 opts['user'] = ui.username()
3892 if not opts.get('date') and opts.get('currentdate'):
3897 if not opts.get('date') and opts.get('currentdate'):
3893 opts['date'] = "%d %d" % util.makedate()
3898 opts['date'] = "%d %d" % util.makedate()
3894
3899
3895 editor = cmdutil.getcommiteditor(editform='graft', **opts)
3900 editor = cmdutil.getcommiteditor(editform='graft', **opts)
3896
3901
3897 cont = False
3902 cont = False
3898 if opts['continue']:
3903 if opts['continue']:
3899 cont = True
3904 cont = True
3900 if revs:
3905 if revs:
3901 raise error.Abort(_("can't specify --continue and revisions"))
3906 raise error.Abort(_("can't specify --continue and revisions"))
3902 # read in unfinished revisions
3907 # read in unfinished revisions
3903 try:
3908 try:
3904 nodes = repo.vfs.read('graftstate').splitlines()
3909 nodes = repo.vfs.read('graftstate').splitlines()
3905 revs = [repo[node].rev() for node in nodes]
3910 revs = [repo[node].rev() for node in nodes]
3906 except IOError as inst:
3911 except IOError as inst:
3907 if inst.errno != errno.ENOENT:
3912 if inst.errno != errno.ENOENT:
3908 raise
3913 raise
3909 raise error.Abort(_("no graft state found, can't continue"))
3914 raise error.Abort(_("no graft state found, can't continue"))
3910 else:
3915 else:
3911 cmdutil.checkunfinished(repo)
3916 cmdutil.checkunfinished(repo)
3912 cmdutil.bailifchanged(repo)
3917 cmdutil.bailifchanged(repo)
3913 if not revs:
3918 if not revs:
3914 raise error.Abort(_('no revisions specified'))
3919 raise error.Abort(_('no revisions specified'))
3915 revs = scmutil.revrange(repo, revs)
3920 revs = scmutil.revrange(repo, revs)
3916
3921
3917 skipped = set()
3922 skipped = set()
3918 # check for merges
3923 # check for merges
3919 for rev in repo.revs('%ld and merge()', revs):
3924 for rev in repo.revs('%ld and merge()', revs):
3920 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3925 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3921 skipped.add(rev)
3926 skipped.add(rev)
3922 revs = [r for r in revs if r not in skipped]
3927 revs = [r for r in revs if r not in skipped]
3923 if not revs:
3928 if not revs:
3924 return -1
3929 return -1
3925
3930
3926 # Don't check in the --continue case, in effect retaining --force across
3931 # Don't check in the --continue case, in effect retaining --force across
3927 # --continues. That's because without --force, any revisions we decided to
3932 # --continues. That's because without --force, any revisions we decided to
3928 # skip would have been filtered out here, so they wouldn't have made their
3933 # skip would have been filtered out here, so they wouldn't have made their
3929 # way to the graftstate. With --force, any revisions we would have otherwise
3934 # way to the graftstate. With --force, any revisions we would have otherwise
3930 # skipped would not have been filtered out, and if they hadn't been applied
3935 # skipped would not have been filtered out, and if they hadn't been applied
3931 # already, they'd have been in the graftstate.
3936 # already, they'd have been in the graftstate.
3932 if not (cont or opts.get('force')):
3937 if not (cont or opts.get('force')):
3933 # check for ancestors of dest branch
3938 # check for ancestors of dest branch
3934 crev = repo['.'].rev()
3939 crev = repo['.'].rev()
3935 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3940 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3936 # Cannot use x.remove(y) on smart set, this has to be a list.
3941 # Cannot use x.remove(y) on smart set, this has to be a list.
3937 # XXX make this lazy in the future
3942 # XXX make this lazy in the future
3938 revs = list(revs)
3943 revs = list(revs)
3939 # don't mutate while iterating, create a copy
3944 # don't mutate while iterating, create a copy
3940 for rev in list(revs):
3945 for rev in list(revs):
3941 if rev in ancestors:
3946 if rev in ancestors:
3942 ui.warn(_('skipping ancestor revision %d:%s\n') %
3947 ui.warn(_('skipping ancestor revision %d:%s\n') %
3943 (rev, repo[rev]))
3948 (rev, repo[rev]))
3944 # XXX remove on list is slow
3949 # XXX remove on list is slow
3945 revs.remove(rev)
3950 revs.remove(rev)
3946 if not revs:
3951 if not revs:
3947 return -1
3952 return -1
3948
3953
3949 # analyze revs for earlier grafts
3954 # analyze revs for earlier grafts
3950 ids = {}
3955 ids = {}
3951 for ctx in repo.set("%ld", revs):
3956 for ctx in repo.set("%ld", revs):
3952 ids[ctx.hex()] = ctx.rev()
3957 ids[ctx.hex()] = ctx.rev()
3953 n = ctx.extra().get('source')
3958 n = ctx.extra().get('source')
3954 if n:
3959 if n:
3955 ids[n] = ctx.rev()
3960 ids[n] = ctx.rev()
3956
3961
3957 # check ancestors for earlier grafts
3962 # check ancestors for earlier grafts
3958 ui.debug('scanning for duplicate grafts\n')
3963 ui.debug('scanning for duplicate grafts\n')
3959
3964
3960 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3965 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3961 ctx = repo[rev]
3966 ctx = repo[rev]
3962 n = ctx.extra().get('source')
3967 n = ctx.extra().get('source')
3963 if n in ids:
3968 if n in ids:
3964 try:
3969 try:
3965 r = repo[n].rev()
3970 r = repo[n].rev()
3966 except error.RepoLookupError:
3971 except error.RepoLookupError:
3967 r = None
3972 r = None
3968 if r in revs:
3973 if r in revs:
3969 ui.warn(_('skipping revision %d:%s '
3974 ui.warn(_('skipping revision %d:%s '
3970 '(already grafted to %d:%s)\n')
3975 '(already grafted to %d:%s)\n')
3971 % (r, repo[r], rev, ctx))
3976 % (r, repo[r], rev, ctx))
3972 revs.remove(r)
3977 revs.remove(r)
3973 elif ids[n] in revs:
3978 elif ids[n] in revs:
3974 if r is None:
3979 if r is None:
3975 ui.warn(_('skipping already grafted revision %d:%s '
3980 ui.warn(_('skipping already grafted revision %d:%s '
3976 '(%d:%s also has unknown origin %s)\n')
3981 '(%d:%s also has unknown origin %s)\n')
3977 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
3982 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
3978 else:
3983 else:
3979 ui.warn(_('skipping already grafted revision %d:%s '
3984 ui.warn(_('skipping already grafted revision %d:%s '
3980 '(%d:%s also has origin %d:%s)\n')
3985 '(%d:%s also has origin %d:%s)\n')
3981 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
3986 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
3982 revs.remove(ids[n])
3987 revs.remove(ids[n])
3983 elif ctx.hex() in ids:
3988 elif ctx.hex() in ids:
3984 r = ids[ctx.hex()]
3989 r = ids[ctx.hex()]
3985 ui.warn(_('skipping already grafted revision %d:%s '
3990 ui.warn(_('skipping already grafted revision %d:%s '
3986 '(was grafted from %d:%s)\n') %
3991 '(was grafted from %d:%s)\n') %
3987 (r, repo[r], rev, ctx))
3992 (r, repo[r], rev, ctx))
3988 revs.remove(r)
3993 revs.remove(r)
3989 if not revs:
3994 if not revs:
3990 return -1
3995 return -1
3991
3996
3992 for pos, ctx in enumerate(repo.set("%ld", revs)):
3997 for pos, ctx in enumerate(repo.set("%ld", revs)):
3993 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
3998 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
3994 ctx.description().split('\n', 1)[0])
3999 ctx.description().split('\n', 1)[0])
3995 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
4000 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3996 if names:
4001 if names:
3997 desc += ' (%s)' % ' '.join(names)
4002 desc += ' (%s)' % ' '.join(names)
3998 ui.status(_('grafting %s\n') % desc)
4003 ui.status(_('grafting %s\n') % desc)
3999 if opts.get('dry_run'):
4004 if opts.get('dry_run'):
4000 continue
4005 continue
4001
4006
4002 extra = ctx.extra().copy()
4007 extra = ctx.extra().copy()
4003 del extra['branch']
4008 del extra['branch']
4004 source = extra.get('source')
4009 source = extra.get('source')
4005 if source:
4010 if source:
4006 extra['intermediate-source'] = ctx.hex()
4011 extra['intermediate-source'] = ctx.hex()
4007 else:
4012 else:
4008 extra['source'] = ctx.hex()
4013 extra['source'] = ctx.hex()
4009 user = ctx.user()
4014 user = ctx.user()
4010 if opts.get('user'):
4015 if opts.get('user'):
4011 user = opts['user']
4016 user = opts['user']
4012 date = ctx.date()
4017 date = ctx.date()
4013 if opts.get('date'):
4018 if opts.get('date'):
4014 date = opts['date']
4019 date = opts['date']
4015 message = ctx.description()
4020 message = ctx.description()
4016 if opts.get('log'):
4021 if opts.get('log'):
4017 message += '\n(grafted from %s)' % ctx.hex()
4022 message += '\n(grafted from %s)' % ctx.hex()
4018
4023
4019 # we don't merge the first commit when continuing
4024 # we don't merge the first commit when continuing
4020 if not cont:
4025 if not cont:
4021 # perform the graft merge with p1(rev) as 'ancestor'
4026 # perform the graft merge with p1(rev) as 'ancestor'
4022 try:
4027 try:
4023 # ui.forcemerge is an internal variable, do not document
4028 # ui.forcemerge is an internal variable, do not document
4024 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
4029 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
4025 'graft')
4030 'graft')
4026 stats = mergemod.graft(repo, ctx, ctx.p1(),
4031 stats = mergemod.graft(repo, ctx, ctx.p1(),
4027 ['local', 'graft'])
4032 ['local', 'graft'])
4028 finally:
4033 finally:
4029 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
4034 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
4030 # report any conflicts
4035 # report any conflicts
4031 if stats and stats[3] > 0:
4036 if stats and stats[3] > 0:
4032 # write out state for --continue
4037 # write out state for --continue
4033 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
4038 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
4034 repo.vfs.write('graftstate', ''.join(nodelines))
4039 repo.vfs.write('graftstate', ''.join(nodelines))
4035 extra = ''
4040 extra = ''
4036 if opts.get('user'):
4041 if opts.get('user'):
4037 extra += ' --user %s' % opts['user']
4042 extra += ' --user %s' % opts['user']
4038 if opts.get('date'):
4043 if opts.get('date'):
4039 extra += ' --date %s' % opts['date']
4044 extra += ' --date %s' % opts['date']
4040 if opts.get('log'):
4045 if opts.get('log'):
4041 extra += ' --log'
4046 extra += ' --log'
4042 hint=_('use hg resolve and hg graft --continue%s') % extra
4047 hint=_('use hg resolve and hg graft --continue%s') % extra
4043 raise error.Abort(
4048 raise error.Abort(
4044 _("unresolved conflicts, can't continue"),
4049 _("unresolved conflicts, can't continue"),
4045 hint=hint)
4050 hint=hint)
4046 else:
4051 else:
4047 cont = False
4052 cont = False
4048
4053
4049 # commit
4054 # commit
4050 node = repo.commit(text=message, user=user,
4055 node = repo.commit(text=message, user=user,
4051 date=date, extra=extra, editor=editor)
4056 date=date, extra=extra, editor=editor)
4052 if node is None:
4057 if node is None:
4053 ui.warn(
4058 ui.warn(
4054 _('note: graft of %d:%s created no changes to commit\n') %
4059 _('note: graft of %d:%s created no changes to commit\n') %
4055 (ctx.rev(), ctx))
4060 (ctx.rev(), ctx))
4056
4061
4057 # remove state when we complete successfully
4062 # remove state when we complete successfully
4058 if not opts.get('dry_run'):
4063 if not opts.get('dry_run'):
4059 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
4064 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
4060
4065
4061 return 0
4066 return 0
4062
4067
4063 @command('grep',
4068 @command('grep',
4064 [('0', 'print0', None, _('end fields with NUL')),
4069 [('0', 'print0', None, _('end fields with NUL')),
4065 ('', 'all', None, _('print all revisions that match')),
4070 ('', 'all', None, _('print all revisions that match')),
4066 ('a', 'text', None, _('treat all files as text')),
4071 ('a', 'text', None, _('treat all files as text')),
4067 ('f', 'follow', None,
4072 ('f', 'follow', None,
4068 _('follow changeset history,'
4073 _('follow changeset history,'
4069 ' or file history across copies and renames')),
4074 ' or file history across copies and renames')),
4070 ('i', 'ignore-case', None, _('ignore case when matching')),
4075 ('i', 'ignore-case', None, _('ignore case when matching')),
4071 ('l', 'files-with-matches', None,
4076 ('l', 'files-with-matches', None,
4072 _('print only filenames and revisions that match')),
4077 _('print only filenames and revisions that match')),
4073 ('n', 'line-number', None, _('print matching line numbers')),
4078 ('n', 'line-number', None, _('print matching line numbers')),
4074 ('r', 'rev', [],
4079 ('r', 'rev', [],
4075 _('only search files changed within revision range'), _('REV')),
4080 _('only search files changed within revision range'), _('REV')),
4076 ('u', 'user', None, _('list the author (long with -v)')),
4081 ('u', 'user', None, _('list the author (long with -v)')),
4077 ('d', 'date', None, _('list the date (short with -q)')),
4082 ('d', 'date', None, _('list the date (short with -q)')),
4078 ] + walkopts,
4083 ] + walkopts,
4079 _('[OPTION]... PATTERN [FILE]...'),
4084 _('[OPTION]... PATTERN [FILE]...'),
4080 inferrepo=True)
4085 inferrepo=True)
4081 def grep(ui, repo, pattern, *pats, **opts):
4086 def grep(ui, repo, pattern, *pats, **opts):
4082 """search for a pattern in specified files and revisions
4087 """search for a pattern in specified files and revisions
4083
4088
4084 Search revisions of files for a regular expression.
4089 Search revisions of files for a regular expression.
4085
4090
4086 This command behaves differently than Unix grep. It only accepts
4091 This command behaves differently than Unix grep. It only accepts
4087 Python/Perl regexps. It searches repository history, not the
4092 Python/Perl regexps. It searches repository history, not the
4088 working directory. It always prints the revision number in which a
4093 working directory. It always prints the revision number in which a
4089 match appears.
4094 match appears.
4090
4095
4091 By default, grep only prints output for the first revision of a
4096 By default, grep only prints output for the first revision of a
4092 file in which it finds a match. To get it to print every revision
4097 file in which it finds a match. To get it to print every revision
4093 that contains a change in match status ("-" for a match that
4098 that contains a change in match status ("-" for a match that
4094 becomes a non-match, or "+" for a non-match that becomes a match),
4099 becomes a non-match, or "+" for a non-match that becomes a match),
4095 use the --all flag.
4100 use the --all flag.
4096
4101
4097 Returns 0 if a match is found, 1 otherwise.
4102 Returns 0 if a match is found, 1 otherwise.
4098 """
4103 """
4099 reflags = re.M
4104 reflags = re.M
4100 if opts.get('ignore_case'):
4105 if opts.get('ignore_case'):
4101 reflags |= re.I
4106 reflags |= re.I
4102 try:
4107 try:
4103 regexp = util.re.compile(pattern, reflags)
4108 regexp = util.re.compile(pattern, reflags)
4104 except re.error as inst:
4109 except re.error as inst:
4105 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
4110 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
4106 return 1
4111 return 1
4107 sep, eol = ':', '\n'
4112 sep, eol = ':', '\n'
4108 if opts.get('print0'):
4113 if opts.get('print0'):
4109 sep = eol = '\0'
4114 sep = eol = '\0'
4110
4115
4111 getfile = util.lrucachefunc(repo.file)
4116 getfile = util.lrucachefunc(repo.file)
4112
4117
4113 def matchlines(body):
4118 def matchlines(body):
4114 begin = 0
4119 begin = 0
4115 linenum = 0
4120 linenum = 0
4116 while begin < len(body):
4121 while begin < len(body):
4117 match = regexp.search(body, begin)
4122 match = regexp.search(body, begin)
4118 if not match:
4123 if not match:
4119 break
4124 break
4120 mstart, mend = match.span()
4125 mstart, mend = match.span()
4121 linenum += body.count('\n', begin, mstart) + 1
4126 linenum += body.count('\n', begin, mstart) + 1
4122 lstart = body.rfind('\n', begin, mstart) + 1 or begin
4127 lstart = body.rfind('\n', begin, mstart) + 1 or begin
4123 begin = body.find('\n', mend) + 1 or len(body) + 1
4128 begin = body.find('\n', mend) + 1 or len(body) + 1
4124 lend = begin - 1
4129 lend = begin - 1
4125 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
4130 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
4126
4131
4127 class linestate(object):
4132 class linestate(object):
4128 def __init__(self, line, linenum, colstart, colend):
4133 def __init__(self, line, linenum, colstart, colend):
4129 self.line = line
4134 self.line = line
4130 self.linenum = linenum
4135 self.linenum = linenum
4131 self.colstart = colstart
4136 self.colstart = colstart
4132 self.colend = colend
4137 self.colend = colend
4133
4138
4134 def __hash__(self):
4139 def __hash__(self):
4135 return hash((self.linenum, self.line))
4140 return hash((self.linenum, self.line))
4136
4141
4137 def __eq__(self, other):
4142 def __eq__(self, other):
4138 return self.line == other.line
4143 return self.line == other.line
4139
4144
4140 def __iter__(self):
4145 def __iter__(self):
4141 yield (self.line[:self.colstart], '')
4146 yield (self.line[:self.colstart], '')
4142 yield (self.line[self.colstart:self.colend], 'grep.match')
4147 yield (self.line[self.colstart:self.colend], 'grep.match')
4143 rest = self.line[self.colend:]
4148 rest = self.line[self.colend:]
4144 while rest != '':
4149 while rest != '':
4145 match = regexp.search(rest)
4150 match = regexp.search(rest)
4146 if not match:
4151 if not match:
4147 yield (rest, '')
4152 yield (rest, '')
4148 break
4153 break
4149 mstart, mend = match.span()
4154 mstart, mend = match.span()
4150 yield (rest[:mstart], '')
4155 yield (rest[:mstart], '')
4151 yield (rest[mstart:mend], 'grep.match')
4156 yield (rest[mstart:mend], 'grep.match')
4152 rest = rest[mend:]
4157 rest = rest[mend:]
4153
4158
4154 matches = {}
4159 matches = {}
4155 copies = {}
4160 copies = {}
4156 def grepbody(fn, rev, body):
4161 def grepbody(fn, rev, body):
4157 matches[rev].setdefault(fn, [])
4162 matches[rev].setdefault(fn, [])
4158 m = matches[rev][fn]
4163 m = matches[rev][fn]
4159 for lnum, cstart, cend, line in matchlines(body):
4164 for lnum, cstart, cend, line in matchlines(body):
4160 s = linestate(line, lnum, cstart, cend)
4165 s = linestate(line, lnum, cstart, cend)
4161 m.append(s)
4166 m.append(s)
4162
4167
4163 def difflinestates(a, b):
4168 def difflinestates(a, b):
4164 sm = difflib.SequenceMatcher(None, a, b)
4169 sm = difflib.SequenceMatcher(None, a, b)
4165 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
4170 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
4166 if tag == 'insert':
4171 if tag == 'insert':
4167 for i in xrange(blo, bhi):
4172 for i in xrange(blo, bhi):
4168 yield ('+', b[i])
4173 yield ('+', b[i])
4169 elif tag == 'delete':
4174 elif tag == 'delete':
4170 for i in xrange(alo, ahi):
4175 for i in xrange(alo, ahi):
4171 yield ('-', a[i])
4176 yield ('-', a[i])
4172 elif tag == 'replace':
4177 elif tag == 'replace':
4173 for i in xrange(alo, ahi):
4178 for i in xrange(alo, ahi):
4174 yield ('-', a[i])
4179 yield ('-', a[i])
4175 for i in xrange(blo, bhi):
4180 for i in xrange(blo, bhi):
4176 yield ('+', b[i])
4181 yield ('+', b[i])
4177
4182
4178 def display(fn, ctx, pstates, states):
4183 def display(fn, ctx, pstates, states):
4179 rev = ctx.rev()
4184 rev = ctx.rev()
4180 if ui.quiet:
4185 if ui.quiet:
4181 datefunc = util.shortdate
4186 datefunc = util.shortdate
4182 else:
4187 else:
4183 datefunc = util.datestr
4188 datefunc = util.datestr
4184 found = False
4189 found = False
4185 @util.cachefunc
4190 @util.cachefunc
4186 def binary():
4191 def binary():
4187 flog = getfile(fn)
4192 flog = getfile(fn)
4188 return util.binary(flog.read(ctx.filenode(fn)))
4193 return util.binary(flog.read(ctx.filenode(fn)))
4189
4194
4190 if opts.get('all'):
4195 if opts.get('all'):
4191 iter = difflinestates(pstates, states)
4196 iter = difflinestates(pstates, states)
4192 else:
4197 else:
4193 iter = [('', l) for l in states]
4198 iter = [('', l) for l in states]
4194 for change, l in iter:
4199 for change, l in iter:
4195 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
4200 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
4196
4201
4197 if opts.get('line_number'):
4202 if opts.get('line_number'):
4198 cols.append((str(l.linenum), 'grep.linenumber'))
4203 cols.append((str(l.linenum), 'grep.linenumber'))
4199 if opts.get('all'):
4204 if opts.get('all'):
4200 cols.append((change, 'grep.change'))
4205 cols.append((change, 'grep.change'))
4201 if opts.get('user'):
4206 if opts.get('user'):
4202 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
4207 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
4203 if opts.get('date'):
4208 if opts.get('date'):
4204 cols.append((datefunc(ctx.date()), 'grep.date'))
4209 cols.append((datefunc(ctx.date()), 'grep.date'))
4205 for col, label in cols[:-1]:
4210 for col, label in cols[:-1]:
4206 ui.write(col, label=label)
4211 ui.write(col, label=label)
4207 ui.write(sep, label='grep.sep')
4212 ui.write(sep, label='grep.sep')
4208 ui.write(cols[-1][0], label=cols[-1][1])
4213 ui.write(cols[-1][0], label=cols[-1][1])
4209 if not opts.get('files_with_matches'):
4214 if not opts.get('files_with_matches'):
4210 ui.write(sep, label='grep.sep')
4215 ui.write(sep, label='grep.sep')
4211 if not opts.get('text') and binary():
4216 if not opts.get('text') and binary():
4212 ui.write(" Binary file matches")
4217 ui.write(" Binary file matches")
4213 else:
4218 else:
4214 for s, label in l:
4219 for s, label in l:
4215 ui.write(s, label=label)
4220 ui.write(s, label=label)
4216 ui.write(eol)
4221 ui.write(eol)
4217 found = True
4222 found = True
4218 if opts.get('files_with_matches'):
4223 if opts.get('files_with_matches'):
4219 break
4224 break
4220 return found
4225 return found
4221
4226
4222 skip = {}
4227 skip = {}
4223 revfiles = {}
4228 revfiles = {}
4224 matchfn = scmutil.match(repo[None], pats, opts)
4229 matchfn = scmutil.match(repo[None], pats, opts)
4225 found = False
4230 found = False
4226 follow = opts.get('follow')
4231 follow = opts.get('follow')
4227
4232
4228 def prep(ctx, fns):
4233 def prep(ctx, fns):
4229 rev = ctx.rev()
4234 rev = ctx.rev()
4230 pctx = ctx.p1()
4235 pctx = ctx.p1()
4231 parent = pctx.rev()
4236 parent = pctx.rev()
4232 matches.setdefault(rev, {})
4237 matches.setdefault(rev, {})
4233 matches.setdefault(parent, {})
4238 matches.setdefault(parent, {})
4234 files = revfiles.setdefault(rev, [])
4239 files = revfiles.setdefault(rev, [])
4235 for fn in fns:
4240 for fn in fns:
4236 flog = getfile(fn)
4241 flog = getfile(fn)
4237 try:
4242 try:
4238 fnode = ctx.filenode(fn)
4243 fnode = ctx.filenode(fn)
4239 except error.LookupError:
4244 except error.LookupError:
4240 continue
4245 continue
4241
4246
4242 copied = flog.renamed(fnode)
4247 copied = flog.renamed(fnode)
4243 copy = follow and copied and copied[0]
4248 copy = follow and copied and copied[0]
4244 if copy:
4249 if copy:
4245 copies.setdefault(rev, {})[fn] = copy
4250 copies.setdefault(rev, {})[fn] = copy
4246 if fn in skip:
4251 if fn in skip:
4247 if copy:
4252 if copy:
4248 skip[copy] = True
4253 skip[copy] = True
4249 continue
4254 continue
4250 files.append(fn)
4255 files.append(fn)
4251
4256
4252 if fn not in matches[rev]:
4257 if fn not in matches[rev]:
4253 grepbody(fn, rev, flog.read(fnode))
4258 grepbody(fn, rev, flog.read(fnode))
4254
4259
4255 pfn = copy or fn
4260 pfn = copy or fn
4256 if pfn not in matches[parent]:
4261 if pfn not in matches[parent]:
4257 try:
4262 try:
4258 fnode = pctx.filenode(pfn)
4263 fnode = pctx.filenode(pfn)
4259 grepbody(pfn, parent, flog.read(fnode))
4264 grepbody(pfn, parent, flog.read(fnode))
4260 except error.LookupError:
4265 except error.LookupError:
4261 pass
4266 pass
4262
4267
4263 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
4268 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
4264 rev = ctx.rev()
4269 rev = ctx.rev()
4265 parent = ctx.p1().rev()
4270 parent = ctx.p1().rev()
4266 for fn in sorted(revfiles.get(rev, [])):
4271 for fn in sorted(revfiles.get(rev, [])):
4267 states = matches[rev][fn]
4272 states = matches[rev][fn]
4268 copy = copies.get(rev, {}).get(fn)
4273 copy = copies.get(rev, {}).get(fn)
4269 if fn in skip:
4274 if fn in skip:
4270 if copy:
4275 if copy:
4271 skip[copy] = True
4276 skip[copy] = True
4272 continue
4277 continue
4273 pstates = matches.get(parent, {}).get(copy or fn, [])
4278 pstates = matches.get(parent, {}).get(copy or fn, [])
4274 if pstates or states:
4279 if pstates or states:
4275 r = display(fn, ctx, pstates, states)
4280 r = display(fn, ctx, pstates, states)
4276 found = found or r
4281 found = found or r
4277 if r and not opts.get('all'):
4282 if r and not opts.get('all'):
4278 skip[fn] = True
4283 skip[fn] = True
4279 if copy:
4284 if copy:
4280 skip[copy] = True
4285 skip[copy] = True
4281 del matches[rev]
4286 del matches[rev]
4282 del revfiles[rev]
4287 del revfiles[rev]
4283
4288
4284 return not found
4289 return not found
4285
4290
4286 @command('heads',
4291 @command('heads',
4287 [('r', 'rev', '',
4292 [('r', 'rev', '',
4288 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
4293 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
4289 ('t', 'topo', False, _('show topological heads only')),
4294 ('t', 'topo', False, _('show topological heads only')),
4290 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
4295 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
4291 ('c', 'closed', False, _('show normal and closed branch heads')),
4296 ('c', 'closed', False, _('show normal and closed branch heads')),
4292 ] + templateopts,
4297 ] + templateopts,
4293 _('[-ct] [-r STARTREV] [REV]...'))
4298 _('[-ct] [-r STARTREV] [REV]...'))
4294 def heads(ui, repo, *branchrevs, **opts):
4299 def heads(ui, repo, *branchrevs, **opts):
4295 """show branch heads
4300 """show branch heads
4296
4301
4297 With no arguments, show all open branch heads in the repository.
4302 With no arguments, show all open branch heads in the repository.
4298 Branch heads are changesets that have no descendants on the
4303 Branch heads are changesets that have no descendants on the
4299 same branch. They are where development generally takes place and
4304 same branch. They are where development generally takes place and
4300 are the usual targets for update and merge operations.
4305 are the usual targets for update and merge operations.
4301
4306
4302 If one or more REVs are given, only open branch heads on the
4307 If one or more REVs are given, only open branch heads on the
4303 branches associated with the specified changesets are shown. This
4308 branches associated with the specified changesets are shown. This
4304 means that you can use :hg:`heads .` to see the heads on the
4309 means that you can use :hg:`heads .` to see the heads on the
4305 currently checked-out branch.
4310 currently checked-out branch.
4306
4311
4307 If -c/--closed is specified, also show branch heads marked closed
4312 If -c/--closed is specified, also show branch heads marked closed
4308 (see :hg:`commit --close-branch`).
4313 (see :hg:`commit --close-branch`).
4309
4314
4310 If STARTREV is specified, only those heads that are descendants of
4315 If STARTREV is specified, only those heads that are descendants of
4311 STARTREV will be displayed.
4316 STARTREV will be displayed.
4312
4317
4313 If -t/--topo is specified, named branch mechanics will be ignored and only
4318 If -t/--topo is specified, named branch mechanics will be ignored and only
4314 topological heads (changesets with no children) will be shown.
4319 topological heads (changesets with no children) will be shown.
4315
4320
4316 Returns 0 if matching heads are found, 1 if not.
4321 Returns 0 if matching heads are found, 1 if not.
4317 """
4322 """
4318
4323
4319 start = None
4324 start = None
4320 if 'rev' in opts:
4325 if 'rev' in opts:
4321 start = scmutil.revsingle(repo, opts['rev'], None).node()
4326 start = scmutil.revsingle(repo, opts['rev'], None).node()
4322
4327
4323 if opts.get('topo'):
4328 if opts.get('topo'):
4324 heads = [repo[h] for h in repo.heads(start)]
4329 heads = [repo[h] for h in repo.heads(start)]
4325 else:
4330 else:
4326 heads = []
4331 heads = []
4327 for branch in repo.branchmap():
4332 for branch in repo.branchmap():
4328 heads += repo.branchheads(branch, start, opts.get('closed'))
4333 heads += repo.branchheads(branch, start, opts.get('closed'))
4329 heads = [repo[h] for h in heads]
4334 heads = [repo[h] for h in heads]
4330
4335
4331 if branchrevs:
4336 if branchrevs:
4332 branches = set(repo[br].branch() for br in branchrevs)
4337 branches = set(repo[br].branch() for br in branchrevs)
4333 heads = [h for h in heads if h.branch() in branches]
4338 heads = [h for h in heads if h.branch() in branches]
4334
4339
4335 if opts.get('active') and branchrevs:
4340 if opts.get('active') and branchrevs:
4336 dagheads = repo.heads(start)
4341 dagheads = repo.heads(start)
4337 heads = [h for h in heads if h.node() in dagheads]
4342 heads = [h for h in heads if h.node() in dagheads]
4338
4343
4339 if branchrevs:
4344 if branchrevs:
4340 haveheads = set(h.branch() for h in heads)
4345 haveheads = set(h.branch() for h in heads)
4341 if branches - haveheads:
4346 if branches - haveheads:
4342 headless = ', '.join(b for b in branches - haveheads)
4347 headless = ', '.join(b for b in branches - haveheads)
4343 msg = _('no open branch heads found on branches %s')
4348 msg = _('no open branch heads found on branches %s')
4344 if opts.get('rev'):
4349 if opts.get('rev'):
4345 msg += _(' (started at %s)') % opts['rev']
4350 msg += _(' (started at %s)') % opts['rev']
4346 ui.warn((msg + '\n') % headless)
4351 ui.warn((msg + '\n') % headless)
4347
4352
4348 if not heads:
4353 if not heads:
4349 return 1
4354 return 1
4350
4355
4351 heads = sorted(heads, key=lambda x: -x.rev())
4356 heads = sorted(heads, key=lambda x: -x.rev())
4352 displayer = cmdutil.show_changeset(ui, repo, opts)
4357 displayer = cmdutil.show_changeset(ui, repo, opts)
4353 for ctx in heads:
4358 for ctx in heads:
4354 displayer.show(ctx)
4359 displayer.show(ctx)
4355 displayer.close()
4360 displayer.close()
4356
4361
4357 @command('help',
4362 @command('help',
4358 [('e', 'extension', None, _('show only help for extensions')),
4363 [('e', 'extension', None, _('show only help for extensions')),
4359 ('c', 'command', None, _('show only help for commands')),
4364 ('c', 'command', None, _('show only help for commands')),
4360 ('k', 'keyword', None, _('show topics matching keyword')),
4365 ('k', 'keyword', None, _('show topics matching keyword')),
4361 ('s', 'system', [], _('show help for specific platform(s)')),
4366 ('s', 'system', [], _('show help for specific platform(s)')),
4362 ],
4367 ],
4363 _('[-ecks] [TOPIC]'),
4368 _('[-ecks] [TOPIC]'),
4364 norepo=True)
4369 norepo=True)
4365 def help_(ui, name=None, **opts):
4370 def help_(ui, name=None, **opts):
4366 """show help for a given topic or a help overview
4371 """show help for a given topic or a help overview
4367
4372
4368 With no arguments, print a list of commands with short help messages.
4373 With no arguments, print a list of commands with short help messages.
4369
4374
4370 Given a topic, extension, or command name, print help for that
4375 Given a topic, extension, or command name, print help for that
4371 topic.
4376 topic.
4372
4377
4373 Returns 0 if successful.
4378 Returns 0 if successful.
4374 """
4379 """
4375
4380
4376 textwidth = min(ui.termwidth(), 80) - 2
4381 textwidth = min(ui.termwidth(), 80) - 2
4377
4382
4378 keep = opts.get('system') or []
4383 keep = opts.get('system') or []
4379 if len(keep) == 0:
4384 if len(keep) == 0:
4380 if sys.platform.startswith('win'):
4385 if sys.platform.startswith('win'):
4381 keep.append('windows')
4386 keep.append('windows')
4382 elif sys.platform == 'OpenVMS':
4387 elif sys.platform == 'OpenVMS':
4383 keep.append('vms')
4388 keep.append('vms')
4384 elif sys.platform == 'plan9':
4389 elif sys.platform == 'plan9':
4385 keep.append('plan9')
4390 keep.append('plan9')
4386 else:
4391 else:
4387 keep.append('unix')
4392 keep.append('unix')
4388 keep.append(sys.platform.lower())
4393 keep.append(sys.platform.lower())
4389 if ui.verbose:
4394 if ui.verbose:
4390 keep.append('verbose')
4395 keep.append('verbose')
4391
4396
4392 section = None
4397 section = None
4393 subtopic = None
4398 subtopic = None
4394 if name and '.' in name:
4399 if name and '.' in name:
4395 name, section = name.split('.', 1)
4400 name, section = name.split('.', 1)
4396 section = section.lower()
4401 section = section.lower()
4397 if '.' in section:
4402 if '.' in section:
4398 subtopic, section = section.split('.', 1)
4403 subtopic, section = section.split('.', 1)
4399 else:
4404 else:
4400 subtopic = section
4405 subtopic = section
4401
4406
4402 text = help.help_(ui, name, subtopic=subtopic, **opts)
4407 text = help.help_(ui, name, subtopic=subtopic, **opts)
4403
4408
4404 formatted, pruned = minirst.format(text, textwidth, keep=keep,
4409 formatted, pruned = minirst.format(text, textwidth, keep=keep,
4405 section=section)
4410 section=section)
4406
4411
4407 # We could have been given a weird ".foo" section without a name
4412 # We could have been given a weird ".foo" section without a name
4408 # to look for, or we could have simply failed to found "foo.bar"
4413 # to look for, or we could have simply failed to found "foo.bar"
4409 # because bar isn't a section of foo
4414 # because bar isn't a section of foo
4410 if section and not (formatted and name):
4415 if section and not (formatted and name):
4411 raise error.Abort(_("help section not found"))
4416 raise error.Abort(_("help section not found"))
4412
4417
4413 if 'verbose' in pruned:
4418 if 'verbose' in pruned:
4414 keep.append('omitted')
4419 keep.append('omitted')
4415 else:
4420 else:
4416 keep.append('notomitted')
4421 keep.append('notomitted')
4417 formatted, pruned = minirst.format(text, textwidth, keep=keep,
4422 formatted, pruned = minirst.format(text, textwidth, keep=keep,
4418 section=section)
4423 section=section)
4419 ui.write(formatted)
4424 ui.write(formatted)
4420
4425
4421
4426
4422 @command('identify|id',
4427 @command('identify|id',
4423 [('r', 'rev', '',
4428 [('r', 'rev', '',
4424 _('identify the specified revision'), _('REV')),
4429 _('identify the specified revision'), _('REV')),
4425 ('n', 'num', None, _('show local revision number')),
4430 ('n', 'num', None, _('show local revision number')),
4426 ('i', 'id', None, _('show global revision id')),
4431 ('i', 'id', None, _('show global revision id')),
4427 ('b', 'branch', None, _('show branch')),
4432 ('b', 'branch', None, _('show branch')),
4428 ('t', 'tags', None, _('show tags')),
4433 ('t', 'tags', None, _('show tags')),
4429 ('B', 'bookmarks', None, _('show bookmarks')),
4434 ('B', 'bookmarks', None, _('show bookmarks')),
4430 ] + remoteopts,
4435 ] + remoteopts,
4431 _('[-nibtB] [-r REV] [SOURCE]'),
4436 _('[-nibtB] [-r REV] [SOURCE]'),
4432 optionalrepo=True)
4437 optionalrepo=True)
4433 def identify(ui, repo, source=None, rev=None,
4438 def identify(ui, repo, source=None, rev=None,
4434 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
4439 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
4435 """identify the working directory or specified revision
4440 """identify the working directory or specified revision
4436
4441
4437 Print a summary identifying the repository state at REV using one or
4442 Print a summary identifying the repository state at REV using one or
4438 two parent hash identifiers, followed by a "+" if the working
4443 two parent hash identifiers, followed by a "+" if the working
4439 directory has uncommitted changes, the branch name (if not default),
4444 directory has uncommitted changes, the branch name (if not default),
4440 a list of tags, and a list of bookmarks.
4445 a list of tags, and a list of bookmarks.
4441
4446
4442 When REV is not given, print a summary of the current state of the
4447 When REV is not given, print a summary of the current state of the
4443 repository.
4448 repository.
4444
4449
4445 Specifying a path to a repository root or Mercurial bundle will
4450 Specifying a path to a repository root or Mercurial bundle will
4446 cause lookup to operate on that repository/bundle.
4451 cause lookup to operate on that repository/bundle.
4447
4452
4448 .. container:: verbose
4453 .. container:: verbose
4449
4454
4450 Examples:
4455 Examples:
4451
4456
4452 - generate a build identifier for the working directory::
4457 - generate a build identifier for the working directory::
4453
4458
4454 hg id --id > build-id.dat
4459 hg id --id > build-id.dat
4455
4460
4456 - find the revision corresponding to a tag::
4461 - find the revision corresponding to a tag::
4457
4462
4458 hg id -n -r 1.3
4463 hg id -n -r 1.3
4459
4464
4460 - check the most recent revision of a remote repository::
4465 - check the most recent revision of a remote repository::
4461
4466
4462 hg id -r tip http://selenic.com/hg/
4467 hg id -r tip http://selenic.com/hg/
4463
4468
4464 See :hg:`log` for generating more information about specific revisions,
4469 See :hg:`log` for generating more information about specific revisions,
4465 including full hash identifiers.
4470 including full hash identifiers.
4466
4471
4467 Returns 0 if successful.
4472 Returns 0 if successful.
4468 """
4473 """
4469
4474
4470 if not repo and not source:
4475 if not repo and not source:
4471 raise error.Abort(_("there is no Mercurial repository here "
4476 raise error.Abort(_("there is no Mercurial repository here "
4472 "(.hg not found)"))
4477 "(.hg not found)"))
4473
4478
4474 if ui.debugflag:
4479 if ui.debugflag:
4475 hexfunc = hex
4480 hexfunc = hex
4476 else:
4481 else:
4477 hexfunc = short
4482 hexfunc = short
4478 default = not (num or id or branch or tags or bookmarks)
4483 default = not (num or id or branch or tags or bookmarks)
4479 output = []
4484 output = []
4480 revs = []
4485 revs = []
4481
4486
4482 if source:
4487 if source:
4483 source, branches = hg.parseurl(ui.expandpath(source))
4488 source, branches = hg.parseurl(ui.expandpath(source))
4484 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
4489 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
4485 repo = peer.local()
4490 repo = peer.local()
4486 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
4491 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
4487
4492
4488 if not repo:
4493 if not repo:
4489 if num or branch or tags:
4494 if num or branch or tags:
4490 raise error.Abort(
4495 raise error.Abort(
4491 _("can't query remote revision number, branch, or tags"))
4496 _("can't query remote revision number, branch, or tags"))
4492 if not rev and revs:
4497 if not rev and revs:
4493 rev = revs[0]
4498 rev = revs[0]
4494 if not rev:
4499 if not rev:
4495 rev = "tip"
4500 rev = "tip"
4496
4501
4497 remoterev = peer.lookup(rev)
4502 remoterev = peer.lookup(rev)
4498 if default or id:
4503 if default or id:
4499 output = [hexfunc(remoterev)]
4504 output = [hexfunc(remoterev)]
4500
4505
4501 def getbms():
4506 def getbms():
4502 bms = []
4507 bms = []
4503
4508
4504 if 'bookmarks' in peer.listkeys('namespaces'):
4509 if 'bookmarks' in peer.listkeys('namespaces'):
4505 hexremoterev = hex(remoterev)
4510 hexremoterev = hex(remoterev)
4506 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
4511 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
4507 if bmr == hexremoterev]
4512 if bmr == hexremoterev]
4508
4513
4509 return sorted(bms)
4514 return sorted(bms)
4510
4515
4511 if bookmarks:
4516 if bookmarks:
4512 output.extend(getbms())
4517 output.extend(getbms())
4513 elif default and not ui.quiet:
4518 elif default and not ui.quiet:
4514 # multiple bookmarks for a single parent separated by '/'
4519 # multiple bookmarks for a single parent separated by '/'
4515 bm = '/'.join(getbms())
4520 bm = '/'.join(getbms())
4516 if bm:
4521 if bm:
4517 output.append(bm)
4522 output.append(bm)
4518 else:
4523 else:
4519 ctx = scmutil.revsingle(repo, rev, None)
4524 ctx = scmutil.revsingle(repo, rev, None)
4520
4525
4521 if ctx.rev() is None:
4526 if ctx.rev() is None:
4522 ctx = repo[None]
4527 ctx = repo[None]
4523 parents = ctx.parents()
4528 parents = ctx.parents()
4524 taglist = []
4529 taglist = []
4525 for p in parents:
4530 for p in parents:
4526 taglist.extend(p.tags())
4531 taglist.extend(p.tags())
4527
4532
4528 changed = ""
4533 changed = ""
4529 if default or id or num:
4534 if default or id or num:
4530 if (any(repo.status())
4535 if (any(repo.status())
4531 or any(ctx.sub(s).dirty() for s in ctx.substate)):
4536 or any(ctx.sub(s).dirty() for s in ctx.substate)):
4532 changed = '+'
4537 changed = '+'
4533 if default or id:
4538 if default or id:
4534 output = ["%s%s" %
4539 output = ["%s%s" %
4535 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
4540 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
4536 if num:
4541 if num:
4537 output.append("%s%s" %
4542 output.append("%s%s" %
4538 ('+'.join([str(p.rev()) for p in parents]), changed))
4543 ('+'.join([str(p.rev()) for p in parents]), changed))
4539 else:
4544 else:
4540 if default or id:
4545 if default or id:
4541 output = [hexfunc(ctx.node())]
4546 output = [hexfunc(ctx.node())]
4542 if num:
4547 if num:
4543 output.append(str(ctx.rev()))
4548 output.append(str(ctx.rev()))
4544 taglist = ctx.tags()
4549 taglist = ctx.tags()
4545
4550
4546 if default and not ui.quiet:
4551 if default and not ui.quiet:
4547 b = ctx.branch()
4552 b = ctx.branch()
4548 if b != 'default':
4553 if b != 'default':
4549 output.append("(%s)" % b)
4554 output.append("(%s)" % b)
4550
4555
4551 # multiple tags for a single parent separated by '/'
4556 # multiple tags for a single parent separated by '/'
4552 t = '/'.join(taglist)
4557 t = '/'.join(taglist)
4553 if t:
4558 if t:
4554 output.append(t)
4559 output.append(t)
4555
4560
4556 # multiple bookmarks for a single parent separated by '/'
4561 # multiple bookmarks for a single parent separated by '/'
4557 bm = '/'.join(ctx.bookmarks())
4562 bm = '/'.join(ctx.bookmarks())
4558 if bm:
4563 if bm:
4559 output.append(bm)
4564 output.append(bm)
4560 else:
4565 else:
4561 if branch:
4566 if branch:
4562 output.append(ctx.branch())
4567 output.append(ctx.branch())
4563
4568
4564 if tags:
4569 if tags:
4565 output.extend(taglist)
4570 output.extend(taglist)
4566
4571
4567 if bookmarks:
4572 if bookmarks:
4568 output.extend(ctx.bookmarks())
4573 output.extend(ctx.bookmarks())
4569
4574
4570 ui.write("%s\n" % ' '.join(output))
4575 ui.write("%s\n" % ' '.join(output))
4571
4576
4572 @command('import|patch',
4577 @command('import|patch',
4573 [('p', 'strip', 1,
4578 [('p', 'strip', 1,
4574 _('directory strip option for patch. This has the same '
4579 _('directory strip option for patch. This has the same '
4575 'meaning as the corresponding patch option'), _('NUM')),
4580 'meaning as the corresponding patch option'), _('NUM')),
4576 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
4581 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
4577 ('e', 'edit', False, _('invoke editor on commit messages')),
4582 ('e', 'edit', False, _('invoke editor on commit messages')),
4578 ('f', 'force', None,
4583 ('f', 'force', None,
4579 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
4584 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
4580 ('', 'no-commit', None,
4585 ('', 'no-commit', None,
4581 _("don't commit, just update the working directory")),
4586 _("don't commit, just update the working directory")),
4582 ('', 'bypass', None,
4587 ('', 'bypass', None,
4583 _("apply patch without touching the working directory")),
4588 _("apply patch without touching the working directory")),
4584 ('', 'partial', None,
4589 ('', 'partial', None,
4585 _('commit even if some hunks fail')),
4590 _('commit even if some hunks fail')),
4586 ('', 'exact', None,
4591 ('', 'exact', None,
4587 _('apply patch to the nodes from which it was generated')),
4592 _('apply patch to the nodes from which it was generated')),
4588 ('', 'prefix', '',
4593 ('', 'prefix', '',
4589 _('apply patch to subdirectory'), _('DIR')),
4594 _('apply patch to subdirectory'), _('DIR')),
4590 ('', 'import-branch', None,
4595 ('', 'import-branch', None,
4591 _('use any branch information in patch (implied by --exact)'))] +
4596 _('use any branch information in patch (implied by --exact)'))] +
4592 commitopts + commitopts2 + similarityopts,
4597 commitopts + commitopts2 + similarityopts,
4593 _('[OPTION]... PATCH...'))
4598 _('[OPTION]... PATCH...'))
4594 def import_(ui, repo, patch1=None, *patches, **opts):
4599 def import_(ui, repo, patch1=None, *patches, **opts):
4595 """import an ordered set of patches
4600 """import an ordered set of patches
4596
4601
4597 Import a list of patches and commit them individually (unless
4602 Import a list of patches and commit them individually (unless
4598 --no-commit is specified).
4603 --no-commit is specified).
4599
4604
4600 To read a patch from standard input, use "-" as the patch name. If
4605 To read a patch from standard input, use "-" as the patch name. If
4601 a URL is specified, the patch will be downloaded from there.
4606 a URL is specified, the patch will be downloaded from there.
4602
4607
4603 Import first applies changes to the working directory (unless
4608 Import first applies changes to the working directory (unless
4604 --bypass is specified), import will abort if there are outstanding
4609 --bypass is specified), import will abort if there are outstanding
4605 changes.
4610 changes.
4606
4611
4607 Use --bypass to apply and commit patches directly to the
4612 Use --bypass to apply and commit patches directly to the
4608 repository, without affecting the working directory. Without
4613 repository, without affecting the working directory. Without
4609 --exact, patches will be applied on top of the working directory
4614 --exact, patches will be applied on top of the working directory
4610 parent revision.
4615 parent revision.
4611
4616
4612 You can import a patch straight from a mail message. Even patches
4617 You can import a patch straight from a mail message. Even patches
4613 as attachments work (to use the body part, it must have type
4618 as attachments work (to use the body part, it must have type
4614 text/plain or text/x-patch). From and Subject headers of email
4619 text/plain or text/x-patch). From and Subject headers of email
4615 message are used as default committer and commit message. All
4620 message are used as default committer and commit message. All
4616 text/plain body parts before first diff are added to the commit
4621 text/plain body parts before first diff are added to the commit
4617 message.
4622 message.
4618
4623
4619 If the imported patch was generated by :hg:`export`, user and
4624 If the imported patch was generated by :hg:`export`, user and
4620 description from patch override values from message headers and
4625 description from patch override values from message headers and
4621 body. Values given on command line with -m/--message and -u/--user
4626 body. Values given on command line with -m/--message and -u/--user
4622 override these.
4627 override these.
4623
4628
4624 If --exact is specified, import will set the working directory to
4629 If --exact is specified, import will set the working directory to
4625 the parent of each patch before applying it, and will abort if the
4630 the parent of each patch before applying it, and will abort if the
4626 resulting changeset has a different ID than the one recorded in
4631 resulting changeset has a different ID than the one recorded in
4627 the patch. This may happen due to character set problems or other
4632 the patch. This may happen due to character set problems or other
4628 deficiencies in the text patch format.
4633 deficiencies in the text patch format.
4629
4634
4630 Use --partial to ensure a changeset will be created from the patch
4635 Use --partial to ensure a changeset will be created from the patch
4631 even if some hunks fail to apply. Hunks that fail to apply will be
4636 even if some hunks fail to apply. Hunks that fail to apply will be
4632 written to a <target-file>.rej file. Conflicts can then be resolved
4637 written to a <target-file>.rej file. Conflicts can then be resolved
4633 by hand before :hg:`commit --amend` is run to update the created
4638 by hand before :hg:`commit --amend` is run to update the created
4634 changeset. This flag exists to let people import patches that
4639 changeset. This flag exists to let people import patches that
4635 partially apply without losing the associated metadata (author,
4640 partially apply without losing the associated metadata (author,
4636 date, description, ...).
4641 date, description, ...).
4637
4642
4638 .. note::
4643 .. note::
4639
4644
4640 When no hunks apply cleanly, :hg:`import --partial` will create
4645 When no hunks apply cleanly, :hg:`import --partial` will create
4641 an empty changeset, importing only the patch metadata.
4646 an empty changeset, importing only the patch metadata.
4642
4647
4643 With -s/--similarity, hg will attempt to discover renames and
4648 With -s/--similarity, hg will attempt to discover renames and
4644 copies in the patch in the same way as :hg:`addremove`.
4649 copies in the patch in the same way as :hg:`addremove`.
4645
4650
4646 It is possible to use external patch programs to perform the patch
4651 It is possible to use external patch programs to perform the patch
4647 by setting the ``ui.patch`` configuration option. For the default
4652 by setting the ``ui.patch`` configuration option. For the default
4648 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4653 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4649 See :hg:`help config` for more information about configuration
4654 See :hg:`help config` for more information about configuration
4650 files and how to use these options.
4655 files and how to use these options.
4651
4656
4652 See :hg:`help dates` for a list of formats valid for -d/--date.
4657 See :hg:`help dates` for a list of formats valid for -d/--date.
4653
4658
4654 .. container:: verbose
4659 .. container:: verbose
4655
4660
4656 Examples:
4661 Examples:
4657
4662
4658 - import a traditional patch from a website and detect renames::
4663 - import a traditional patch from a website and detect renames::
4659
4664
4660 hg import -s 80 http://example.com/bugfix.patch
4665 hg import -s 80 http://example.com/bugfix.patch
4661
4666
4662 - import a changeset from an hgweb server::
4667 - import a changeset from an hgweb server::
4663
4668
4664 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
4669 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
4665
4670
4666 - import all the patches in an Unix-style mbox::
4671 - import all the patches in an Unix-style mbox::
4667
4672
4668 hg import incoming-patches.mbox
4673 hg import incoming-patches.mbox
4669
4674
4670 - attempt to exactly restore an exported changeset (not always
4675 - attempt to exactly restore an exported changeset (not always
4671 possible)::
4676 possible)::
4672
4677
4673 hg import --exact proposed-fix.patch
4678 hg import --exact proposed-fix.patch
4674
4679
4675 - use an external tool to apply a patch which is too fuzzy for
4680 - use an external tool to apply a patch which is too fuzzy for
4676 the default internal tool.
4681 the default internal tool.
4677
4682
4678 hg import --config ui.patch="patch --merge" fuzzy.patch
4683 hg import --config ui.patch="patch --merge" fuzzy.patch
4679
4684
4680 - change the default fuzzing from 2 to a less strict 7
4685 - change the default fuzzing from 2 to a less strict 7
4681
4686
4682 hg import --config ui.fuzz=7 fuzz.patch
4687 hg import --config ui.fuzz=7 fuzz.patch
4683
4688
4684 Returns 0 on success, 1 on partial success (see --partial).
4689 Returns 0 on success, 1 on partial success (see --partial).
4685 """
4690 """
4686
4691
4687 if not patch1:
4692 if not patch1:
4688 raise error.Abort(_('need at least one patch to import'))
4693 raise error.Abort(_('need at least one patch to import'))
4689
4694
4690 patches = (patch1,) + patches
4695 patches = (patch1,) + patches
4691
4696
4692 date = opts.get('date')
4697 date = opts.get('date')
4693 if date:
4698 if date:
4694 opts['date'] = util.parsedate(date)
4699 opts['date'] = util.parsedate(date)
4695
4700
4696 exact = opts.get('exact')
4701 exact = opts.get('exact')
4697 update = not opts.get('bypass')
4702 update = not opts.get('bypass')
4698 if not update and opts.get('no_commit'):
4703 if not update and opts.get('no_commit'):
4699 raise error.Abort(_('cannot use --no-commit with --bypass'))
4704 raise error.Abort(_('cannot use --no-commit with --bypass'))
4700 try:
4705 try:
4701 sim = float(opts.get('similarity') or 0)
4706 sim = float(opts.get('similarity') or 0)
4702 except ValueError:
4707 except ValueError:
4703 raise error.Abort(_('similarity must be a number'))
4708 raise error.Abort(_('similarity must be a number'))
4704 if sim < 0 or sim > 100:
4709 if sim < 0 or sim > 100:
4705 raise error.Abort(_('similarity must be between 0 and 100'))
4710 raise error.Abort(_('similarity must be between 0 and 100'))
4706 if sim and not update:
4711 if sim and not update:
4707 raise error.Abort(_('cannot use --similarity with --bypass'))
4712 raise error.Abort(_('cannot use --similarity with --bypass'))
4708 if exact:
4713 if exact:
4709 if opts.get('edit'):
4714 if opts.get('edit'):
4710 raise error.Abort(_('cannot use --exact with --edit'))
4715 raise error.Abort(_('cannot use --exact with --edit'))
4711 if opts.get('prefix'):
4716 if opts.get('prefix'):
4712 raise error.Abort(_('cannot use --exact with --prefix'))
4717 raise error.Abort(_('cannot use --exact with --prefix'))
4713
4718
4714 base = opts["base"]
4719 base = opts["base"]
4715 wlock = dsguard = lock = tr = None
4720 wlock = dsguard = lock = tr = None
4716 msgs = []
4721 msgs = []
4717 ret = 0
4722 ret = 0
4718
4723
4719
4724
4720 try:
4725 try:
4721 wlock = repo.wlock()
4726 wlock = repo.wlock()
4722
4727
4723 if update:
4728 if update:
4724 cmdutil.checkunfinished(repo)
4729 cmdutil.checkunfinished(repo)
4725 if (exact or not opts.get('force')):
4730 if (exact or not opts.get('force')):
4726 cmdutil.bailifchanged(repo)
4731 cmdutil.bailifchanged(repo)
4727
4732
4728 if not opts.get('no_commit'):
4733 if not opts.get('no_commit'):
4729 lock = repo.lock()
4734 lock = repo.lock()
4730 tr = repo.transaction('import')
4735 tr = repo.transaction('import')
4731 else:
4736 else:
4732 dsguard = cmdutil.dirstateguard(repo, 'import')
4737 dsguard = cmdutil.dirstateguard(repo, 'import')
4733 parents = repo[None].parents()
4738 parents = repo[None].parents()
4734 for patchurl in patches:
4739 for patchurl in patches:
4735 if patchurl == '-':
4740 if patchurl == '-':
4736 ui.status(_('applying patch from stdin\n'))
4741 ui.status(_('applying patch from stdin\n'))
4737 patchfile = ui.fin
4742 patchfile = ui.fin
4738 patchurl = 'stdin' # for error message
4743 patchurl = 'stdin' # for error message
4739 else:
4744 else:
4740 patchurl = os.path.join(base, patchurl)
4745 patchurl = os.path.join(base, patchurl)
4741 ui.status(_('applying %s\n') % patchurl)
4746 ui.status(_('applying %s\n') % patchurl)
4742 patchfile = hg.openpath(ui, patchurl)
4747 patchfile = hg.openpath(ui, patchurl)
4743
4748
4744 haspatch = False
4749 haspatch = False
4745 for hunk in patch.split(patchfile):
4750 for hunk in patch.split(patchfile):
4746 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
4751 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
4747 parents, opts,
4752 parents, opts,
4748 msgs, hg.clean)
4753 msgs, hg.clean)
4749 if msg:
4754 if msg:
4750 haspatch = True
4755 haspatch = True
4751 ui.note(msg + '\n')
4756 ui.note(msg + '\n')
4752 if update or exact:
4757 if update or exact:
4753 parents = repo[None].parents()
4758 parents = repo[None].parents()
4754 else:
4759 else:
4755 parents = [repo[node]]
4760 parents = [repo[node]]
4756 if rej:
4761 if rej:
4757 ui.write_err(_("patch applied partially\n"))
4762 ui.write_err(_("patch applied partially\n"))
4758 ui.write_err(_("(fix the .rej files and run "
4763 ui.write_err(_("(fix the .rej files and run "
4759 "`hg commit --amend`)\n"))
4764 "`hg commit --amend`)\n"))
4760 ret = 1
4765 ret = 1
4761 break
4766 break
4762
4767
4763 if not haspatch:
4768 if not haspatch:
4764 raise error.Abort(_('%s: no diffs found') % patchurl)
4769 raise error.Abort(_('%s: no diffs found') % patchurl)
4765
4770
4766 if tr:
4771 if tr:
4767 tr.close()
4772 tr.close()
4768 if msgs:
4773 if msgs:
4769 repo.savecommitmessage('\n* * *\n'.join(msgs))
4774 repo.savecommitmessage('\n* * *\n'.join(msgs))
4770 if dsguard:
4775 if dsguard:
4771 dsguard.close()
4776 dsguard.close()
4772 return ret
4777 return ret
4773 finally:
4778 finally:
4774 if tr:
4779 if tr:
4775 tr.release()
4780 tr.release()
4776 release(lock, dsguard, wlock)
4781 release(lock, dsguard, wlock)
4777
4782
4778 @command('incoming|in',
4783 @command('incoming|in',
4779 [('f', 'force', None,
4784 [('f', 'force', None,
4780 _('run even if remote repository is unrelated')),
4785 _('run even if remote repository is unrelated')),
4781 ('n', 'newest-first', None, _('show newest record first')),
4786 ('n', 'newest-first', None, _('show newest record first')),
4782 ('', 'bundle', '',
4787 ('', 'bundle', '',
4783 _('file to store the bundles into'), _('FILE')),
4788 _('file to store the bundles into'), _('FILE')),
4784 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4789 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4785 ('B', 'bookmarks', False, _("compare bookmarks")),
4790 ('B', 'bookmarks', False, _("compare bookmarks")),
4786 ('b', 'branch', [],
4791 ('b', 'branch', [],
4787 _('a specific branch you would like to pull'), _('BRANCH')),
4792 _('a specific branch you would like to pull'), _('BRANCH')),
4788 ] + logopts + remoteopts + subrepoopts,
4793 ] + logopts + remoteopts + subrepoopts,
4789 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
4794 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
4790 def incoming(ui, repo, source="default", **opts):
4795 def incoming(ui, repo, source="default", **opts):
4791 """show new changesets found in source
4796 """show new changesets found in source
4792
4797
4793 Show new changesets found in the specified path/URL or the default
4798 Show new changesets found in the specified path/URL or the default
4794 pull location. These are the changesets that would have been pulled
4799 pull location. These are the changesets that would have been pulled
4795 if a pull at the time you issued this command.
4800 if a pull at the time you issued this command.
4796
4801
4797 See pull for valid source format details.
4802 See pull for valid source format details.
4798
4803
4799 .. container:: verbose
4804 .. container:: verbose
4800
4805
4801 With -B/--bookmarks, the result of bookmark comparison between
4806 With -B/--bookmarks, the result of bookmark comparison between
4802 local and remote repositories is displayed. With -v/--verbose,
4807 local and remote repositories is displayed. With -v/--verbose,
4803 status is also displayed for each bookmark like below::
4808 status is also displayed for each bookmark like below::
4804
4809
4805 BM1 01234567890a added
4810 BM1 01234567890a added
4806 BM2 1234567890ab advanced
4811 BM2 1234567890ab advanced
4807 BM3 234567890abc diverged
4812 BM3 234567890abc diverged
4808 BM4 34567890abcd changed
4813 BM4 34567890abcd changed
4809
4814
4810 The action taken locally when pulling depends on the
4815 The action taken locally when pulling depends on the
4811 status of each bookmark:
4816 status of each bookmark:
4812
4817
4813 :``added``: pull will create it
4818 :``added``: pull will create it
4814 :``advanced``: pull will update it
4819 :``advanced``: pull will update it
4815 :``diverged``: pull will create a divergent bookmark
4820 :``diverged``: pull will create a divergent bookmark
4816 :``changed``: result depends on remote changesets
4821 :``changed``: result depends on remote changesets
4817
4822
4818 From the point of view of pulling behavior, bookmark
4823 From the point of view of pulling behavior, bookmark
4819 existing only in the remote repository are treated as ``added``,
4824 existing only in the remote repository are treated as ``added``,
4820 even if it is in fact locally deleted.
4825 even if it is in fact locally deleted.
4821
4826
4822 .. container:: verbose
4827 .. container:: verbose
4823
4828
4824 For remote repository, using --bundle avoids downloading the
4829 For remote repository, using --bundle avoids downloading the
4825 changesets twice if the incoming is followed by a pull.
4830 changesets twice if the incoming is followed by a pull.
4826
4831
4827 Examples:
4832 Examples:
4828
4833
4829 - show incoming changes with patches and full description::
4834 - show incoming changes with patches and full description::
4830
4835
4831 hg incoming -vp
4836 hg incoming -vp
4832
4837
4833 - show incoming changes excluding merges, store a bundle::
4838 - show incoming changes excluding merges, store a bundle::
4834
4839
4835 hg in -vpM --bundle incoming.hg
4840 hg in -vpM --bundle incoming.hg
4836 hg pull incoming.hg
4841 hg pull incoming.hg
4837
4842
4838 - briefly list changes inside a bundle::
4843 - briefly list changes inside a bundle::
4839
4844
4840 hg in changes.hg -T "{desc|firstline}\\n"
4845 hg in changes.hg -T "{desc|firstline}\\n"
4841
4846
4842 Returns 0 if there are incoming changes, 1 otherwise.
4847 Returns 0 if there are incoming changes, 1 otherwise.
4843 """
4848 """
4844 if opts.get('graph'):
4849 if opts.get('graph'):
4845 cmdutil.checkunsupportedgraphflags([], opts)
4850 cmdutil.checkunsupportedgraphflags([], opts)
4846 def display(other, chlist, displayer):
4851 def display(other, chlist, displayer):
4847 revdag = cmdutil.graphrevs(other, chlist, opts)
4852 revdag = cmdutil.graphrevs(other, chlist, opts)
4848 cmdutil.displaygraph(ui, repo, revdag, displayer,
4853 cmdutil.displaygraph(ui, repo, revdag, displayer,
4849 graphmod.asciiedges)
4854 graphmod.asciiedges)
4850
4855
4851 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4856 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4852 return 0
4857 return 0
4853
4858
4854 if opts.get('bundle') and opts.get('subrepos'):
4859 if opts.get('bundle') and opts.get('subrepos'):
4855 raise error.Abort(_('cannot combine --bundle and --subrepos'))
4860 raise error.Abort(_('cannot combine --bundle and --subrepos'))
4856
4861
4857 if opts.get('bookmarks'):
4862 if opts.get('bookmarks'):
4858 source, branches = hg.parseurl(ui.expandpath(source),
4863 source, branches = hg.parseurl(ui.expandpath(source),
4859 opts.get('branch'))
4864 opts.get('branch'))
4860 other = hg.peer(repo, opts, source)
4865 other = hg.peer(repo, opts, source)
4861 if 'bookmarks' not in other.listkeys('namespaces'):
4866 if 'bookmarks' not in other.listkeys('namespaces'):
4862 ui.warn(_("remote doesn't support bookmarks\n"))
4867 ui.warn(_("remote doesn't support bookmarks\n"))
4863 return 0
4868 return 0
4864 ui.status(_('comparing with %s\n') % util.hidepassword(source))
4869 ui.status(_('comparing with %s\n') % util.hidepassword(source))
4865 return bookmarks.incoming(ui, repo, other)
4870 return bookmarks.incoming(ui, repo, other)
4866
4871
4867 repo._subtoppath = ui.expandpath(source)
4872 repo._subtoppath = ui.expandpath(source)
4868 try:
4873 try:
4869 return hg.incoming(ui, repo, source, opts)
4874 return hg.incoming(ui, repo, source, opts)
4870 finally:
4875 finally:
4871 del repo._subtoppath
4876 del repo._subtoppath
4872
4877
4873
4878
4874 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
4879 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
4875 norepo=True)
4880 norepo=True)
4876 def init(ui, dest=".", **opts):
4881 def init(ui, dest=".", **opts):
4877 """create a new repository in the given directory
4882 """create a new repository in the given directory
4878
4883
4879 Initialize a new repository in the given directory. If the given
4884 Initialize a new repository in the given directory. If the given
4880 directory does not exist, it will be created.
4885 directory does not exist, it will be created.
4881
4886
4882 If no directory is given, the current directory is used.
4887 If no directory is given, the current directory is used.
4883
4888
4884 It is possible to specify an ``ssh://`` URL as the destination.
4889 It is possible to specify an ``ssh://`` URL as the destination.
4885 See :hg:`help urls` for more information.
4890 See :hg:`help urls` for more information.
4886
4891
4887 Returns 0 on success.
4892 Returns 0 on success.
4888 """
4893 """
4889 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4894 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4890
4895
4891 @command('locate',
4896 @command('locate',
4892 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
4897 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
4893 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4898 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4894 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
4899 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
4895 ] + walkopts,
4900 ] + walkopts,
4896 _('[OPTION]... [PATTERN]...'))
4901 _('[OPTION]... [PATTERN]...'))
4897 def locate(ui, repo, *pats, **opts):
4902 def locate(ui, repo, *pats, **opts):
4898 """locate files matching specific patterns (DEPRECATED)
4903 """locate files matching specific patterns (DEPRECATED)
4899
4904
4900 Print files under Mercurial control in the working directory whose
4905 Print files under Mercurial control in the working directory whose
4901 names match the given patterns.
4906 names match the given patterns.
4902
4907
4903 By default, this command searches all directories in the working
4908 By default, this command searches all directories in the working
4904 directory. To search just the current directory and its
4909 directory. To search just the current directory and its
4905 subdirectories, use "--include .".
4910 subdirectories, use "--include .".
4906
4911
4907 If no patterns are given to match, this command prints the names
4912 If no patterns are given to match, this command prints the names
4908 of all files under Mercurial control in the working directory.
4913 of all files under Mercurial control in the working directory.
4909
4914
4910 If you want to feed the output of this command into the "xargs"
4915 If you want to feed the output of this command into the "xargs"
4911 command, use the -0 option to both this command and "xargs". This
4916 command, use the -0 option to both this command and "xargs". This
4912 will avoid the problem of "xargs" treating single filenames that
4917 will avoid the problem of "xargs" treating single filenames that
4913 contain whitespace as multiple filenames.
4918 contain whitespace as multiple filenames.
4914
4919
4915 See :hg:`help files` for a more versatile command.
4920 See :hg:`help files` for a more versatile command.
4916
4921
4917 Returns 0 if a match is found, 1 otherwise.
4922 Returns 0 if a match is found, 1 otherwise.
4918 """
4923 """
4919 if opts.get('print0'):
4924 if opts.get('print0'):
4920 end = '\0'
4925 end = '\0'
4921 else:
4926 else:
4922 end = '\n'
4927 end = '\n'
4923 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
4928 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
4924
4929
4925 ret = 1
4930 ret = 1
4926 ctx = repo[rev]
4931 ctx = repo[rev]
4927 m = scmutil.match(ctx, pats, opts, default='relglob',
4932 m = scmutil.match(ctx, pats, opts, default='relglob',
4928 badfn=lambda x, y: False)
4933 badfn=lambda x, y: False)
4929
4934
4930 for abs in ctx.matches(m):
4935 for abs in ctx.matches(m):
4931 if opts.get('fullpath'):
4936 if opts.get('fullpath'):
4932 ui.write(repo.wjoin(abs), end)
4937 ui.write(repo.wjoin(abs), end)
4933 else:
4938 else:
4934 ui.write(((pats and m.rel(abs)) or abs), end)
4939 ui.write(((pats and m.rel(abs)) or abs), end)
4935 ret = 0
4940 ret = 0
4936
4941
4937 return ret
4942 return ret
4938
4943
4939 @command('^log|history',
4944 @command('^log|history',
4940 [('f', 'follow', None,
4945 [('f', 'follow', None,
4941 _('follow changeset history, or file history across copies and renames')),
4946 _('follow changeset history, or file history across copies and renames')),
4942 ('', 'follow-first', None,
4947 ('', 'follow-first', None,
4943 _('only follow the first parent of merge changesets (DEPRECATED)')),
4948 _('only follow the first parent of merge changesets (DEPRECATED)')),
4944 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
4949 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
4945 ('C', 'copies', None, _('show copied files')),
4950 ('C', 'copies', None, _('show copied files')),
4946 ('k', 'keyword', [],
4951 ('k', 'keyword', [],
4947 _('do case-insensitive search for a given text'), _('TEXT')),
4952 _('do case-insensitive search for a given text'), _('TEXT')),
4948 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
4953 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
4949 ('', 'removed', None, _('include revisions where files were removed')),
4954 ('', 'removed', None, _('include revisions where files were removed')),
4950 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4955 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4951 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4956 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4952 ('', 'only-branch', [],
4957 ('', 'only-branch', [],
4953 _('show only changesets within the given named branch (DEPRECATED)'),
4958 _('show only changesets within the given named branch (DEPRECATED)'),
4954 _('BRANCH')),
4959 _('BRANCH')),
4955 ('b', 'branch', [],
4960 ('b', 'branch', [],
4956 _('show changesets within the given named branch'), _('BRANCH')),
4961 _('show changesets within the given named branch'), _('BRANCH')),
4957 ('P', 'prune', [],
4962 ('P', 'prune', [],
4958 _('do not display revision or any of its ancestors'), _('REV')),
4963 _('do not display revision or any of its ancestors'), _('REV')),
4959 ] + logopts + walkopts,
4964 ] + logopts + walkopts,
4960 _('[OPTION]... [FILE]'),
4965 _('[OPTION]... [FILE]'),
4961 inferrepo=True)
4966 inferrepo=True)
4962 def log(ui, repo, *pats, **opts):
4967 def log(ui, repo, *pats, **opts):
4963 """show revision history of entire repository or files
4968 """show revision history of entire repository or files
4964
4969
4965 Print the revision history of the specified files or the entire
4970 Print the revision history of the specified files or the entire
4966 project.
4971 project.
4967
4972
4968 If no revision range is specified, the default is ``tip:0`` unless
4973 If no revision range is specified, the default is ``tip:0`` unless
4969 --follow is set, in which case the working directory parent is
4974 --follow is set, in which case the working directory parent is
4970 used as the starting revision.
4975 used as the starting revision.
4971
4976
4972 File history is shown without following rename or copy history of
4977 File history is shown without following rename or copy history of
4973 files. Use -f/--follow with a filename to follow history across
4978 files. Use -f/--follow with a filename to follow history across
4974 renames and copies. --follow without a filename will only show
4979 renames and copies. --follow without a filename will only show
4975 ancestors or descendants of the starting revision.
4980 ancestors or descendants of the starting revision.
4976
4981
4977 By default this command prints revision number and changeset id,
4982 By default this command prints revision number and changeset id,
4978 tags, non-trivial parents, user, date and time, and a summary for
4983 tags, non-trivial parents, user, date and time, and a summary for
4979 each commit. When the -v/--verbose switch is used, the list of
4984 each commit. When the -v/--verbose switch is used, the list of
4980 changed files and full commit message are shown.
4985 changed files and full commit message are shown.
4981
4986
4982 With --graph the revisions are shown as an ASCII art DAG with the most
4987 With --graph the revisions are shown as an ASCII art DAG with the most
4983 recent changeset at the top.
4988 recent changeset at the top.
4984 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4989 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4985 and '+' represents a fork where the changeset from the lines below is a
4990 and '+' represents a fork where the changeset from the lines below is a
4986 parent of the 'o' merge on the same line.
4991 parent of the 'o' merge on the same line.
4987
4992
4988 .. note::
4993 .. note::
4989
4994
4990 :hg:`log --patch` may generate unexpected diff output for merge
4995 :hg:`log --patch` may generate unexpected diff output for merge
4991 changesets, as it will only compare the merge changeset against
4996 changesets, as it will only compare the merge changeset against
4992 its first parent. Also, only files different from BOTH parents
4997 its first parent. Also, only files different from BOTH parents
4993 will appear in files:.
4998 will appear in files:.
4994
4999
4995 .. note::
5000 .. note::
4996
5001
4997 For performance reasons, :hg:`log FILE` may omit duplicate changes
5002 For performance reasons, :hg:`log FILE` may omit duplicate changes
4998 made on branches and will not show removals or mode changes. To
5003 made on branches and will not show removals or mode changes. To
4999 see all such changes, use the --removed switch.
5004 see all such changes, use the --removed switch.
5000
5005
5001 .. container:: verbose
5006 .. container:: verbose
5002
5007
5003 Some examples:
5008 Some examples:
5004
5009
5005 - changesets with full descriptions and file lists::
5010 - changesets with full descriptions and file lists::
5006
5011
5007 hg log -v
5012 hg log -v
5008
5013
5009 - changesets ancestral to the working directory::
5014 - changesets ancestral to the working directory::
5010
5015
5011 hg log -f
5016 hg log -f
5012
5017
5013 - last 10 commits on the current branch::
5018 - last 10 commits on the current branch::
5014
5019
5015 hg log -l 10 -b .
5020 hg log -l 10 -b .
5016
5021
5017 - changesets showing all modifications of a file, including removals::
5022 - changesets showing all modifications of a file, including removals::
5018
5023
5019 hg log --removed file.c
5024 hg log --removed file.c
5020
5025
5021 - all changesets that touch a directory, with diffs, excluding merges::
5026 - all changesets that touch a directory, with diffs, excluding merges::
5022
5027
5023 hg log -Mp lib/
5028 hg log -Mp lib/
5024
5029
5025 - all revision numbers that match a keyword::
5030 - all revision numbers that match a keyword::
5026
5031
5027 hg log -k bug --template "{rev}\\n"
5032 hg log -k bug --template "{rev}\\n"
5028
5033
5029 - the full hash identifier of the working directory parent::
5034 - the full hash identifier of the working directory parent::
5030
5035
5031 hg log -r . --template "{node}\\n"
5036 hg log -r . --template "{node}\\n"
5032
5037
5033 - list available log templates::
5038 - list available log templates::
5034
5039
5035 hg log -T list
5040 hg log -T list
5036
5041
5037 - check if a given changeset is included in a tagged release::
5042 - check if a given changeset is included in a tagged release::
5038
5043
5039 hg log -r "a21ccf and ancestor(1.9)"
5044 hg log -r "a21ccf and ancestor(1.9)"
5040
5045
5041 - find all changesets by some user in a date range::
5046 - find all changesets by some user in a date range::
5042
5047
5043 hg log -k alice -d "may 2008 to jul 2008"
5048 hg log -k alice -d "may 2008 to jul 2008"
5044
5049
5045 - summary of all changesets after the last tag::
5050 - summary of all changesets after the last tag::
5046
5051
5047 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
5052 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
5048
5053
5049 See :hg:`help dates` for a list of formats valid for -d/--date.
5054 See :hg:`help dates` for a list of formats valid for -d/--date.
5050
5055
5051 See :hg:`help revisions` and :hg:`help revsets` for more about
5056 See :hg:`help revisions` and :hg:`help revsets` for more about
5052 specifying and ordering revisions.
5057 specifying and ordering revisions.
5053
5058
5054 See :hg:`help templates` for more about pre-packaged styles and
5059 See :hg:`help templates` for more about pre-packaged styles and
5055 specifying custom templates.
5060 specifying custom templates.
5056
5061
5057 Returns 0 on success.
5062 Returns 0 on success.
5058
5063
5059 """
5064 """
5060 if opts.get('follow') and opts.get('rev'):
5065 if opts.get('follow') and opts.get('rev'):
5061 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
5066 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
5062 del opts['follow']
5067 del opts['follow']
5063
5068
5064 if opts.get('graph'):
5069 if opts.get('graph'):
5065 return cmdutil.graphlog(ui, repo, *pats, **opts)
5070 return cmdutil.graphlog(ui, repo, *pats, **opts)
5066
5071
5067 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
5072 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
5068 limit = cmdutil.loglimit(opts)
5073 limit = cmdutil.loglimit(opts)
5069 count = 0
5074 count = 0
5070
5075
5071 getrenamed = None
5076 getrenamed = None
5072 if opts.get('copies'):
5077 if opts.get('copies'):
5073 endrev = None
5078 endrev = None
5074 if opts.get('rev'):
5079 if opts.get('rev'):
5075 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
5080 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
5076 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
5081 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
5077
5082
5078 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
5083 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
5079 for rev in revs:
5084 for rev in revs:
5080 if count == limit:
5085 if count == limit:
5081 break
5086 break
5082 ctx = repo[rev]
5087 ctx = repo[rev]
5083 copies = None
5088 copies = None
5084 if getrenamed is not None and rev:
5089 if getrenamed is not None and rev:
5085 copies = []
5090 copies = []
5086 for fn in ctx.files():
5091 for fn in ctx.files():
5087 rename = getrenamed(fn, rev)
5092 rename = getrenamed(fn, rev)
5088 if rename:
5093 if rename:
5089 copies.append((fn, rename[0]))
5094 copies.append((fn, rename[0]))
5090 if filematcher:
5095 if filematcher:
5091 revmatchfn = filematcher(ctx.rev())
5096 revmatchfn = filematcher(ctx.rev())
5092 else:
5097 else:
5093 revmatchfn = None
5098 revmatchfn = None
5094 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
5099 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
5095 if displayer.flush(ctx):
5100 if displayer.flush(ctx):
5096 count += 1
5101 count += 1
5097
5102
5098 displayer.close()
5103 displayer.close()
5099
5104
5100 @command('manifest',
5105 @command('manifest',
5101 [('r', 'rev', '', _('revision to display'), _('REV')),
5106 [('r', 'rev', '', _('revision to display'), _('REV')),
5102 ('', 'all', False, _("list files from all revisions"))]
5107 ('', 'all', False, _("list files from all revisions"))]
5103 + formatteropts,
5108 + formatteropts,
5104 _('[-r REV]'))
5109 _('[-r REV]'))
5105 def manifest(ui, repo, node=None, rev=None, **opts):
5110 def manifest(ui, repo, node=None, rev=None, **opts):
5106 """output the current or given revision of the project manifest
5111 """output the current or given revision of the project manifest
5107
5112
5108 Print a list of version controlled files for the given revision.
5113 Print a list of version controlled files for the given revision.
5109 If no revision is given, the first parent of the working directory
5114 If no revision is given, the first parent of the working directory
5110 is used, or the null revision if no revision is checked out.
5115 is used, or the null revision if no revision is checked out.
5111
5116
5112 With -v, print file permissions, symlink and executable bits.
5117 With -v, print file permissions, symlink and executable bits.
5113 With --debug, print file revision hashes.
5118 With --debug, print file revision hashes.
5114
5119
5115 If option --all is specified, the list of all files from all revisions
5120 If option --all is specified, the list of all files from all revisions
5116 is printed. This includes deleted and renamed files.
5121 is printed. This includes deleted and renamed files.
5117
5122
5118 Returns 0 on success.
5123 Returns 0 on success.
5119 """
5124 """
5120
5125
5121 fm = ui.formatter('manifest', opts)
5126 fm = ui.formatter('manifest', opts)
5122
5127
5123 if opts.get('all'):
5128 if opts.get('all'):
5124 if rev or node:
5129 if rev or node:
5125 raise error.Abort(_("can't specify a revision with --all"))
5130 raise error.Abort(_("can't specify a revision with --all"))
5126
5131
5127 res = []
5132 res = []
5128 prefix = "data/"
5133 prefix = "data/"
5129 suffix = ".i"
5134 suffix = ".i"
5130 plen = len(prefix)
5135 plen = len(prefix)
5131 slen = len(suffix)
5136 slen = len(suffix)
5132 with repo.lock():
5137 with repo.lock():
5133 for fn, b, size in repo.store.datafiles():
5138 for fn, b, size in repo.store.datafiles():
5134 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
5139 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
5135 res.append(fn[plen:-slen])
5140 res.append(fn[plen:-slen])
5136 for f in res:
5141 for f in res:
5137 fm.startitem()
5142 fm.startitem()
5138 fm.write("path", '%s\n', f)
5143 fm.write("path", '%s\n', f)
5139 fm.end()
5144 fm.end()
5140 return
5145 return
5141
5146
5142 if rev and node:
5147 if rev and node:
5143 raise error.Abort(_("please specify just one revision"))
5148 raise error.Abort(_("please specify just one revision"))
5144
5149
5145 if not node:
5150 if not node:
5146 node = rev
5151 node = rev
5147
5152
5148 char = {'l': '@', 'x': '*', '': ''}
5153 char = {'l': '@', 'x': '*', '': ''}
5149 mode = {'l': '644', 'x': '755', '': '644'}
5154 mode = {'l': '644', 'x': '755', '': '644'}
5150 ctx = scmutil.revsingle(repo, node)
5155 ctx = scmutil.revsingle(repo, node)
5151 mf = ctx.manifest()
5156 mf = ctx.manifest()
5152 for f in ctx:
5157 for f in ctx:
5153 fm.startitem()
5158 fm.startitem()
5154 fl = ctx[f].flags()
5159 fl = ctx[f].flags()
5155 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
5160 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
5156 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
5161 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
5157 fm.write('path', '%s\n', f)
5162 fm.write('path', '%s\n', f)
5158 fm.end()
5163 fm.end()
5159
5164
5160 @command('^merge',
5165 @command('^merge',
5161 [('f', 'force', None,
5166 [('f', 'force', None,
5162 _('force a merge including outstanding changes (DEPRECATED)')),
5167 _('force a merge including outstanding changes (DEPRECATED)')),
5163 ('r', 'rev', '', _('revision to merge'), _('REV')),
5168 ('r', 'rev', '', _('revision to merge'), _('REV')),
5164 ('P', 'preview', None,
5169 ('P', 'preview', None,
5165 _('review revisions to merge (no merge is performed)'))
5170 _('review revisions to merge (no merge is performed)'))
5166 ] + mergetoolopts,
5171 ] + mergetoolopts,
5167 _('[-P] [-f] [[-r] REV]'))
5172 _('[-P] [-f] [[-r] REV]'))
5168 def merge(ui, repo, node=None, **opts):
5173 def merge(ui, repo, node=None, **opts):
5169 """merge another revision into working directory
5174 """merge another revision into working directory
5170
5175
5171 The current working directory is updated with all changes made in
5176 The current working directory is updated with all changes made in
5172 the requested revision since the last common predecessor revision.
5177 the requested revision since the last common predecessor revision.
5173
5178
5174 Files that changed between either parent are marked as changed for
5179 Files that changed between either parent are marked as changed for
5175 the next commit and a commit must be performed before any further
5180 the next commit and a commit must be performed before any further
5176 updates to the repository are allowed. The next commit will have
5181 updates to the repository are allowed. The next commit will have
5177 two parents.
5182 two parents.
5178
5183
5179 ``--tool`` can be used to specify the merge tool used for file
5184 ``--tool`` can be used to specify the merge tool used for file
5180 merges. It overrides the HGMERGE environment variable and your
5185 merges. It overrides the HGMERGE environment variable and your
5181 configuration files. See :hg:`help merge-tools` for options.
5186 configuration files. See :hg:`help merge-tools` for options.
5182
5187
5183 If no revision is specified, the working directory's parent is a
5188 If no revision is specified, the working directory's parent is a
5184 head revision, and the current branch contains exactly one other
5189 head revision, and the current branch contains exactly one other
5185 head, the other head is merged with by default. Otherwise, an
5190 head, the other head is merged with by default. Otherwise, an
5186 explicit revision with which to merge with must be provided.
5191 explicit revision with which to merge with must be provided.
5187
5192
5188 See :hg:`help resolve` for information on handling file conflicts.
5193 See :hg:`help resolve` for information on handling file conflicts.
5189
5194
5190 To undo an uncommitted merge, use :hg:`update --clean .` which
5195 To undo an uncommitted merge, use :hg:`update --clean .` which
5191 will check out a clean copy of the original merge parent, losing
5196 will check out a clean copy of the original merge parent, losing
5192 all changes.
5197 all changes.
5193
5198
5194 Returns 0 on success, 1 if there are unresolved files.
5199 Returns 0 on success, 1 if there are unresolved files.
5195 """
5200 """
5196
5201
5197 if opts.get('rev') and node:
5202 if opts.get('rev') and node:
5198 raise error.Abort(_("please specify just one revision"))
5203 raise error.Abort(_("please specify just one revision"))
5199 if not node:
5204 if not node:
5200 node = opts.get('rev')
5205 node = opts.get('rev')
5201
5206
5202 if node:
5207 if node:
5203 node = scmutil.revsingle(repo, node).node()
5208 node = scmutil.revsingle(repo, node).node()
5204
5209
5205 if not node:
5210 if not node:
5206 node = repo[destutil.destmerge(repo)].node()
5211 node = repo[destutil.destmerge(repo)].node()
5207
5212
5208 if opts.get('preview'):
5213 if opts.get('preview'):
5209 # find nodes that are ancestors of p2 but not of p1
5214 # find nodes that are ancestors of p2 but not of p1
5210 p1 = repo.lookup('.')
5215 p1 = repo.lookup('.')
5211 p2 = repo.lookup(node)
5216 p2 = repo.lookup(node)
5212 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
5217 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
5213
5218
5214 displayer = cmdutil.show_changeset(ui, repo, opts)
5219 displayer = cmdutil.show_changeset(ui, repo, opts)
5215 for node in nodes:
5220 for node in nodes:
5216 displayer.show(repo[node])
5221 displayer.show(repo[node])
5217 displayer.close()
5222 displayer.close()
5218 return 0
5223 return 0
5219
5224
5220 try:
5225 try:
5221 # ui.forcemerge is an internal variable, do not document
5226 # ui.forcemerge is an internal variable, do not document
5222 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
5227 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
5223 return hg.merge(repo, node, force=opts.get('force'))
5228 return hg.merge(repo, node, force=opts.get('force'))
5224 finally:
5229 finally:
5225 ui.setconfig('ui', 'forcemerge', '', 'merge')
5230 ui.setconfig('ui', 'forcemerge', '', 'merge')
5226
5231
5227 @command('outgoing|out',
5232 @command('outgoing|out',
5228 [('f', 'force', None, _('run even when the destination is unrelated')),
5233 [('f', 'force', None, _('run even when the destination is unrelated')),
5229 ('r', 'rev', [],
5234 ('r', 'rev', [],
5230 _('a changeset intended to be included in the destination'), _('REV')),
5235 _('a changeset intended to be included in the destination'), _('REV')),
5231 ('n', 'newest-first', None, _('show newest record first')),
5236 ('n', 'newest-first', None, _('show newest record first')),
5232 ('B', 'bookmarks', False, _('compare bookmarks')),
5237 ('B', 'bookmarks', False, _('compare bookmarks')),
5233 ('b', 'branch', [], _('a specific branch you would like to push'),
5238 ('b', 'branch', [], _('a specific branch you would like to push'),
5234 _('BRANCH')),
5239 _('BRANCH')),
5235 ] + logopts + remoteopts + subrepoopts,
5240 ] + logopts + remoteopts + subrepoopts,
5236 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
5241 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
5237 def outgoing(ui, repo, dest=None, **opts):
5242 def outgoing(ui, repo, dest=None, **opts):
5238 """show changesets not found in the destination
5243 """show changesets not found in the destination
5239
5244
5240 Show changesets not found in the specified destination repository
5245 Show changesets not found in the specified destination repository
5241 or the default push location. These are the changesets that would
5246 or the default push location. These are the changesets that would
5242 be pushed if a push was requested.
5247 be pushed if a push was requested.
5243
5248
5244 See pull for details of valid destination formats.
5249 See pull for details of valid destination formats.
5245
5250
5246 .. container:: verbose
5251 .. container:: verbose
5247
5252
5248 With -B/--bookmarks, the result of bookmark comparison between
5253 With -B/--bookmarks, the result of bookmark comparison between
5249 local and remote repositories is displayed. With -v/--verbose,
5254 local and remote repositories is displayed. With -v/--verbose,
5250 status is also displayed for each bookmark like below::
5255 status is also displayed for each bookmark like below::
5251
5256
5252 BM1 01234567890a added
5257 BM1 01234567890a added
5253 BM2 deleted
5258 BM2 deleted
5254 BM3 234567890abc advanced
5259 BM3 234567890abc advanced
5255 BM4 34567890abcd diverged
5260 BM4 34567890abcd diverged
5256 BM5 4567890abcde changed
5261 BM5 4567890abcde changed
5257
5262
5258 The action taken when pushing depends on the
5263 The action taken when pushing depends on the
5259 status of each bookmark:
5264 status of each bookmark:
5260
5265
5261 :``added``: push with ``-B`` will create it
5266 :``added``: push with ``-B`` will create it
5262 :``deleted``: push with ``-B`` will delete it
5267 :``deleted``: push with ``-B`` will delete it
5263 :``advanced``: push will update it
5268 :``advanced``: push will update it
5264 :``diverged``: push with ``-B`` will update it
5269 :``diverged``: push with ``-B`` will update it
5265 :``changed``: push with ``-B`` will update it
5270 :``changed``: push with ``-B`` will update it
5266
5271
5267 From the point of view of pushing behavior, bookmarks
5272 From the point of view of pushing behavior, bookmarks
5268 existing only in the remote repository are treated as
5273 existing only in the remote repository are treated as
5269 ``deleted``, even if it is in fact added remotely.
5274 ``deleted``, even if it is in fact added remotely.
5270
5275
5271 Returns 0 if there are outgoing changes, 1 otherwise.
5276 Returns 0 if there are outgoing changes, 1 otherwise.
5272 """
5277 """
5273 if opts.get('graph'):
5278 if opts.get('graph'):
5274 cmdutil.checkunsupportedgraphflags([], opts)
5279 cmdutil.checkunsupportedgraphflags([], opts)
5275 o, other = hg._outgoing(ui, repo, dest, opts)
5280 o, other = hg._outgoing(ui, repo, dest, opts)
5276 if not o:
5281 if not o:
5277 cmdutil.outgoinghooks(ui, repo, other, opts, o)
5282 cmdutil.outgoinghooks(ui, repo, other, opts, o)
5278 return
5283 return
5279
5284
5280 revdag = cmdutil.graphrevs(repo, o, opts)
5285 revdag = cmdutil.graphrevs(repo, o, opts)
5281 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
5286 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
5282 cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
5287 cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
5283 cmdutil.outgoinghooks(ui, repo, other, opts, o)
5288 cmdutil.outgoinghooks(ui, repo, other, opts, o)
5284 return 0
5289 return 0
5285
5290
5286 if opts.get('bookmarks'):
5291 if opts.get('bookmarks'):
5287 dest = ui.expandpath(dest or 'default-push', dest or 'default')
5292 dest = ui.expandpath(dest or 'default-push', dest or 'default')
5288 dest, branches = hg.parseurl(dest, opts.get('branch'))
5293 dest, branches = hg.parseurl(dest, opts.get('branch'))
5289 other = hg.peer(repo, opts, dest)
5294 other = hg.peer(repo, opts, dest)
5290 if 'bookmarks' not in other.listkeys('namespaces'):
5295 if 'bookmarks' not in other.listkeys('namespaces'):
5291 ui.warn(_("remote doesn't support bookmarks\n"))
5296 ui.warn(_("remote doesn't support bookmarks\n"))
5292 return 0
5297 return 0
5293 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
5298 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
5294 return bookmarks.outgoing(ui, repo, other)
5299 return bookmarks.outgoing(ui, repo, other)
5295
5300
5296 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
5301 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
5297 try:
5302 try:
5298 return hg.outgoing(ui, repo, dest, opts)
5303 return hg.outgoing(ui, repo, dest, opts)
5299 finally:
5304 finally:
5300 del repo._subtoppath
5305 del repo._subtoppath
5301
5306
5302 @command('parents',
5307 @command('parents',
5303 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
5308 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
5304 ] + templateopts,
5309 ] + templateopts,
5305 _('[-r REV] [FILE]'),
5310 _('[-r REV] [FILE]'),
5306 inferrepo=True)
5311 inferrepo=True)
5307 def parents(ui, repo, file_=None, **opts):
5312 def parents(ui, repo, file_=None, **opts):
5308 """show the parents of the working directory or revision (DEPRECATED)
5313 """show the parents of the working directory or revision (DEPRECATED)
5309
5314
5310 Print the working directory's parent revisions. If a revision is
5315 Print the working directory's parent revisions. If a revision is
5311 given via -r/--rev, the parent of that revision will be printed.
5316 given via -r/--rev, the parent of that revision will be printed.
5312 If a file argument is given, the revision in which the file was
5317 If a file argument is given, the revision in which the file was
5313 last changed (before the working directory revision or the
5318 last changed (before the working directory revision or the
5314 argument to --rev if given) is printed.
5319 argument to --rev if given) is printed.
5315
5320
5316 This command is equivalent to::
5321 This command is equivalent to::
5317
5322
5318 hg log -r "p1()+p2()" or
5323 hg log -r "p1()+p2()" or
5319 hg log -r "p1(REV)+p2(REV)" or
5324 hg log -r "p1(REV)+p2(REV)" or
5320 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
5325 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
5321 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
5326 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
5322
5327
5323 See :hg:`summary` and :hg:`help revsets` for related information.
5328 See :hg:`summary` and :hg:`help revsets` for related information.
5324
5329
5325 Returns 0 on success.
5330 Returns 0 on success.
5326 """
5331 """
5327
5332
5328 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
5333 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
5329
5334
5330 if file_:
5335 if file_:
5331 m = scmutil.match(ctx, (file_,), opts)
5336 m = scmutil.match(ctx, (file_,), opts)
5332 if m.anypats() or len(m.files()) != 1:
5337 if m.anypats() or len(m.files()) != 1:
5333 raise error.Abort(_('can only specify an explicit filename'))
5338 raise error.Abort(_('can only specify an explicit filename'))
5334 file_ = m.files()[0]
5339 file_ = m.files()[0]
5335 filenodes = []
5340 filenodes = []
5336 for cp in ctx.parents():
5341 for cp in ctx.parents():
5337 if not cp:
5342 if not cp:
5338 continue
5343 continue
5339 try:
5344 try:
5340 filenodes.append(cp.filenode(file_))
5345 filenodes.append(cp.filenode(file_))
5341 except error.LookupError:
5346 except error.LookupError:
5342 pass
5347 pass
5343 if not filenodes:
5348 if not filenodes:
5344 raise error.Abort(_("'%s' not found in manifest!") % file_)
5349 raise error.Abort(_("'%s' not found in manifest!") % file_)
5345 p = []
5350 p = []
5346 for fn in filenodes:
5351 for fn in filenodes:
5347 fctx = repo.filectx(file_, fileid=fn)
5352 fctx = repo.filectx(file_, fileid=fn)
5348 p.append(fctx.node())
5353 p.append(fctx.node())
5349 else:
5354 else:
5350 p = [cp.node() for cp in ctx.parents()]
5355 p = [cp.node() for cp in ctx.parents()]
5351
5356
5352 displayer = cmdutil.show_changeset(ui, repo, opts)
5357 displayer = cmdutil.show_changeset(ui, repo, opts)
5353 for n in p:
5358 for n in p:
5354 if n != nullid:
5359 if n != nullid:
5355 displayer.show(repo[n])
5360 displayer.show(repo[n])
5356 displayer.close()
5361 displayer.close()
5357
5362
5358 @command('paths', formatteropts, _('[NAME]'), optionalrepo=True)
5363 @command('paths', formatteropts, _('[NAME]'), optionalrepo=True)
5359 def paths(ui, repo, search=None, **opts):
5364 def paths(ui, repo, search=None, **opts):
5360 """show aliases for remote repositories
5365 """show aliases for remote repositories
5361
5366
5362 Show definition of symbolic path name NAME. If no name is given,
5367 Show definition of symbolic path name NAME. If no name is given,
5363 show definition of all available names.
5368 show definition of all available names.
5364
5369
5365 Option -q/--quiet suppresses all output when searching for NAME
5370 Option -q/--quiet suppresses all output when searching for NAME
5366 and shows only the path names when listing all definitions.
5371 and shows only the path names when listing all definitions.
5367
5372
5368 Path names are defined in the [paths] section of your
5373 Path names are defined in the [paths] section of your
5369 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
5374 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
5370 repository, ``.hg/hgrc`` is used, too.
5375 repository, ``.hg/hgrc`` is used, too.
5371
5376
5372 The path names ``default`` and ``default-push`` have a special
5377 The path names ``default`` and ``default-push`` have a special
5373 meaning. When performing a push or pull operation, they are used
5378 meaning. When performing a push or pull operation, they are used
5374 as fallbacks if no location is specified on the command-line.
5379 as fallbacks if no location is specified on the command-line.
5375 When ``default-push`` is set, it will be used for push and
5380 When ``default-push`` is set, it will be used for push and
5376 ``default`` will be used for pull; otherwise ``default`` is used
5381 ``default`` will be used for pull; otherwise ``default`` is used
5377 as the fallback for both. When cloning a repository, the clone
5382 as the fallback for both. When cloning a repository, the clone
5378 source is written as ``default`` in ``.hg/hgrc``.
5383 source is written as ``default`` in ``.hg/hgrc``.
5379
5384
5380 .. note::
5385 .. note::
5381
5386
5382 ``default`` and ``default-push`` apply to all inbound (e.g.
5387 ``default`` and ``default-push`` apply to all inbound (e.g.
5383 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
5388 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
5384 and :hg:`bundle`) operations.
5389 and :hg:`bundle`) operations.
5385
5390
5386 See :hg:`help urls` for more information.
5391 See :hg:`help urls` for more information.
5387
5392
5388 Returns 0 on success.
5393 Returns 0 on success.
5389 """
5394 """
5390 if search:
5395 if search:
5391 pathitems = [(name, path) for name, path in ui.paths.iteritems()
5396 pathitems = [(name, path) for name, path in ui.paths.iteritems()
5392 if name == search]
5397 if name == search]
5393 else:
5398 else:
5394 pathitems = sorted(ui.paths.iteritems())
5399 pathitems = sorted(ui.paths.iteritems())
5395
5400
5396 fm = ui.formatter('paths', opts)
5401 fm = ui.formatter('paths', opts)
5397 if fm:
5402 if fm:
5398 hidepassword = str
5403 hidepassword = str
5399 else:
5404 else:
5400 hidepassword = util.hidepassword
5405 hidepassword = util.hidepassword
5401 if ui.quiet:
5406 if ui.quiet:
5402 namefmt = '%s\n'
5407 namefmt = '%s\n'
5403 else:
5408 else:
5404 namefmt = '%s = '
5409 namefmt = '%s = '
5405 showsubopts = not search and not ui.quiet
5410 showsubopts = not search and not ui.quiet
5406
5411
5407 for name, path in pathitems:
5412 for name, path in pathitems:
5408 fm.startitem()
5413 fm.startitem()
5409 fm.condwrite(not search, 'name', namefmt, name)
5414 fm.condwrite(not search, 'name', namefmt, name)
5410 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
5415 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
5411 for subopt, value in sorted(path.suboptions.items()):
5416 for subopt, value in sorted(path.suboptions.items()):
5412 assert subopt not in ('name', 'url')
5417 assert subopt not in ('name', 'url')
5413 if showsubopts:
5418 if showsubopts:
5414 fm.plain('%s:%s = ' % (name, subopt))
5419 fm.plain('%s:%s = ' % (name, subopt))
5415 fm.condwrite(showsubopts, subopt, '%s\n', value)
5420 fm.condwrite(showsubopts, subopt, '%s\n', value)
5416
5421
5417 fm.end()
5422 fm.end()
5418
5423
5419 if search and not pathitems:
5424 if search and not pathitems:
5420 if not ui.quiet:
5425 if not ui.quiet:
5421 ui.warn(_("not found!\n"))
5426 ui.warn(_("not found!\n"))
5422 return 1
5427 return 1
5423 else:
5428 else:
5424 return 0
5429 return 0
5425
5430
5426 @command('phase',
5431 @command('phase',
5427 [('p', 'public', False, _('set changeset phase to public')),
5432 [('p', 'public', False, _('set changeset phase to public')),
5428 ('d', 'draft', False, _('set changeset phase to draft')),
5433 ('d', 'draft', False, _('set changeset phase to draft')),
5429 ('s', 'secret', False, _('set changeset phase to secret')),
5434 ('s', 'secret', False, _('set changeset phase to secret')),
5430 ('f', 'force', False, _('allow to move boundary backward')),
5435 ('f', 'force', False, _('allow to move boundary backward')),
5431 ('r', 'rev', [], _('target revision'), _('REV')),
5436 ('r', 'rev', [], _('target revision'), _('REV')),
5432 ],
5437 ],
5433 _('[-p|-d|-s] [-f] [-r] [REV...]'))
5438 _('[-p|-d|-s] [-f] [-r] [REV...]'))
5434 def phase(ui, repo, *revs, **opts):
5439 def phase(ui, repo, *revs, **opts):
5435 """set or show the current phase name
5440 """set or show the current phase name
5436
5441
5437 With no argument, show the phase name of the current revision(s).
5442 With no argument, show the phase name of the current revision(s).
5438
5443
5439 With one of -p/--public, -d/--draft or -s/--secret, change the
5444 With one of -p/--public, -d/--draft or -s/--secret, change the
5440 phase value of the specified revisions.
5445 phase value of the specified revisions.
5441
5446
5442 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
5447 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
5443 lower phase to an higher phase. Phases are ordered as follows::
5448 lower phase to an higher phase. Phases are ordered as follows::
5444
5449
5445 public < draft < secret
5450 public < draft < secret
5446
5451
5447 Returns 0 on success, 1 if some phases could not be changed.
5452 Returns 0 on success, 1 if some phases could not be changed.
5448
5453
5449 (For more information about the phases concept, see :hg:`help phases`.)
5454 (For more information about the phases concept, see :hg:`help phases`.)
5450 """
5455 """
5451 # search for a unique phase argument
5456 # search for a unique phase argument
5452 targetphase = None
5457 targetphase = None
5453 for idx, name in enumerate(phases.phasenames):
5458 for idx, name in enumerate(phases.phasenames):
5454 if opts[name]:
5459 if opts[name]:
5455 if targetphase is not None:
5460 if targetphase is not None:
5456 raise error.Abort(_('only one phase can be specified'))
5461 raise error.Abort(_('only one phase can be specified'))
5457 targetphase = idx
5462 targetphase = idx
5458
5463
5459 # look for specified revision
5464 # look for specified revision
5460 revs = list(revs)
5465 revs = list(revs)
5461 revs.extend(opts['rev'])
5466 revs.extend(opts['rev'])
5462 if not revs:
5467 if not revs:
5463 # display both parents as the second parent phase can influence
5468 # display both parents as the second parent phase can influence
5464 # the phase of a merge commit
5469 # the phase of a merge commit
5465 revs = [c.rev() for c in repo[None].parents()]
5470 revs = [c.rev() for c in repo[None].parents()]
5466
5471
5467 revs = scmutil.revrange(repo, revs)
5472 revs = scmutil.revrange(repo, revs)
5468
5473
5469 lock = None
5474 lock = None
5470 ret = 0
5475 ret = 0
5471 if targetphase is None:
5476 if targetphase is None:
5472 # display
5477 # display
5473 for r in revs:
5478 for r in revs:
5474 ctx = repo[r]
5479 ctx = repo[r]
5475 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5480 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5476 else:
5481 else:
5477 tr = None
5482 tr = None
5478 lock = repo.lock()
5483 lock = repo.lock()
5479 try:
5484 try:
5480 tr = repo.transaction("phase")
5485 tr = repo.transaction("phase")
5481 # set phase
5486 # set phase
5482 if not revs:
5487 if not revs:
5483 raise error.Abort(_('empty revision set'))
5488 raise error.Abort(_('empty revision set'))
5484 nodes = [repo[r].node() for r in revs]
5489 nodes = [repo[r].node() for r in revs]
5485 # moving revision from public to draft may hide them
5490 # moving revision from public to draft may hide them
5486 # We have to check result on an unfiltered repository
5491 # We have to check result on an unfiltered repository
5487 unfi = repo.unfiltered()
5492 unfi = repo.unfiltered()
5488 getphase = unfi._phasecache.phase
5493 getphase = unfi._phasecache.phase
5489 olddata = [getphase(unfi, r) for r in unfi]
5494 olddata = [getphase(unfi, r) for r in unfi]
5490 phases.advanceboundary(repo, tr, targetphase, nodes)
5495 phases.advanceboundary(repo, tr, targetphase, nodes)
5491 if opts['force']:
5496 if opts['force']:
5492 phases.retractboundary(repo, tr, targetphase, nodes)
5497 phases.retractboundary(repo, tr, targetphase, nodes)
5493 tr.close()
5498 tr.close()
5494 finally:
5499 finally:
5495 if tr is not None:
5500 if tr is not None:
5496 tr.release()
5501 tr.release()
5497 lock.release()
5502 lock.release()
5498 getphase = unfi._phasecache.phase
5503 getphase = unfi._phasecache.phase
5499 newdata = [getphase(unfi, r) for r in unfi]
5504 newdata = [getphase(unfi, r) for r in unfi]
5500 changes = sum(newdata[r] != olddata[r] for r in unfi)
5505 changes = sum(newdata[r] != olddata[r] for r in unfi)
5501 cl = unfi.changelog
5506 cl = unfi.changelog
5502 rejected = [n for n in nodes
5507 rejected = [n for n in nodes
5503 if newdata[cl.rev(n)] < targetphase]
5508 if newdata[cl.rev(n)] < targetphase]
5504 if rejected:
5509 if rejected:
5505 ui.warn(_('cannot move %i changesets to a higher '
5510 ui.warn(_('cannot move %i changesets to a higher '
5506 'phase, use --force\n') % len(rejected))
5511 'phase, use --force\n') % len(rejected))
5507 ret = 1
5512 ret = 1
5508 if changes:
5513 if changes:
5509 msg = _('phase changed for %i changesets\n') % changes
5514 msg = _('phase changed for %i changesets\n') % changes
5510 if ret:
5515 if ret:
5511 ui.status(msg)
5516 ui.status(msg)
5512 else:
5517 else:
5513 ui.note(msg)
5518 ui.note(msg)
5514 else:
5519 else:
5515 ui.warn(_('no phases changed\n'))
5520 ui.warn(_('no phases changed\n'))
5516 return ret
5521 return ret
5517
5522
5518 def postincoming(ui, repo, modheads, optupdate, checkout):
5523 def postincoming(ui, repo, modheads, optupdate, checkout):
5519 if modheads == 0:
5524 if modheads == 0:
5520 return
5525 return
5521 if optupdate:
5526 if optupdate:
5522 try:
5527 try:
5523 brev = checkout
5528 brev = checkout
5524 movemarkfrom = None
5529 movemarkfrom = None
5525 if not checkout:
5530 if not checkout:
5526 updata = destutil.destupdate(repo)
5531 updata = destutil.destupdate(repo)
5527 checkout, movemarkfrom, brev = updata
5532 checkout, movemarkfrom, brev = updata
5528 ret = hg.update(repo, checkout)
5533 ret = hg.update(repo, checkout)
5529 except error.UpdateAbort as inst:
5534 except error.UpdateAbort as inst:
5530 msg = _("not updating: %s") % str(inst)
5535 msg = _("not updating: %s") % str(inst)
5531 hint = inst.hint
5536 hint = inst.hint
5532 raise error.UpdateAbort(msg, hint=hint)
5537 raise error.UpdateAbort(msg, hint=hint)
5533 if not ret and not checkout:
5538 if not ret and not checkout:
5534 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5539 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5535 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
5540 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
5536 return ret
5541 return ret
5537 if modheads > 1:
5542 if modheads > 1:
5538 currentbranchheads = len(repo.branchheads())
5543 currentbranchheads = len(repo.branchheads())
5539 if currentbranchheads == modheads:
5544 if currentbranchheads == modheads:
5540 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
5545 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
5541 elif currentbranchheads > 1:
5546 elif currentbranchheads > 1:
5542 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
5547 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
5543 "merge)\n"))
5548 "merge)\n"))
5544 else:
5549 else:
5545 ui.status(_("(run 'hg heads' to see heads)\n"))
5550 ui.status(_("(run 'hg heads' to see heads)\n"))
5546 else:
5551 else:
5547 ui.status(_("(run 'hg update' to get a working copy)\n"))
5552 ui.status(_("(run 'hg update' to get a working copy)\n"))
5548
5553
5549 @command('^pull',
5554 @command('^pull',
5550 [('u', 'update', None,
5555 [('u', 'update', None,
5551 _('update to new branch head if changesets were pulled')),
5556 _('update to new branch head if changesets were pulled')),
5552 ('f', 'force', None, _('run even when remote repository is unrelated')),
5557 ('f', 'force', None, _('run even when remote repository is unrelated')),
5553 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
5558 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
5554 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
5559 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
5555 ('b', 'branch', [], _('a specific branch you would like to pull'),
5560 ('b', 'branch', [], _('a specific branch you would like to pull'),
5556 _('BRANCH')),
5561 _('BRANCH')),
5557 ] + remoteopts,
5562 ] + remoteopts,
5558 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
5563 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
5559 def pull(ui, repo, source="default", **opts):
5564 def pull(ui, repo, source="default", **opts):
5560 """pull changes from the specified source
5565 """pull changes from the specified source
5561
5566
5562 Pull changes from a remote repository to a local one.
5567 Pull changes from a remote repository to a local one.
5563
5568
5564 This finds all changes from the repository at the specified path
5569 This finds all changes from the repository at the specified path
5565 or URL and adds them to a local repository (the current one unless
5570 or URL and adds them to a local repository (the current one unless
5566 -R is specified). By default, this does not update the copy of the
5571 -R is specified). By default, this does not update the copy of the
5567 project in the working directory.
5572 project in the working directory.
5568
5573
5569 Use :hg:`incoming` if you want to see what would have been added
5574 Use :hg:`incoming` if you want to see what would have been added
5570 by a pull at the time you issued this command. If you then decide
5575 by a pull at the time you issued this command. If you then decide
5571 to add those changes to the repository, you should use :hg:`pull
5576 to add those changes to the repository, you should use :hg:`pull
5572 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5577 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5573
5578
5574 If SOURCE is omitted, the 'default' path will be used.
5579 If SOURCE is omitted, the 'default' path will be used.
5575 See :hg:`help urls` for more information.
5580 See :hg:`help urls` for more information.
5576
5581
5577 Returns 0 on success, 1 if an update had unresolved files.
5582 Returns 0 on success, 1 if an update had unresolved files.
5578 """
5583 """
5579 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
5584 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
5580 ui.status(_('pulling from %s\n') % util.hidepassword(source))
5585 ui.status(_('pulling from %s\n') % util.hidepassword(source))
5581 other = hg.peer(repo, opts, source)
5586 other = hg.peer(repo, opts, source)
5582 try:
5587 try:
5583 revs, checkout = hg.addbranchrevs(repo, other, branches,
5588 revs, checkout = hg.addbranchrevs(repo, other, branches,
5584 opts.get('rev'))
5589 opts.get('rev'))
5585
5590
5586
5591
5587 pullopargs = {}
5592 pullopargs = {}
5588 if opts.get('bookmark'):
5593 if opts.get('bookmark'):
5589 if not revs:
5594 if not revs:
5590 revs = []
5595 revs = []
5591 # The list of bookmark used here is not the one used to actually
5596 # The list of bookmark used here is not the one used to actually
5592 # update the bookmark name. This can result in the revision pulled
5597 # update the bookmark name. This can result in the revision pulled
5593 # not ending up with the name of the bookmark because of a race
5598 # not ending up with the name of the bookmark because of a race
5594 # condition on the server. (See issue 4689 for details)
5599 # condition on the server. (See issue 4689 for details)
5595 remotebookmarks = other.listkeys('bookmarks')
5600 remotebookmarks = other.listkeys('bookmarks')
5596 pullopargs['remotebookmarks'] = remotebookmarks
5601 pullopargs['remotebookmarks'] = remotebookmarks
5597 for b in opts['bookmark']:
5602 for b in opts['bookmark']:
5598 if b not in remotebookmarks:
5603 if b not in remotebookmarks:
5599 raise error.Abort(_('remote bookmark %s not found!') % b)
5604 raise error.Abort(_('remote bookmark %s not found!') % b)
5600 revs.append(remotebookmarks[b])
5605 revs.append(remotebookmarks[b])
5601
5606
5602 if revs:
5607 if revs:
5603 try:
5608 try:
5604 # When 'rev' is a bookmark name, we cannot guarantee that it
5609 # When 'rev' is a bookmark name, we cannot guarantee that it
5605 # will be updated with that name because of a race condition
5610 # will be updated with that name because of a race condition
5606 # server side. (See issue 4689 for details)
5611 # server side. (See issue 4689 for details)
5607 oldrevs = revs
5612 oldrevs = revs
5608 revs = [] # actually, nodes
5613 revs = [] # actually, nodes
5609 for r in oldrevs:
5614 for r in oldrevs:
5610 node = other.lookup(r)
5615 node = other.lookup(r)
5611 revs.append(node)
5616 revs.append(node)
5612 if r == checkout:
5617 if r == checkout:
5613 checkout = node
5618 checkout = node
5614 except error.CapabilityError:
5619 except error.CapabilityError:
5615 err = _("other repository doesn't support revision lookup, "
5620 err = _("other repository doesn't support revision lookup, "
5616 "so a rev cannot be specified.")
5621 "so a rev cannot be specified.")
5617 raise error.Abort(err)
5622 raise error.Abort(err)
5618
5623
5619 pullopargs.update(opts.get('opargs', {}))
5624 pullopargs.update(opts.get('opargs', {}))
5620 modheads = exchange.pull(repo, other, heads=revs,
5625 modheads = exchange.pull(repo, other, heads=revs,
5621 force=opts.get('force'),
5626 force=opts.get('force'),
5622 bookmarks=opts.get('bookmark', ()),
5627 bookmarks=opts.get('bookmark', ()),
5623 opargs=pullopargs).cgresult
5628 opargs=pullopargs).cgresult
5624 if checkout:
5629 if checkout:
5625 checkout = str(repo.changelog.rev(checkout))
5630 checkout = str(repo.changelog.rev(checkout))
5626 repo._subtoppath = source
5631 repo._subtoppath = source
5627 try:
5632 try:
5628 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
5633 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
5629
5634
5630 finally:
5635 finally:
5631 del repo._subtoppath
5636 del repo._subtoppath
5632
5637
5633 finally:
5638 finally:
5634 other.close()
5639 other.close()
5635 return ret
5640 return ret
5636
5641
5637 @command('^push',
5642 @command('^push',
5638 [('f', 'force', None, _('force push')),
5643 [('f', 'force', None, _('force push')),
5639 ('r', 'rev', [],
5644 ('r', 'rev', [],
5640 _('a changeset intended to be included in the destination'),
5645 _('a changeset intended to be included in the destination'),
5641 _('REV')),
5646 _('REV')),
5642 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
5647 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
5643 ('b', 'branch', [],
5648 ('b', 'branch', [],
5644 _('a specific branch you would like to push'), _('BRANCH')),
5649 _('a specific branch you would like to push'), _('BRANCH')),
5645 ('', 'new-branch', False, _('allow pushing a new branch')),
5650 ('', 'new-branch', False, _('allow pushing a new branch')),
5646 ] + remoteopts,
5651 ] + remoteopts,
5647 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
5652 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
5648 def push(ui, repo, dest=None, **opts):
5653 def push(ui, repo, dest=None, **opts):
5649 """push changes to the specified destination
5654 """push changes to the specified destination
5650
5655
5651 Push changesets from the local repository to the specified
5656 Push changesets from the local repository to the specified
5652 destination.
5657 destination.
5653
5658
5654 This operation is symmetrical to pull: it is identical to a pull
5659 This operation is symmetrical to pull: it is identical to a pull
5655 in the destination repository from the current one.
5660 in the destination repository from the current one.
5656
5661
5657 By default, push will not allow creation of new heads at the
5662 By default, push will not allow creation of new heads at the
5658 destination, since multiple heads would make it unclear which head
5663 destination, since multiple heads would make it unclear which head
5659 to use. In this situation, it is recommended to pull and merge
5664 to use. In this situation, it is recommended to pull and merge
5660 before pushing.
5665 before pushing.
5661
5666
5662 Use --new-branch if you want to allow push to create a new named
5667 Use --new-branch if you want to allow push to create a new named
5663 branch that is not present at the destination. This allows you to
5668 branch that is not present at the destination. This allows you to
5664 only create a new branch without forcing other changes.
5669 only create a new branch without forcing other changes.
5665
5670
5666 .. note::
5671 .. note::
5667
5672
5668 Extra care should be taken with the -f/--force option,
5673 Extra care should be taken with the -f/--force option,
5669 which will push all new heads on all branches, an action which will
5674 which will push all new heads on all branches, an action which will
5670 almost always cause confusion for collaborators.
5675 almost always cause confusion for collaborators.
5671
5676
5672 If -r/--rev is used, the specified revision and all its ancestors
5677 If -r/--rev is used, the specified revision and all its ancestors
5673 will be pushed to the remote repository.
5678 will be pushed to the remote repository.
5674
5679
5675 If -B/--bookmark is used, the specified bookmarked revision, its
5680 If -B/--bookmark is used, the specified bookmarked revision, its
5676 ancestors, and the bookmark will be pushed to the remote
5681 ancestors, and the bookmark will be pushed to the remote
5677 repository.
5682 repository.
5678
5683
5679 Please see :hg:`help urls` for important details about ``ssh://``
5684 Please see :hg:`help urls` for important details about ``ssh://``
5680 URLs. If DESTINATION is omitted, a default path will be used.
5685 URLs. If DESTINATION is omitted, a default path will be used.
5681
5686
5682 Returns 0 if push was successful, 1 if nothing to push.
5687 Returns 0 if push was successful, 1 if nothing to push.
5683 """
5688 """
5684
5689
5685 if opts.get('bookmark'):
5690 if opts.get('bookmark'):
5686 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
5691 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
5687 for b in opts['bookmark']:
5692 for b in opts['bookmark']:
5688 # translate -B options to -r so changesets get pushed
5693 # translate -B options to -r so changesets get pushed
5689 if b in repo._bookmarks:
5694 if b in repo._bookmarks:
5690 opts.setdefault('rev', []).append(b)
5695 opts.setdefault('rev', []).append(b)
5691 else:
5696 else:
5692 # if we try to push a deleted bookmark, translate it to null
5697 # if we try to push a deleted bookmark, translate it to null
5693 # this lets simultaneous -r, -b options continue working
5698 # this lets simultaneous -r, -b options continue working
5694 opts.setdefault('rev', []).append("null")
5699 opts.setdefault('rev', []).append("null")
5695
5700
5696 path = ui.paths.getpath(dest, default=('default-push', 'default'))
5701 path = ui.paths.getpath(dest, default=('default-push', 'default'))
5697 if not path:
5702 if not path:
5698 raise error.Abort(_('default repository not configured!'),
5703 raise error.Abort(_('default repository not configured!'),
5699 hint=_('see the "path" section in "hg help config"'))
5704 hint=_('see the "path" section in "hg help config"'))
5700 dest = path.pushloc or path.loc
5705 dest = path.pushloc or path.loc
5701 branches = (path.branch, opts.get('branch') or [])
5706 branches = (path.branch, opts.get('branch') or [])
5702 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
5707 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
5703 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
5708 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
5704 other = hg.peer(repo, opts, dest)
5709 other = hg.peer(repo, opts, dest)
5705
5710
5706 if revs:
5711 if revs:
5707 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
5712 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
5708 if not revs:
5713 if not revs:
5709 raise error.Abort(_("specified revisions evaluate to an empty set"),
5714 raise error.Abort(_("specified revisions evaluate to an empty set"),
5710 hint=_("use different revision arguments"))
5715 hint=_("use different revision arguments"))
5711
5716
5712 repo._subtoppath = dest
5717 repo._subtoppath = dest
5713 try:
5718 try:
5714 # push subrepos depth-first for coherent ordering
5719 # push subrepos depth-first for coherent ordering
5715 c = repo['']
5720 c = repo['']
5716 subs = c.substate # only repos that are committed
5721 subs = c.substate # only repos that are committed
5717 for s in sorted(subs):
5722 for s in sorted(subs):
5718 result = c.sub(s).push(opts)
5723 result = c.sub(s).push(opts)
5719 if result == 0:
5724 if result == 0:
5720 return not result
5725 return not result
5721 finally:
5726 finally:
5722 del repo._subtoppath
5727 del repo._subtoppath
5723 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
5728 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
5724 newbranch=opts.get('new_branch'),
5729 newbranch=opts.get('new_branch'),
5725 bookmarks=opts.get('bookmark', ()),
5730 bookmarks=opts.get('bookmark', ()),
5726 opargs=opts.get('opargs'))
5731 opargs=opts.get('opargs'))
5727
5732
5728 result = not pushop.cgresult
5733 result = not pushop.cgresult
5729
5734
5730 if pushop.bkresult is not None:
5735 if pushop.bkresult is not None:
5731 if pushop.bkresult == 2:
5736 if pushop.bkresult == 2:
5732 result = 2
5737 result = 2
5733 elif not result and pushop.bkresult:
5738 elif not result and pushop.bkresult:
5734 result = 2
5739 result = 2
5735
5740
5736 return result
5741 return result
5737
5742
5738 @command('recover', [])
5743 @command('recover', [])
5739 def recover(ui, repo):
5744 def recover(ui, repo):
5740 """roll back an interrupted transaction
5745 """roll back an interrupted transaction
5741
5746
5742 Recover from an interrupted commit or pull.
5747 Recover from an interrupted commit or pull.
5743
5748
5744 This command tries to fix the repository status after an
5749 This command tries to fix the repository status after an
5745 interrupted operation. It should only be necessary when Mercurial
5750 interrupted operation. It should only be necessary when Mercurial
5746 suggests it.
5751 suggests it.
5747
5752
5748 Returns 0 if successful, 1 if nothing to recover or verify fails.
5753 Returns 0 if successful, 1 if nothing to recover or verify fails.
5749 """
5754 """
5750 if repo.recover():
5755 if repo.recover():
5751 return hg.verify(repo)
5756 return hg.verify(repo)
5752 return 1
5757 return 1
5753
5758
5754 @command('^remove|rm',
5759 @command('^remove|rm',
5755 [('A', 'after', None, _('record delete for missing files')),
5760 [('A', 'after', None, _('record delete for missing files')),
5756 ('f', 'force', None,
5761 ('f', 'force', None,
5757 _('remove (and delete) file even if added or modified')),
5762 _('remove (and delete) file even if added or modified')),
5758 ] + subrepoopts + walkopts,
5763 ] + subrepoopts + walkopts,
5759 _('[OPTION]... FILE...'),
5764 _('[OPTION]... FILE...'),
5760 inferrepo=True)
5765 inferrepo=True)
5761 def remove(ui, repo, *pats, **opts):
5766 def remove(ui, repo, *pats, **opts):
5762 """remove the specified files on the next commit
5767 """remove the specified files on the next commit
5763
5768
5764 Schedule the indicated files for removal from the current branch.
5769 Schedule the indicated files for removal from the current branch.
5765
5770
5766 This command schedules the files to be removed at the next commit.
5771 This command schedules the files to be removed at the next commit.
5767 To undo a remove before that, see :hg:`revert`. To undo added
5772 To undo a remove before that, see :hg:`revert`. To undo added
5768 files, see :hg:`forget`.
5773 files, see :hg:`forget`.
5769
5774
5770 .. container:: verbose
5775 .. container:: verbose
5771
5776
5772 -A/--after can be used to remove only files that have already
5777 -A/--after can be used to remove only files that have already
5773 been deleted, -f/--force can be used to force deletion, and -Af
5778 been deleted, -f/--force can be used to force deletion, and -Af
5774 can be used to remove files from the next revision without
5779 can be used to remove files from the next revision without
5775 deleting them from the working directory.
5780 deleting them from the working directory.
5776
5781
5777 The following table details the behavior of remove for different
5782 The following table details the behavior of remove for different
5778 file states (columns) and option combinations (rows). The file
5783 file states (columns) and option combinations (rows). The file
5779 states are Added [A], Clean [C], Modified [M] and Missing [!]
5784 states are Added [A], Clean [C], Modified [M] and Missing [!]
5780 (as reported by :hg:`status`). The actions are Warn, Remove
5785 (as reported by :hg:`status`). The actions are Warn, Remove
5781 (from branch) and Delete (from disk):
5786 (from branch) and Delete (from disk):
5782
5787
5783 ========= == == == ==
5788 ========= == == == ==
5784 opt/state A C M !
5789 opt/state A C M !
5785 ========= == == == ==
5790 ========= == == == ==
5786 none W RD W R
5791 none W RD W R
5787 -f R RD RD R
5792 -f R RD RD R
5788 -A W W W R
5793 -A W W W R
5789 -Af R R R R
5794 -Af R R R R
5790 ========= == == == ==
5795 ========= == == == ==
5791
5796
5792 .. note::
5797 .. note::
5793
5798
5794 :hg:`remove` never deletes files in Added [A] state from the
5799 :hg:`remove` never deletes files in Added [A] state from the
5795 working directory, not even if ``--force`` is specified.
5800 working directory, not even if ``--force`` is specified.
5796
5801
5797 Returns 0 on success, 1 if any warnings encountered.
5802 Returns 0 on success, 1 if any warnings encountered.
5798 """
5803 """
5799
5804
5800 after, force = opts.get('after'), opts.get('force')
5805 after, force = opts.get('after'), opts.get('force')
5801 if not pats and not after:
5806 if not pats and not after:
5802 raise error.Abort(_('no files specified'))
5807 raise error.Abort(_('no files specified'))
5803
5808
5804 m = scmutil.match(repo[None], pats, opts)
5809 m = scmutil.match(repo[None], pats, opts)
5805 subrepos = opts.get('subrepos')
5810 subrepos = opts.get('subrepos')
5806 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
5811 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
5807
5812
5808 @command('rename|move|mv',
5813 @command('rename|move|mv',
5809 [('A', 'after', None, _('record a rename that has already occurred')),
5814 [('A', 'after', None, _('record a rename that has already occurred')),
5810 ('f', 'force', None, _('forcibly copy over an existing managed file')),
5815 ('f', 'force', None, _('forcibly copy over an existing managed file')),
5811 ] + walkopts + dryrunopts,
5816 ] + walkopts + dryrunopts,
5812 _('[OPTION]... SOURCE... DEST'))
5817 _('[OPTION]... SOURCE... DEST'))
5813 def rename(ui, repo, *pats, **opts):
5818 def rename(ui, repo, *pats, **opts):
5814 """rename files; equivalent of copy + remove
5819 """rename files; equivalent of copy + remove
5815
5820
5816 Mark dest as copies of sources; mark sources for deletion. If dest
5821 Mark dest as copies of sources; mark sources for deletion. If dest
5817 is a directory, copies are put in that directory. If dest is a
5822 is a directory, copies are put in that directory. If dest is a
5818 file, there can only be one source.
5823 file, there can only be one source.
5819
5824
5820 By default, this command copies the contents of files as they
5825 By default, this command copies the contents of files as they
5821 exist in the working directory. If invoked with -A/--after, the
5826 exist in the working directory. If invoked with -A/--after, the
5822 operation is recorded, but no copying is performed.
5827 operation is recorded, but no copying is performed.
5823
5828
5824 This command takes effect at the next commit. To undo a rename
5829 This command takes effect at the next commit. To undo a rename
5825 before that, see :hg:`revert`.
5830 before that, see :hg:`revert`.
5826
5831
5827 Returns 0 on success, 1 if errors are encountered.
5832 Returns 0 on success, 1 if errors are encountered.
5828 """
5833 """
5829 with repo.wlock(False):
5834 with repo.wlock(False):
5830 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5835 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5831
5836
5832 @command('resolve',
5837 @command('resolve',
5833 [('a', 'all', None, _('select all unresolved files')),
5838 [('a', 'all', None, _('select all unresolved files')),
5834 ('l', 'list', None, _('list state of files needing merge')),
5839 ('l', 'list', None, _('list state of files needing merge')),
5835 ('m', 'mark', None, _('mark files as resolved')),
5840 ('m', 'mark', None, _('mark files as resolved')),
5836 ('u', 'unmark', None, _('mark files as unresolved')),
5841 ('u', 'unmark', None, _('mark files as unresolved')),
5837 ('n', 'no-status', None, _('hide status prefix'))]
5842 ('n', 'no-status', None, _('hide status prefix'))]
5838 + mergetoolopts + walkopts + formatteropts,
5843 + mergetoolopts + walkopts + formatteropts,
5839 _('[OPTION]... [FILE]...'),
5844 _('[OPTION]... [FILE]...'),
5840 inferrepo=True)
5845 inferrepo=True)
5841 def resolve(ui, repo, *pats, **opts):
5846 def resolve(ui, repo, *pats, **opts):
5842 """redo merges or set/view the merge status of files
5847 """redo merges or set/view the merge status of files
5843
5848
5844 Merges with unresolved conflicts are often the result of
5849 Merges with unresolved conflicts are often the result of
5845 non-interactive merging using the ``internal:merge`` configuration
5850 non-interactive merging using the ``internal:merge`` configuration
5846 setting, or a command-line merge tool like ``diff3``. The resolve
5851 setting, or a command-line merge tool like ``diff3``. The resolve
5847 command is used to manage the files involved in a merge, after
5852 command is used to manage the files involved in a merge, after
5848 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5853 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5849 working directory must have two parents). See :hg:`help
5854 working directory must have two parents). See :hg:`help
5850 merge-tools` for information on configuring merge tools.
5855 merge-tools` for information on configuring merge tools.
5851
5856
5852 The resolve command can be used in the following ways:
5857 The resolve command can be used in the following ways:
5853
5858
5854 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
5859 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
5855 files, discarding any previous merge attempts. Re-merging is not
5860 files, discarding any previous merge attempts. Re-merging is not
5856 performed for files already marked as resolved. Use ``--all/-a``
5861 performed for files already marked as resolved. Use ``--all/-a``
5857 to select all unresolved files. ``--tool`` can be used to specify
5862 to select all unresolved files. ``--tool`` can be used to specify
5858 the merge tool used for the given files. It overrides the HGMERGE
5863 the merge tool used for the given files. It overrides the HGMERGE
5859 environment variable and your configuration files. Previous file
5864 environment variable and your configuration files. Previous file
5860 contents are saved with a ``.orig`` suffix.
5865 contents are saved with a ``.orig`` suffix.
5861
5866
5862 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5867 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5863 (e.g. after having manually fixed-up the files). The default is
5868 (e.g. after having manually fixed-up the files). The default is
5864 to mark all unresolved files.
5869 to mark all unresolved files.
5865
5870
5866 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5871 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5867 default is to mark all resolved files.
5872 default is to mark all resolved files.
5868
5873
5869 - :hg:`resolve -l`: list files which had or still have conflicts.
5874 - :hg:`resolve -l`: list files which had or still have conflicts.
5870 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5875 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5871
5876
5872 .. note::
5877 .. note::
5873
5878
5874 Mercurial will not let you commit files with unresolved merge
5879 Mercurial will not let you commit files with unresolved merge
5875 conflicts. You must use :hg:`resolve -m ...` before you can
5880 conflicts. You must use :hg:`resolve -m ...` before you can
5876 commit after a conflicting merge.
5881 commit after a conflicting merge.
5877
5882
5878 Returns 0 on success, 1 if any files fail a resolve attempt.
5883 Returns 0 on success, 1 if any files fail a resolve attempt.
5879 """
5884 """
5880
5885
5881 all, mark, unmark, show, nostatus = \
5886 all, mark, unmark, show, nostatus = \
5882 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
5887 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
5883
5888
5884 if (show and (mark or unmark)) or (mark and unmark):
5889 if (show and (mark or unmark)) or (mark and unmark):
5885 raise error.Abort(_("too many options specified"))
5890 raise error.Abort(_("too many options specified"))
5886 if pats and all:
5891 if pats and all:
5887 raise error.Abort(_("can't specify --all and patterns"))
5892 raise error.Abort(_("can't specify --all and patterns"))
5888 if not (all or pats or show or mark or unmark):
5893 if not (all or pats or show or mark or unmark):
5889 raise error.Abort(_('no files or directories specified'),
5894 raise error.Abort(_('no files or directories specified'),
5890 hint=('use --all to re-merge all unresolved files'))
5895 hint=('use --all to re-merge all unresolved files'))
5891
5896
5892 if show:
5897 if show:
5893 fm = ui.formatter('resolve', opts)
5898 fm = ui.formatter('resolve', opts)
5894 ms = mergemod.mergestate.read(repo)
5899 ms = mergemod.mergestate.read(repo)
5895 m = scmutil.match(repo[None], pats, opts)
5900 m = scmutil.match(repo[None], pats, opts)
5896 for f in ms:
5901 for f in ms:
5897 if not m(f):
5902 if not m(f):
5898 continue
5903 continue
5899 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved',
5904 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved',
5900 'd': 'driverresolved'}[ms[f]]
5905 'd': 'driverresolved'}[ms[f]]
5901 fm.startitem()
5906 fm.startitem()
5902 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
5907 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
5903 fm.write('path', '%s\n', f, label=l)
5908 fm.write('path', '%s\n', f, label=l)
5904 fm.end()
5909 fm.end()
5905 return 0
5910 return 0
5906
5911
5907 with repo.wlock():
5912 with repo.wlock():
5908 ms = mergemod.mergestate.read(repo)
5913 ms = mergemod.mergestate.read(repo)
5909
5914
5910 if not (ms.active() or repo.dirstate.p2() != nullid):
5915 if not (ms.active() or repo.dirstate.p2() != nullid):
5911 raise error.Abort(
5916 raise error.Abort(
5912 _('resolve command not applicable when not merging'))
5917 _('resolve command not applicable when not merging'))
5913
5918
5914 wctx = repo[None]
5919 wctx = repo[None]
5915
5920
5916 if ms.mergedriver and ms.mdstate() == 'u':
5921 if ms.mergedriver and ms.mdstate() == 'u':
5917 proceed = mergemod.driverpreprocess(repo, ms, wctx)
5922 proceed = mergemod.driverpreprocess(repo, ms, wctx)
5918 ms.commit()
5923 ms.commit()
5919 # allow mark and unmark to go through
5924 # allow mark and unmark to go through
5920 if not mark and not unmark and not proceed:
5925 if not mark and not unmark and not proceed:
5921 return 1
5926 return 1
5922
5927
5923 m = scmutil.match(wctx, pats, opts)
5928 m = scmutil.match(wctx, pats, opts)
5924 ret = 0
5929 ret = 0
5925 didwork = False
5930 didwork = False
5926 runconclude = False
5931 runconclude = False
5927
5932
5928 tocomplete = []
5933 tocomplete = []
5929 for f in ms:
5934 for f in ms:
5930 if not m(f):
5935 if not m(f):
5931 continue
5936 continue
5932
5937
5933 didwork = True
5938 didwork = True
5934
5939
5935 # don't let driver-resolved files be marked, and run the conclude
5940 # don't let driver-resolved files be marked, and run the conclude
5936 # step if asked to resolve
5941 # step if asked to resolve
5937 if ms[f] == "d":
5942 if ms[f] == "d":
5938 exact = m.exact(f)
5943 exact = m.exact(f)
5939 if mark:
5944 if mark:
5940 if exact:
5945 if exact:
5941 ui.warn(_('not marking %s as it is driver-resolved\n')
5946 ui.warn(_('not marking %s as it is driver-resolved\n')
5942 % f)
5947 % f)
5943 elif unmark:
5948 elif unmark:
5944 if exact:
5949 if exact:
5945 ui.warn(_('not unmarking %s as it is driver-resolved\n')
5950 ui.warn(_('not unmarking %s as it is driver-resolved\n')
5946 % f)
5951 % f)
5947 else:
5952 else:
5948 runconclude = True
5953 runconclude = True
5949 continue
5954 continue
5950
5955
5951 if mark:
5956 if mark:
5952 ms.mark(f, "r")
5957 ms.mark(f, "r")
5953 elif unmark:
5958 elif unmark:
5954 ms.mark(f, "u")
5959 ms.mark(f, "u")
5955 else:
5960 else:
5956 # backup pre-resolve (merge uses .orig for its own purposes)
5961 # backup pre-resolve (merge uses .orig for its own purposes)
5957 a = repo.wjoin(f)
5962 a = repo.wjoin(f)
5958 try:
5963 try:
5959 util.copyfile(a, a + ".resolve")
5964 util.copyfile(a, a + ".resolve")
5960 except (IOError, OSError) as inst:
5965 except (IOError, OSError) as inst:
5961 if inst.errno != errno.ENOENT:
5966 if inst.errno != errno.ENOENT:
5962 raise
5967 raise
5963
5968
5964 try:
5969 try:
5965 # preresolve file
5970 # preresolve file
5966 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5971 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5967 'resolve')
5972 'resolve')
5968 complete, r = ms.preresolve(f, wctx)
5973 complete, r = ms.preresolve(f, wctx)
5969 if not complete:
5974 if not complete:
5970 tocomplete.append(f)
5975 tocomplete.append(f)
5971 elif r:
5976 elif r:
5972 ret = 1
5977 ret = 1
5973 finally:
5978 finally:
5974 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5979 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5975 ms.commit()
5980 ms.commit()
5976
5981
5977 # replace filemerge's .orig file with our resolve file, but only
5982 # replace filemerge's .orig file with our resolve file, but only
5978 # for merges that are complete
5983 # for merges that are complete
5979 if complete:
5984 if complete:
5980 try:
5985 try:
5981 util.rename(a + ".resolve",
5986 util.rename(a + ".resolve",
5982 scmutil.origpath(ui, repo, a))
5987 scmutil.origpath(ui, repo, a))
5983 except OSError as inst:
5988 except OSError as inst:
5984 if inst.errno != errno.ENOENT:
5989 if inst.errno != errno.ENOENT:
5985 raise
5990 raise
5986
5991
5987 for f in tocomplete:
5992 for f in tocomplete:
5988 try:
5993 try:
5989 # resolve file
5994 # resolve file
5990 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5995 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5991 'resolve')
5996 'resolve')
5992 r = ms.resolve(f, wctx)
5997 r = ms.resolve(f, wctx)
5993 if r:
5998 if r:
5994 ret = 1
5999 ret = 1
5995 finally:
6000 finally:
5996 ui.setconfig('ui', 'forcemerge', '', 'resolve')
6001 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5997 ms.commit()
6002 ms.commit()
5998
6003
5999 # replace filemerge's .orig file with our resolve file
6004 # replace filemerge's .orig file with our resolve file
6000 a = repo.wjoin(f)
6005 a = repo.wjoin(f)
6001 try:
6006 try:
6002 util.rename(a + ".resolve", scmutil.origpath(ui, repo, a))
6007 util.rename(a + ".resolve", scmutil.origpath(ui, repo, a))
6003 except OSError as inst:
6008 except OSError as inst:
6004 if inst.errno != errno.ENOENT:
6009 if inst.errno != errno.ENOENT:
6005 raise
6010 raise
6006
6011
6007 ms.commit()
6012 ms.commit()
6008 ms.recordactions()
6013 ms.recordactions()
6009
6014
6010 if not didwork and pats:
6015 if not didwork and pats:
6011 ui.warn(_("arguments do not match paths that need resolving\n"))
6016 ui.warn(_("arguments do not match paths that need resolving\n"))
6012 elif ms.mergedriver and ms.mdstate() != 's':
6017 elif ms.mergedriver and ms.mdstate() != 's':
6013 # run conclude step when either a driver-resolved file is requested
6018 # run conclude step when either a driver-resolved file is requested
6014 # or there are no driver-resolved files
6019 # or there are no driver-resolved files
6015 # we can't use 'ret' to determine whether any files are unresolved
6020 # we can't use 'ret' to determine whether any files are unresolved
6016 # because we might not have tried to resolve some
6021 # because we might not have tried to resolve some
6017 if ((runconclude or not list(ms.driverresolved()))
6022 if ((runconclude or not list(ms.driverresolved()))
6018 and not list(ms.unresolved())):
6023 and not list(ms.unresolved())):
6019 proceed = mergemod.driverconclude(repo, ms, wctx)
6024 proceed = mergemod.driverconclude(repo, ms, wctx)
6020 ms.commit()
6025 ms.commit()
6021 if not proceed:
6026 if not proceed:
6022 return 1
6027 return 1
6023
6028
6024 # Nudge users into finishing an unfinished operation
6029 # Nudge users into finishing an unfinished operation
6025 unresolvedf = list(ms.unresolved())
6030 unresolvedf = list(ms.unresolved())
6026 driverresolvedf = list(ms.driverresolved())
6031 driverresolvedf = list(ms.driverresolved())
6027 if not unresolvedf and not driverresolvedf:
6032 if not unresolvedf and not driverresolvedf:
6028 ui.status(_('(no more unresolved files)\n'))
6033 ui.status(_('(no more unresolved files)\n'))
6029 cmdutil.checkafterresolved(repo)
6034 cmdutil.checkafterresolved(repo)
6030 elif not unresolvedf:
6035 elif not unresolvedf:
6031 ui.status(_('(no more unresolved files -- '
6036 ui.status(_('(no more unresolved files -- '
6032 'run "hg resolve --all" to conclude)\n'))
6037 'run "hg resolve --all" to conclude)\n'))
6033
6038
6034 return ret
6039 return ret
6035
6040
6036 @command('revert',
6041 @command('revert',
6037 [('a', 'all', None, _('revert all changes when no arguments given')),
6042 [('a', 'all', None, _('revert all changes when no arguments given')),
6038 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6043 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6039 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
6044 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
6040 ('C', 'no-backup', None, _('do not save backup copies of files')),
6045 ('C', 'no-backup', None, _('do not save backup copies of files')),
6041 ('i', 'interactive', None,
6046 ('i', 'interactive', None,
6042 _('interactively select the changes (EXPERIMENTAL)')),
6047 _('interactively select the changes (EXPERIMENTAL)')),
6043 ] + walkopts + dryrunopts,
6048 ] + walkopts + dryrunopts,
6044 _('[OPTION]... [-r REV] [NAME]...'))
6049 _('[OPTION]... [-r REV] [NAME]...'))
6045 def revert(ui, repo, *pats, **opts):
6050 def revert(ui, repo, *pats, **opts):
6046 """restore files to their checkout state
6051 """restore files to their checkout state
6047
6052
6048 .. note::
6053 .. note::
6049
6054
6050 To check out earlier revisions, you should use :hg:`update REV`.
6055 To check out earlier revisions, you should use :hg:`update REV`.
6051 To cancel an uncommitted merge (and lose your changes),
6056 To cancel an uncommitted merge (and lose your changes),
6052 use :hg:`update --clean .`.
6057 use :hg:`update --clean .`.
6053
6058
6054 With no revision specified, revert the specified files or directories
6059 With no revision specified, revert the specified files or directories
6055 to the contents they had in the parent of the working directory.
6060 to the contents they had in the parent of the working directory.
6056 This restores the contents of files to an unmodified
6061 This restores the contents of files to an unmodified
6057 state and unschedules adds, removes, copies, and renames. If the
6062 state and unschedules adds, removes, copies, and renames. If the
6058 working directory has two parents, you must explicitly specify a
6063 working directory has two parents, you must explicitly specify a
6059 revision.
6064 revision.
6060
6065
6061 Using the -r/--rev or -d/--date options, revert the given files or
6066 Using the -r/--rev or -d/--date options, revert the given files or
6062 directories to their states as of a specific revision. Because
6067 directories to their states as of a specific revision. Because
6063 revert does not change the working directory parents, this will
6068 revert does not change the working directory parents, this will
6064 cause these files to appear modified. This can be helpful to "back
6069 cause these files to appear modified. This can be helpful to "back
6065 out" some or all of an earlier change. See :hg:`backout` for a
6070 out" some or all of an earlier change. See :hg:`backout` for a
6066 related method.
6071 related method.
6067
6072
6068 Modified files are saved with a .orig suffix before reverting.
6073 Modified files are saved with a .orig suffix before reverting.
6069 To disable these backups, use --no-backup.
6074 To disable these backups, use --no-backup.
6070
6075
6071 See :hg:`help dates` for a list of formats valid for -d/--date.
6076 See :hg:`help dates` for a list of formats valid for -d/--date.
6072
6077
6073 See :hg:`help backout` for a way to reverse the effect of an
6078 See :hg:`help backout` for a way to reverse the effect of an
6074 earlier changeset.
6079 earlier changeset.
6075
6080
6076 Returns 0 on success.
6081 Returns 0 on success.
6077 """
6082 """
6078
6083
6079 if opts.get("date"):
6084 if opts.get("date"):
6080 if opts.get("rev"):
6085 if opts.get("rev"):
6081 raise error.Abort(_("you can't specify a revision and a date"))
6086 raise error.Abort(_("you can't specify a revision and a date"))
6082 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
6087 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
6083
6088
6084 parent, p2 = repo.dirstate.parents()
6089 parent, p2 = repo.dirstate.parents()
6085 if not opts.get('rev') and p2 != nullid:
6090 if not opts.get('rev') and p2 != nullid:
6086 # revert after merge is a trap for new users (issue2915)
6091 # revert after merge is a trap for new users (issue2915)
6087 raise error.Abort(_('uncommitted merge with no revision specified'),
6092 raise error.Abort(_('uncommitted merge with no revision specified'),
6088 hint=_('use "hg update" or see "hg help revert"'))
6093 hint=_('use "hg update" or see "hg help revert"'))
6089
6094
6090 ctx = scmutil.revsingle(repo, opts.get('rev'))
6095 ctx = scmutil.revsingle(repo, opts.get('rev'))
6091
6096
6092 if (not (pats or opts.get('include') or opts.get('exclude') or
6097 if (not (pats or opts.get('include') or opts.get('exclude') or
6093 opts.get('all') or opts.get('interactive'))):
6098 opts.get('all') or opts.get('interactive'))):
6094 msg = _("no files or directories specified")
6099 msg = _("no files or directories specified")
6095 if p2 != nullid:
6100 if p2 != nullid:
6096 hint = _("uncommitted merge, use --all to discard all changes,"
6101 hint = _("uncommitted merge, use --all to discard all changes,"
6097 " or 'hg update -C .' to abort the merge")
6102 " or 'hg update -C .' to abort the merge")
6098 raise error.Abort(msg, hint=hint)
6103 raise error.Abort(msg, hint=hint)
6099 dirty = any(repo.status())
6104 dirty = any(repo.status())
6100 node = ctx.node()
6105 node = ctx.node()
6101 if node != parent:
6106 if node != parent:
6102 if dirty:
6107 if dirty:
6103 hint = _("uncommitted changes, use --all to discard all"
6108 hint = _("uncommitted changes, use --all to discard all"
6104 " changes, or 'hg update %s' to update") % ctx.rev()
6109 " changes, or 'hg update %s' to update") % ctx.rev()
6105 else:
6110 else:
6106 hint = _("use --all to revert all files,"
6111 hint = _("use --all to revert all files,"
6107 " or 'hg update %s' to update") % ctx.rev()
6112 " or 'hg update %s' to update") % ctx.rev()
6108 elif dirty:
6113 elif dirty:
6109 hint = _("uncommitted changes, use --all to discard all changes")
6114 hint = _("uncommitted changes, use --all to discard all changes")
6110 else:
6115 else:
6111 hint = _("use --all to revert all files")
6116 hint = _("use --all to revert all files")
6112 raise error.Abort(msg, hint=hint)
6117 raise error.Abort(msg, hint=hint)
6113
6118
6114 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
6119 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
6115
6120
6116 @command('rollback', dryrunopts +
6121 @command('rollback', dryrunopts +
6117 [('f', 'force', False, _('ignore safety measures'))])
6122 [('f', 'force', False, _('ignore safety measures'))])
6118 def rollback(ui, repo, **opts):
6123 def rollback(ui, repo, **opts):
6119 """roll back the last transaction (DANGEROUS) (DEPRECATED)
6124 """roll back the last transaction (DANGEROUS) (DEPRECATED)
6120
6125
6121 Please use :hg:`commit --amend` instead of rollback to correct
6126 Please use :hg:`commit --amend` instead of rollback to correct
6122 mistakes in the last commit.
6127 mistakes in the last commit.
6123
6128
6124 This command should be used with care. There is only one level of
6129 This command should be used with care. There is only one level of
6125 rollback, and there is no way to undo a rollback. It will also
6130 rollback, and there is no way to undo a rollback. It will also
6126 restore the dirstate at the time of the last transaction, losing
6131 restore the dirstate at the time of the last transaction, losing
6127 any dirstate changes since that time. This command does not alter
6132 any dirstate changes since that time. This command does not alter
6128 the working directory.
6133 the working directory.
6129
6134
6130 Transactions are used to encapsulate the effects of all commands
6135 Transactions are used to encapsulate the effects of all commands
6131 that create new changesets or propagate existing changesets into a
6136 that create new changesets or propagate existing changesets into a
6132 repository.
6137 repository.
6133
6138
6134 .. container:: verbose
6139 .. container:: verbose
6135
6140
6136 For example, the following commands are transactional, and their
6141 For example, the following commands are transactional, and their
6137 effects can be rolled back:
6142 effects can be rolled back:
6138
6143
6139 - commit
6144 - commit
6140 - import
6145 - import
6141 - pull
6146 - pull
6142 - push (with this repository as the destination)
6147 - push (with this repository as the destination)
6143 - unbundle
6148 - unbundle
6144
6149
6145 To avoid permanent data loss, rollback will refuse to rollback a
6150 To avoid permanent data loss, rollback will refuse to rollback a
6146 commit transaction if it isn't checked out. Use --force to
6151 commit transaction if it isn't checked out. Use --force to
6147 override this protection.
6152 override this protection.
6148
6153
6149 This command is not intended for use on public repositories. Once
6154 This command is not intended for use on public repositories. Once
6150 changes are visible for pull by other users, rolling a transaction
6155 changes are visible for pull by other users, rolling a transaction
6151 back locally is ineffective (someone else may already have pulled
6156 back locally is ineffective (someone else may already have pulled
6152 the changes). Furthermore, a race is possible with readers of the
6157 the changes). Furthermore, a race is possible with readers of the
6153 repository; for example an in-progress pull from the repository
6158 repository; for example an in-progress pull from the repository
6154 may fail if a rollback is performed.
6159 may fail if a rollback is performed.
6155
6160
6156 Returns 0 on success, 1 if no rollback data is available.
6161 Returns 0 on success, 1 if no rollback data is available.
6157 """
6162 """
6158 return repo.rollback(dryrun=opts.get('dry_run'),
6163 return repo.rollback(dryrun=opts.get('dry_run'),
6159 force=opts.get('force'))
6164 force=opts.get('force'))
6160
6165
6161 @command('root', [])
6166 @command('root', [])
6162 def root(ui, repo):
6167 def root(ui, repo):
6163 """print the root (top) of the current working directory
6168 """print the root (top) of the current working directory
6164
6169
6165 Print the root directory of the current repository.
6170 Print the root directory of the current repository.
6166
6171
6167 Returns 0 on success.
6172 Returns 0 on success.
6168 """
6173 """
6169 ui.write(repo.root + "\n")
6174 ui.write(repo.root + "\n")
6170
6175
6171 @command('^serve',
6176 @command('^serve',
6172 [('A', 'accesslog', '', _('name of access log file to write to'),
6177 [('A', 'accesslog', '', _('name of access log file to write to'),
6173 _('FILE')),
6178 _('FILE')),
6174 ('d', 'daemon', None, _('run server in background')),
6179 ('d', 'daemon', None, _('run server in background')),
6175 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('FILE')),
6180 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('FILE')),
6176 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
6181 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
6177 # use string type, then we can check if something was passed
6182 # use string type, then we can check if something was passed
6178 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
6183 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
6179 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
6184 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
6180 _('ADDR')),
6185 _('ADDR')),
6181 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
6186 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
6182 _('PREFIX')),
6187 _('PREFIX')),
6183 ('n', 'name', '',
6188 ('n', 'name', '',
6184 _('name to show in web pages (default: working directory)'), _('NAME')),
6189 _('name to show in web pages (default: working directory)'), _('NAME')),
6185 ('', 'web-conf', '',
6190 ('', 'web-conf', '',
6186 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
6191 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
6187 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
6192 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
6188 _('FILE')),
6193 _('FILE')),
6189 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
6194 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
6190 ('', 'stdio', None, _('for remote clients')),
6195 ('', 'stdio', None, _('for remote clients')),
6191 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
6196 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
6192 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
6197 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
6193 ('', 'style', '', _('template style to use'), _('STYLE')),
6198 ('', 'style', '', _('template style to use'), _('STYLE')),
6194 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
6199 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
6195 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
6200 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
6196 _('[OPTION]...'),
6201 _('[OPTION]...'),
6197 optionalrepo=True)
6202 optionalrepo=True)
6198 def serve(ui, repo, **opts):
6203 def serve(ui, repo, **opts):
6199 """start stand-alone webserver
6204 """start stand-alone webserver
6200
6205
6201 Start a local HTTP repository browser and pull server. You can use
6206 Start a local HTTP repository browser and pull server. You can use
6202 this for ad-hoc sharing and browsing of repositories. It is
6207 this for ad-hoc sharing and browsing of repositories. It is
6203 recommended to use a real web server to serve a repository for
6208 recommended to use a real web server to serve a repository for
6204 longer periods of time.
6209 longer periods of time.
6205
6210
6206 Please note that the server does not implement access control.
6211 Please note that the server does not implement access control.
6207 This means that, by default, anybody can read from the server and
6212 This means that, by default, anybody can read from the server and
6208 nobody can write to it by default. Set the ``web.allow_push``
6213 nobody can write to it by default. Set the ``web.allow_push``
6209 option to ``*`` to allow everybody to push to the server. You
6214 option to ``*`` to allow everybody to push to the server. You
6210 should use a real web server if you need to authenticate users.
6215 should use a real web server if you need to authenticate users.
6211
6216
6212 By default, the server logs accesses to stdout and errors to
6217 By default, the server logs accesses to stdout and errors to
6213 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
6218 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
6214 files.
6219 files.
6215
6220
6216 To have the server choose a free port number to listen on, specify
6221 To have the server choose a free port number to listen on, specify
6217 a port number of 0; in this case, the server will print the port
6222 a port number of 0; in this case, the server will print the port
6218 number it uses.
6223 number it uses.
6219
6224
6220 Returns 0 on success.
6225 Returns 0 on success.
6221 """
6226 """
6222
6227
6223 if opts["stdio"] and opts["cmdserver"]:
6228 if opts["stdio"] and opts["cmdserver"]:
6224 raise error.Abort(_("cannot use --stdio with --cmdserver"))
6229 raise error.Abort(_("cannot use --stdio with --cmdserver"))
6225
6230
6226 if opts["stdio"]:
6231 if opts["stdio"]:
6227 if repo is None:
6232 if repo is None:
6228 raise error.RepoError(_("there is no Mercurial repository here"
6233 raise error.RepoError(_("there is no Mercurial repository here"
6229 " (.hg not found)"))
6234 " (.hg not found)"))
6230 s = sshserver.sshserver(ui, repo)
6235 s = sshserver.sshserver(ui, repo)
6231 s.serve_forever()
6236 s.serve_forever()
6232
6237
6233 if opts["cmdserver"]:
6238 if opts["cmdserver"]:
6234 service = commandserver.createservice(ui, repo, opts)
6239 service = commandserver.createservice(ui, repo, opts)
6235 else:
6240 else:
6236 service = hgweb.createservice(ui, repo, opts)
6241 service = hgweb.createservice(ui, repo, opts)
6237 return cmdutil.service(opts, initfn=service.init, runfn=service.run)
6242 return cmdutil.service(opts, initfn=service.init, runfn=service.run)
6238
6243
6239 @command('^status|st',
6244 @command('^status|st',
6240 [('A', 'all', None, _('show status of all files')),
6245 [('A', 'all', None, _('show status of all files')),
6241 ('m', 'modified', None, _('show only modified files')),
6246 ('m', 'modified', None, _('show only modified files')),
6242 ('a', 'added', None, _('show only added files')),
6247 ('a', 'added', None, _('show only added files')),
6243 ('r', 'removed', None, _('show only removed files')),
6248 ('r', 'removed', None, _('show only removed files')),
6244 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
6249 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
6245 ('c', 'clean', None, _('show only files without changes')),
6250 ('c', 'clean', None, _('show only files without changes')),
6246 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
6251 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
6247 ('i', 'ignored', None, _('show only ignored files')),
6252 ('i', 'ignored', None, _('show only ignored files')),
6248 ('n', 'no-status', None, _('hide status prefix')),
6253 ('n', 'no-status', None, _('hide status prefix')),
6249 ('C', 'copies', None, _('show source of copied files')),
6254 ('C', 'copies', None, _('show source of copied files')),
6250 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
6255 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
6251 ('', 'rev', [], _('show difference from revision'), _('REV')),
6256 ('', 'rev', [], _('show difference from revision'), _('REV')),
6252 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
6257 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
6253 ] + walkopts + subrepoopts + formatteropts,
6258 ] + walkopts + subrepoopts + formatteropts,
6254 _('[OPTION]... [FILE]...'),
6259 _('[OPTION]... [FILE]...'),
6255 inferrepo=True)
6260 inferrepo=True)
6256 def status(ui, repo, *pats, **opts):
6261 def status(ui, repo, *pats, **opts):
6257 """show changed files in the working directory
6262 """show changed files in the working directory
6258
6263
6259 Show status of files in the repository. If names are given, only
6264 Show status of files in the repository. If names are given, only
6260 files that match are shown. Files that are clean or ignored or
6265 files that match are shown. Files that are clean or ignored or
6261 the source of a copy/move operation, are not listed unless
6266 the source of a copy/move operation, are not listed unless
6262 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
6267 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
6263 Unless options described with "show only ..." are given, the
6268 Unless options described with "show only ..." are given, the
6264 options -mardu are used.
6269 options -mardu are used.
6265
6270
6266 Option -q/--quiet hides untracked (unknown and ignored) files
6271 Option -q/--quiet hides untracked (unknown and ignored) files
6267 unless explicitly requested with -u/--unknown or -i/--ignored.
6272 unless explicitly requested with -u/--unknown or -i/--ignored.
6268
6273
6269 .. note::
6274 .. note::
6270
6275
6271 :hg:`status` may appear to disagree with diff if permissions have
6276 :hg:`status` may appear to disagree with diff if permissions have
6272 changed or a merge has occurred. The standard diff format does
6277 changed or a merge has occurred. The standard diff format does
6273 not report permission changes and diff only reports changes
6278 not report permission changes and diff only reports changes
6274 relative to one merge parent.
6279 relative to one merge parent.
6275
6280
6276 If one revision is given, it is used as the base revision.
6281 If one revision is given, it is used as the base revision.
6277 If two revisions are given, the differences between them are
6282 If two revisions are given, the differences between them are
6278 shown. The --change option can also be used as a shortcut to list
6283 shown. The --change option can also be used as a shortcut to list
6279 the changed files of a revision from its first parent.
6284 the changed files of a revision from its first parent.
6280
6285
6281 The codes used to show the status of files are::
6286 The codes used to show the status of files are::
6282
6287
6283 M = modified
6288 M = modified
6284 A = added
6289 A = added
6285 R = removed
6290 R = removed
6286 C = clean
6291 C = clean
6287 ! = missing (deleted by non-hg command, but still tracked)
6292 ! = missing (deleted by non-hg command, but still tracked)
6288 ? = not tracked
6293 ? = not tracked
6289 I = ignored
6294 I = ignored
6290 = origin of the previous file (with --copies)
6295 = origin of the previous file (with --copies)
6291
6296
6292 .. container:: verbose
6297 .. container:: verbose
6293
6298
6294 Examples:
6299 Examples:
6295
6300
6296 - show changes in the working directory relative to a
6301 - show changes in the working directory relative to a
6297 changeset::
6302 changeset::
6298
6303
6299 hg status --rev 9353
6304 hg status --rev 9353
6300
6305
6301 - show changes in the working directory relative to the
6306 - show changes in the working directory relative to the
6302 current directory (see :hg:`help patterns` for more information)::
6307 current directory (see :hg:`help patterns` for more information)::
6303
6308
6304 hg status re:
6309 hg status re:
6305
6310
6306 - show all changes including copies in an existing changeset::
6311 - show all changes including copies in an existing changeset::
6307
6312
6308 hg status --copies --change 9353
6313 hg status --copies --change 9353
6309
6314
6310 - get a NUL separated list of added files, suitable for xargs::
6315 - get a NUL separated list of added files, suitable for xargs::
6311
6316
6312 hg status -an0
6317 hg status -an0
6313
6318
6314 Returns 0 on success.
6319 Returns 0 on success.
6315 """
6320 """
6316
6321
6317 revs = opts.get('rev')
6322 revs = opts.get('rev')
6318 change = opts.get('change')
6323 change = opts.get('change')
6319
6324
6320 if revs and change:
6325 if revs and change:
6321 msg = _('cannot specify --rev and --change at the same time')
6326 msg = _('cannot specify --rev and --change at the same time')
6322 raise error.Abort(msg)
6327 raise error.Abort(msg)
6323 elif change:
6328 elif change:
6324 node2 = scmutil.revsingle(repo, change, None).node()
6329 node2 = scmutil.revsingle(repo, change, None).node()
6325 node1 = repo[node2].p1().node()
6330 node1 = repo[node2].p1().node()
6326 else:
6331 else:
6327 node1, node2 = scmutil.revpair(repo, revs)
6332 node1, node2 = scmutil.revpair(repo, revs)
6328
6333
6329 if pats:
6334 if pats:
6330 cwd = repo.getcwd()
6335 cwd = repo.getcwd()
6331 else:
6336 else:
6332 cwd = ''
6337 cwd = ''
6333
6338
6334 if opts.get('print0'):
6339 if opts.get('print0'):
6335 end = '\0'
6340 end = '\0'
6336 else:
6341 else:
6337 end = '\n'
6342 end = '\n'
6338 copy = {}
6343 copy = {}
6339 states = 'modified added removed deleted unknown ignored clean'.split()
6344 states = 'modified added removed deleted unknown ignored clean'.split()
6340 show = [k for k in states if opts.get(k)]
6345 show = [k for k in states if opts.get(k)]
6341 if opts.get('all'):
6346 if opts.get('all'):
6342 show += ui.quiet and (states[:4] + ['clean']) or states
6347 show += ui.quiet and (states[:4] + ['clean']) or states
6343 if not show:
6348 if not show:
6344 if ui.quiet:
6349 if ui.quiet:
6345 show = states[:4]
6350 show = states[:4]
6346 else:
6351 else:
6347 show = states[:5]
6352 show = states[:5]
6348
6353
6349 m = scmutil.match(repo[node2], pats, opts)
6354 m = scmutil.match(repo[node2], pats, opts)
6350 stat = repo.status(node1, node2, m,
6355 stat = repo.status(node1, node2, m,
6351 'ignored' in show, 'clean' in show, 'unknown' in show,
6356 'ignored' in show, 'clean' in show, 'unknown' in show,
6352 opts.get('subrepos'))
6357 opts.get('subrepos'))
6353 changestates = zip(states, 'MAR!?IC', stat)
6358 changestates = zip(states, 'MAR!?IC', stat)
6354
6359
6355 if (opts.get('all') or opts.get('copies')
6360 if (opts.get('all') or opts.get('copies')
6356 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
6361 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
6357 copy = copies.pathcopies(repo[node1], repo[node2], m)
6362 copy = copies.pathcopies(repo[node1], repo[node2], m)
6358
6363
6359 fm = ui.formatter('status', opts)
6364 fm = ui.formatter('status', opts)
6360 fmt = '%s' + end
6365 fmt = '%s' + end
6361 showchar = not opts.get('no_status')
6366 showchar = not opts.get('no_status')
6362
6367
6363 for state, char, files in changestates:
6368 for state, char, files in changestates:
6364 if state in show:
6369 if state in show:
6365 label = 'status.' + state
6370 label = 'status.' + state
6366 for f in files:
6371 for f in files:
6367 fm.startitem()
6372 fm.startitem()
6368 fm.condwrite(showchar, 'status', '%s ', char, label=label)
6373 fm.condwrite(showchar, 'status', '%s ', char, label=label)
6369 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
6374 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
6370 if f in copy:
6375 if f in copy:
6371 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
6376 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
6372 label='status.copied')
6377 label='status.copied')
6373 fm.end()
6378 fm.end()
6374
6379
6375 @command('^summary|sum',
6380 @command('^summary|sum',
6376 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
6381 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
6377 def summary(ui, repo, **opts):
6382 def summary(ui, repo, **opts):
6378 """summarize working directory state
6383 """summarize working directory state
6379
6384
6380 This generates a brief summary of the working directory state,
6385 This generates a brief summary of the working directory state,
6381 including parents, branch, commit status, phase and available updates.
6386 including parents, branch, commit status, phase and available updates.
6382
6387
6383 With the --remote option, this will check the default paths for
6388 With the --remote option, this will check the default paths for
6384 incoming and outgoing changes. This can be time-consuming.
6389 incoming and outgoing changes. This can be time-consuming.
6385
6390
6386 Returns 0 on success.
6391 Returns 0 on success.
6387 """
6392 """
6388
6393
6389 ctx = repo[None]
6394 ctx = repo[None]
6390 parents = ctx.parents()
6395 parents = ctx.parents()
6391 pnode = parents[0].node()
6396 pnode = parents[0].node()
6392 marks = []
6397 marks = []
6393
6398
6394 for p in parents:
6399 for p in parents:
6395 # label with log.changeset (instead of log.parent) since this
6400 # label with log.changeset (instead of log.parent) since this
6396 # shows a working directory parent *changeset*:
6401 # shows a working directory parent *changeset*:
6397 # i18n: column positioning for "hg summary"
6402 # i18n: column positioning for "hg summary"
6398 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
6403 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
6399 label='log.changeset changeset.%s' % p.phasestr())
6404 label='log.changeset changeset.%s' % p.phasestr())
6400 ui.write(' '.join(p.tags()), label='log.tag')
6405 ui.write(' '.join(p.tags()), label='log.tag')
6401 if p.bookmarks():
6406 if p.bookmarks():
6402 marks.extend(p.bookmarks())
6407 marks.extend(p.bookmarks())
6403 if p.rev() == -1:
6408 if p.rev() == -1:
6404 if not len(repo):
6409 if not len(repo):
6405 ui.write(_(' (empty repository)'))
6410 ui.write(_(' (empty repository)'))
6406 else:
6411 else:
6407 ui.write(_(' (no revision checked out)'))
6412 ui.write(_(' (no revision checked out)'))
6408 ui.write('\n')
6413 ui.write('\n')
6409 if p.description():
6414 if p.description():
6410 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
6415 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
6411 label='log.summary')
6416 label='log.summary')
6412
6417
6413 branch = ctx.branch()
6418 branch = ctx.branch()
6414 bheads = repo.branchheads(branch)
6419 bheads = repo.branchheads(branch)
6415 # i18n: column positioning for "hg summary"
6420 # i18n: column positioning for "hg summary"
6416 m = _('branch: %s\n') % branch
6421 m = _('branch: %s\n') % branch
6417 if branch != 'default':
6422 if branch != 'default':
6418 ui.write(m, label='log.branch')
6423 ui.write(m, label='log.branch')
6419 else:
6424 else:
6420 ui.status(m, label='log.branch')
6425 ui.status(m, label='log.branch')
6421
6426
6422 if marks:
6427 if marks:
6423 active = repo._activebookmark
6428 active = repo._activebookmark
6424 # i18n: column positioning for "hg summary"
6429 # i18n: column positioning for "hg summary"
6425 ui.write(_('bookmarks:'), label='log.bookmark')
6430 ui.write(_('bookmarks:'), label='log.bookmark')
6426 if active is not None:
6431 if active is not None:
6427 if active in marks:
6432 if active in marks:
6428 ui.write(' *' + active, label=activebookmarklabel)
6433 ui.write(' *' + active, label=activebookmarklabel)
6429 marks.remove(active)
6434 marks.remove(active)
6430 else:
6435 else:
6431 ui.write(' [%s]' % active, label=activebookmarklabel)
6436 ui.write(' [%s]' % active, label=activebookmarklabel)
6432 for m in marks:
6437 for m in marks:
6433 ui.write(' ' + m, label='log.bookmark')
6438 ui.write(' ' + m, label='log.bookmark')
6434 ui.write('\n', label='log.bookmark')
6439 ui.write('\n', label='log.bookmark')
6435
6440
6436 status = repo.status(unknown=True)
6441 status = repo.status(unknown=True)
6437
6442
6438 c = repo.dirstate.copies()
6443 c = repo.dirstate.copies()
6439 copied, renamed = [], []
6444 copied, renamed = [], []
6440 for d, s in c.iteritems():
6445 for d, s in c.iteritems():
6441 if s in status.removed:
6446 if s in status.removed:
6442 status.removed.remove(s)
6447 status.removed.remove(s)
6443 renamed.append(d)
6448 renamed.append(d)
6444 else:
6449 else:
6445 copied.append(d)
6450 copied.append(d)
6446 if d in status.added:
6451 if d in status.added:
6447 status.added.remove(d)
6452 status.added.remove(d)
6448
6453
6449 try:
6454 try:
6450 ms = mergemod.mergestate.read(repo)
6455 ms = mergemod.mergestate.read(repo)
6451 except error.UnsupportedMergeRecords as e:
6456 except error.UnsupportedMergeRecords as e:
6452 s = ' '.join(e.recordtypes)
6457 s = ' '.join(e.recordtypes)
6453 ui.warn(
6458 ui.warn(
6454 _('warning: merge state has unsupported record types: %s\n') % s)
6459 _('warning: merge state has unsupported record types: %s\n') % s)
6455 unresolved = 0
6460 unresolved = 0
6456 else:
6461 else:
6457 unresolved = [f for f in ms if ms[f] == 'u']
6462 unresolved = [f for f in ms if ms[f] == 'u']
6458
6463
6459 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6464 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6460
6465
6461 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
6466 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
6462 (ui.label(_('%d added'), 'status.added'), status.added),
6467 (ui.label(_('%d added'), 'status.added'), status.added),
6463 (ui.label(_('%d removed'), 'status.removed'), status.removed),
6468 (ui.label(_('%d removed'), 'status.removed'), status.removed),
6464 (ui.label(_('%d renamed'), 'status.copied'), renamed),
6469 (ui.label(_('%d renamed'), 'status.copied'), renamed),
6465 (ui.label(_('%d copied'), 'status.copied'), copied),
6470 (ui.label(_('%d copied'), 'status.copied'), copied),
6466 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
6471 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
6467 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
6472 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
6468 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
6473 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
6469 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
6474 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
6470 t = []
6475 t = []
6471 for l, s in labels:
6476 for l, s in labels:
6472 if s:
6477 if s:
6473 t.append(l % len(s))
6478 t.append(l % len(s))
6474
6479
6475 t = ', '.join(t)
6480 t = ', '.join(t)
6476 cleanworkdir = False
6481 cleanworkdir = False
6477
6482
6478 if repo.vfs.exists('graftstate'):
6483 if repo.vfs.exists('graftstate'):
6479 t += _(' (graft in progress)')
6484 t += _(' (graft in progress)')
6480 if repo.vfs.exists('updatestate'):
6485 if repo.vfs.exists('updatestate'):
6481 t += _(' (interrupted update)')
6486 t += _(' (interrupted update)')
6482 elif len(parents) > 1:
6487 elif len(parents) > 1:
6483 t += _(' (merge)')
6488 t += _(' (merge)')
6484 elif branch != parents[0].branch():
6489 elif branch != parents[0].branch():
6485 t += _(' (new branch)')
6490 t += _(' (new branch)')
6486 elif (parents[0].closesbranch() and
6491 elif (parents[0].closesbranch() and
6487 pnode in repo.branchheads(branch, closed=True)):
6492 pnode in repo.branchheads(branch, closed=True)):
6488 t += _(' (head closed)')
6493 t += _(' (head closed)')
6489 elif not (status.modified or status.added or status.removed or renamed or
6494 elif not (status.modified or status.added or status.removed or renamed or
6490 copied or subs):
6495 copied or subs):
6491 t += _(' (clean)')
6496 t += _(' (clean)')
6492 cleanworkdir = True
6497 cleanworkdir = True
6493 elif pnode not in bheads:
6498 elif pnode not in bheads:
6494 t += _(' (new branch head)')
6499 t += _(' (new branch head)')
6495
6500
6496 if parents:
6501 if parents:
6497 pendingphase = max(p.phase() for p in parents)
6502 pendingphase = max(p.phase() for p in parents)
6498 else:
6503 else:
6499 pendingphase = phases.public
6504 pendingphase = phases.public
6500
6505
6501 if pendingphase > phases.newcommitphase(ui):
6506 if pendingphase > phases.newcommitphase(ui):
6502 t += ' (%s)' % phases.phasenames[pendingphase]
6507 t += ' (%s)' % phases.phasenames[pendingphase]
6503
6508
6504 if cleanworkdir:
6509 if cleanworkdir:
6505 # i18n: column positioning for "hg summary"
6510 # i18n: column positioning for "hg summary"
6506 ui.status(_('commit: %s\n') % t.strip())
6511 ui.status(_('commit: %s\n') % t.strip())
6507 else:
6512 else:
6508 # i18n: column positioning for "hg summary"
6513 # i18n: column positioning for "hg summary"
6509 ui.write(_('commit: %s\n') % t.strip())
6514 ui.write(_('commit: %s\n') % t.strip())
6510
6515
6511 # all ancestors of branch heads - all ancestors of parent = new csets
6516 # all ancestors of branch heads - all ancestors of parent = new csets
6512 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
6517 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
6513 bheads))
6518 bheads))
6514
6519
6515 if new == 0:
6520 if new == 0:
6516 # i18n: column positioning for "hg summary"
6521 # i18n: column positioning for "hg summary"
6517 ui.status(_('update: (current)\n'))
6522 ui.status(_('update: (current)\n'))
6518 elif pnode not in bheads:
6523 elif pnode not in bheads:
6519 # i18n: column positioning for "hg summary"
6524 # i18n: column positioning for "hg summary"
6520 ui.write(_('update: %d new changesets (update)\n') % new)
6525 ui.write(_('update: %d new changesets (update)\n') % new)
6521 else:
6526 else:
6522 # i18n: column positioning for "hg summary"
6527 # i18n: column positioning for "hg summary"
6523 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
6528 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
6524 (new, len(bheads)))
6529 (new, len(bheads)))
6525
6530
6526 t = []
6531 t = []
6527 draft = len(repo.revs('draft()'))
6532 draft = len(repo.revs('draft()'))
6528 if draft:
6533 if draft:
6529 t.append(_('%d draft') % draft)
6534 t.append(_('%d draft') % draft)
6530 secret = len(repo.revs('secret()'))
6535 secret = len(repo.revs('secret()'))
6531 if secret:
6536 if secret:
6532 t.append(_('%d secret') % secret)
6537 t.append(_('%d secret') % secret)
6533
6538
6534 if draft or secret:
6539 if draft or secret:
6535 ui.status(_('phases: %s\n') % ', '.join(t))
6540 ui.status(_('phases: %s\n') % ', '.join(t))
6536
6541
6537 if obsolete.isenabled(repo, obsolete.createmarkersopt):
6542 if obsolete.isenabled(repo, obsolete.createmarkersopt):
6538 for trouble in ("unstable", "divergent", "bumped"):
6543 for trouble in ("unstable", "divergent", "bumped"):
6539 numtrouble = len(repo.revs(trouble + "()"))
6544 numtrouble = len(repo.revs(trouble + "()"))
6540 # We write all the possibilities to ease translation
6545 # We write all the possibilities to ease translation
6541 troublemsg = {
6546 troublemsg = {
6542 "unstable": _("unstable: %d changesets"),
6547 "unstable": _("unstable: %d changesets"),
6543 "divergent": _("divergent: %d changesets"),
6548 "divergent": _("divergent: %d changesets"),
6544 "bumped": _("bumped: %d changesets"),
6549 "bumped": _("bumped: %d changesets"),
6545 }
6550 }
6546 if numtrouble > 0:
6551 if numtrouble > 0:
6547 ui.status(troublemsg[trouble] % numtrouble + "\n")
6552 ui.status(troublemsg[trouble] % numtrouble + "\n")
6548
6553
6549 cmdutil.summaryhooks(ui, repo)
6554 cmdutil.summaryhooks(ui, repo)
6550
6555
6551 if opts.get('remote'):
6556 if opts.get('remote'):
6552 needsincoming, needsoutgoing = True, True
6557 needsincoming, needsoutgoing = True, True
6553 else:
6558 else:
6554 needsincoming, needsoutgoing = False, False
6559 needsincoming, needsoutgoing = False, False
6555 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
6560 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
6556 if i:
6561 if i:
6557 needsincoming = True
6562 needsincoming = True
6558 if o:
6563 if o:
6559 needsoutgoing = True
6564 needsoutgoing = True
6560 if not needsincoming and not needsoutgoing:
6565 if not needsincoming and not needsoutgoing:
6561 return
6566 return
6562
6567
6563 def getincoming():
6568 def getincoming():
6564 source, branches = hg.parseurl(ui.expandpath('default'))
6569 source, branches = hg.parseurl(ui.expandpath('default'))
6565 sbranch = branches[0]
6570 sbranch = branches[0]
6566 try:
6571 try:
6567 other = hg.peer(repo, {}, source)
6572 other = hg.peer(repo, {}, source)
6568 except error.RepoError:
6573 except error.RepoError:
6569 if opts.get('remote'):
6574 if opts.get('remote'):
6570 raise
6575 raise
6571 return source, sbranch, None, None, None
6576 return source, sbranch, None, None, None
6572 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
6577 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
6573 if revs:
6578 if revs:
6574 revs = [other.lookup(rev) for rev in revs]
6579 revs = [other.lookup(rev) for rev in revs]
6575 ui.debug('comparing with %s\n' % util.hidepassword(source))
6580 ui.debug('comparing with %s\n' % util.hidepassword(source))
6576 repo.ui.pushbuffer()
6581 repo.ui.pushbuffer()
6577 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
6582 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
6578 repo.ui.popbuffer()
6583 repo.ui.popbuffer()
6579 return source, sbranch, other, commoninc, commoninc[1]
6584 return source, sbranch, other, commoninc, commoninc[1]
6580
6585
6581 if needsincoming:
6586 if needsincoming:
6582 source, sbranch, sother, commoninc, incoming = getincoming()
6587 source, sbranch, sother, commoninc, incoming = getincoming()
6583 else:
6588 else:
6584 source = sbranch = sother = commoninc = incoming = None
6589 source = sbranch = sother = commoninc = incoming = None
6585
6590
6586 def getoutgoing():
6591 def getoutgoing():
6587 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
6592 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
6588 dbranch = branches[0]
6593 dbranch = branches[0]
6589 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
6594 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
6590 if source != dest:
6595 if source != dest:
6591 try:
6596 try:
6592 dother = hg.peer(repo, {}, dest)
6597 dother = hg.peer(repo, {}, dest)
6593 except error.RepoError:
6598 except error.RepoError:
6594 if opts.get('remote'):
6599 if opts.get('remote'):
6595 raise
6600 raise
6596 return dest, dbranch, None, None
6601 return dest, dbranch, None, None
6597 ui.debug('comparing with %s\n' % util.hidepassword(dest))
6602 ui.debug('comparing with %s\n' % util.hidepassword(dest))
6598 elif sother is None:
6603 elif sother is None:
6599 # there is no explicit destination peer, but source one is invalid
6604 # there is no explicit destination peer, but source one is invalid
6600 return dest, dbranch, None, None
6605 return dest, dbranch, None, None
6601 else:
6606 else:
6602 dother = sother
6607 dother = sother
6603 if (source != dest or (sbranch is not None and sbranch != dbranch)):
6608 if (source != dest or (sbranch is not None and sbranch != dbranch)):
6604 common = None
6609 common = None
6605 else:
6610 else:
6606 common = commoninc
6611 common = commoninc
6607 if revs:
6612 if revs:
6608 revs = [repo.lookup(rev) for rev in revs]
6613 revs = [repo.lookup(rev) for rev in revs]
6609 repo.ui.pushbuffer()
6614 repo.ui.pushbuffer()
6610 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
6615 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
6611 commoninc=common)
6616 commoninc=common)
6612 repo.ui.popbuffer()
6617 repo.ui.popbuffer()
6613 return dest, dbranch, dother, outgoing
6618 return dest, dbranch, dother, outgoing
6614
6619
6615 if needsoutgoing:
6620 if needsoutgoing:
6616 dest, dbranch, dother, outgoing = getoutgoing()
6621 dest, dbranch, dother, outgoing = getoutgoing()
6617 else:
6622 else:
6618 dest = dbranch = dother = outgoing = None
6623 dest = dbranch = dother = outgoing = None
6619
6624
6620 if opts.get('remote'):
6625 if opts.get('remote'):
6621 t = []
6626 t = []
6622 if incoming:
6627 if incoming:
6623 t.append(_('1 or more incoming'))
6628 t.append(_('1 or more incoming'))
6624 o = outgoing.missing
6629 o = outgoing.missing
6625 if o:
6630 if o:
6626 t.append(_('%d outgoing') % len(o))
6631 t.append(_('%d outgoing') % len(o))
6627 other = dother or sother
6632 other = dother or sother
6628 if 'bookmarks' in other.listkeys('namespaces'):
6633 if 'bookmarks' in other.listkeys('namespaces'):
6629 counts = bookmarks.summary(repo, other)
6634 counts = bookmarks.summary(repo, other)
6630 if counts[0] > 0:
6635 if counts[0] > 0:
6631 t.append(_('%d incoming bookmarks') % counts[0])
6636 t.append(_('%d incoming bookmarks') % counts[0])
6632 if counts[1] > 0:
6637 if counts[1] > 0:
6633 t.append(_('%d outgoing bookmarks') % counts[1])
6638 t.append(_('%d outgoing bookmarks') % counts[1])
6634
6639
6635 if t:
6640 if t:
6636 # i18n: column positioning for "hg summary"
6641 # i18n: column positioning for "hg summary"
6637 ui.write(_('remote: %s\n') % (', '.join(t)))
6642 ui.write(_('remote: %s\n') % (', '.join(t)))
6638 else:
6643 else:
6639 # i18n: column positioning for "hg summary"
6644 # i18n: column positioning for "hg summary"
6640 ui.status(_('remote: (synced)\n'))
6645 ui.status(_('remote: (synced)\n'))
6641
6646
6642 cmdutil.summaryremotehooks(ui, repo, opts,
6647 cmdutil.summaryremotehooks(ui, repo, opts,
6643 ((source, sbranch, sother, commoninc),
6648 ((source, sbranch, sother, commoninc),
6644 (dest, dbranch, dother, outgoing)))
6649 (dest, dbranch, dother, outgoing)))
6645
6650
6646 @command('tag',
6651 @command('tag',
6647 [('f', 'force', None, _('force tag')),
6652 [('f', 'force', None, _('force tag')),
6648 ('l', 'local', None, _('make the tag local')),
6653 ('l', 'local', None, _('make the tag local')),
6649 ('r', 'rev', '', _('revision to tag'), _('REV')),
6654 ('r', 'rev', '', _('revision to tag'), _('REV')),
6650 ('', 'remove', None, _('remove a tag')),
6655 ('', 'remove', None, _('remove a tag')),
6651 # -l/--local is already there, commitopts cannot be used
6656 # -l/--local is already there, commitopts cannot be used
6652 ('e', 'edit', None, _('invoke editor on commit messages')),
6657 ('e', 'edit', None, _('invoke editor on commit messages')),
6653 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
6658 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
6654 ] + commitopts2,
6659 ] + commitopts2,
6655 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
6660 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
6656 def tag(ui, repo, name1, *names, **opts):
6661 def tag(ui, repo, name1, *names, **opts):
6657 """add one or more tags for the current or given revision
6662 """add one or more tags for the current or given revision
6658
6663
6659 Name a particular revision using <name>.
6664 Name a particular revision using <name>.
6660
6665
6661 Tags are used to name particular revisions of the repository and are
6666 Tags are used to name particular revisions of the repository and are
6662 very useful to compare different revisions, to go back to significant
6667 very useful to compare different revisions, to go back to significant
6663 earlier versions or to mark branch points as releases, etc. Changing
6668 earlier versions or to mark branch points as releases, etc. Changing
6664 an existing tag is normally disallowed; use -f/--force to override.
6669 an existing tag is normally disallowed; use -f/--force to override.
6665
6670
6666 If no revision is given, the parent of the working directory is
6671 If no revision is given, the parent of the working directory is
6667 used.
6672 used.
6668
6673
6669 To facilitate version control, distribution, and merging of tags,
6674 To facilitate version control, distribution, and merging of tags,
6670 they are stored as a file named ".hgtags" which is managed similarly
6675 they are stored as a file named ".hgtags" which is managed similarly
6671 to other project files and can be hand-edited if necessary. This
6676 to other project files and can be hand-edited if necessary. This
6672 also means that tagging creates a new commit. The file
6677 also means that tagging creates a new commit. The file
6673 ".hg/localtags" is used for local tags (not shared among
6678 ".hg/localtags" is used for local tags (not shared among
6674 repositories).
6679 repositories).
6675
6680
6676 Tag commits are usually made at the head of a branch. If the parent
6681 Tag commits are usually made at the head of a branch. If the parent
6677 of the working directory is not a branch head, :hg:`tag` aborts; use
6682 of the working directory is not a branch head, :hg:`tag` aborts; use
6678 -f/--force to force the tag commit to be based on a non-head
6683 -f/--force to force the tag commit to be based on a non-head
6679 changeset.
6684 changeset.
6680
6685
6681 See :hg:`help dates` for a list of formats valid for -d/--date.
6686 See :hg:`help dates` for a list of formats valid for -d/--date.
6682
6687
6683 Since tag names have priority over branch names during revision
6688 Since tag names have priority over branch names during revision
6684 lookup, using an existing branch name as a tag name is discouraged.
6689 lookup, using an existing branch name as a tag name is discouraged.
6685
6690
6686 Returns 0 on success.
6691 Returns 0 on success.
6687 """
6692 """
6688 wlock = lock = None
6693 wlock = lock = None
6689 try:
6694 try:
6690 wlock = repo.wlock()
6695 wlock = repo.wlock()
6691 lock = repo.lock()
6696 lock = repo.lock()
6692 rev_ = "."
6697 rev_ = "."
6693 names = [t.strip() for t in (name1,) + names]
6698 names = [t.strip() for t in (name1,) + names]
6694 if len(names) != len(set(names)):
6699 if len(names) != len(set(names)):
6695 raise error.Abort(_('tag names must be unique'))
6700 raise error.Abort(_('tag names must be unique'))
6696 for n in names:
6701 for n in names:
6697 scmutil.checknewlabel(repo, n, 'tag')
6702 scmutil.checknewlabel(repo, n, 'tag')
6698 if not n:
6703 if not n:
6699 raise error.Abort(_('tag names cannot consist entirely of '
6704 raise error.Abort(_('tag names cannot consist entirely of '
6700 'whitespace'))
6705 'whitespace'))
6701 if opts.get('rev') and opts.get('remove'):
6706 if opts.get('rev') and opts.get('remove'):
6702 raise error.Abort(_("--rev and --remove are incompatible"))
6707 raise error.Abort(_("--rev and --remove are incompatible"))
6703 if opts.get('rev'):
6708 if opts.get('rev'):
6704 rev_ = opts['rev']
6709 rev_ = opts['rev']
6705 message = opts.get('message')
6710 message = opts.get('message')
6706 if opts.get('remove'):
6711 if opts.get('remove'):
6707 if opts.get('local'):
6712 if opts.get('local'):
6708 expectedtype = 'local'
6713 expectedtype = 'local'
6709 else:
6714 else:
6710 expectedtype = 'global'
6715 expectedtype = 'global'
6711
6716
6712 for n in names:
6717 for n in names:
6713 if not repo.tagtype(n):
6718 if not repo.tagtype(n):
6714 raise error.Abort(_("tag '%s' does not exist") % n)
6719 raise error.Abort(_("tag '%s' does not exist") % n)
6715 if repo.tagtype(n) != expectedtype:
6720 if repo.tagtype(n) != expectedtype:
6716 if expectedtype == 'global':
6721 if expectedtype == 'global':
6717 raise error.Abort(_("tag '%s' is not a global tag") % n)
6722 raise error.Abort(_("tag '%s' is not a global tag") % n)
6718 else:
6723 else:
6719 raise error.Abort(_("tag '%s' is not a local tag") % n)
6724 raise error.Abort(_("tag '%s' is not a local tag") % n)
6720 rev_ = 'null'
6725 rev_ = 'null'
6721 if not message:
6726 if not message:
6722 # we don't translate commit messages
6727 # we don't translate commit messages
6723 message = 'Removed tag %s' % ', '.join(names)
6728 message = 'Removed tag %s' % ', '.join(names)
6724 elif not opts.get('force'):
6729 elif not opts.get('force'):
6725 for n in names:
6730 for n in names:
6726 if n in repo.tags():
6731 if n in repo.tags():
6727 raise error.Abort(_("tag '%s' already exists "
6732 raise error.Abort(_("tag '%s' already exists "
6728 "(use -f to force)") % n)
6733 "(use -f to force)") % n)
6729 if not opts.get('local'):
6734 if not opts.get('local'):
6730 p1, p2 = repo.dirstate.parents()
6735 p1, p2 = repo.dirstate.parents()
6731 if p2 != nullid:
6736 if p2 != nullid:
6732 raise error.Abort(_('uncommitted merge'))
6737 raise error.Abort(_('uncommitted merge'))
6733 bheads = repo.branchheads()
6738 bheads = repo.branchheads()
6734 if not opts.get('force') and bheads and p1 not in bheads:
6739 if not opts.get('force') and bheads and p1 not in bheads:
6735 raise error.Abort(_('not at a branch head (use -f to force)'))
6740 raise error.Abort(_('not at a branch head (use -f to force)'))
6736 r = scmutil.revsingle(repo, rev_).node()
6741 r = scmutil.revsingle(repo, rev_).node()
6737
6742
6738 if not message:
6743 if not message:
6739 # we don't translate commit messages
6744 # we don't translate commit messages
6740 message = ('Added tag %s for changeset %s' %
6745 message = ('Added tag %s for changeset %s' %
6741 (', '.join(names), short(r)))
6746 (', '.join(names), short(r)))
6742
6747
6743 date = opts.get('date')
6748 date = opts.get('date')
6744 if date:
6749 if date:
6745 date = util.parsedate(date)
6750 date = util.parsedate(date)
6746
6751
6747 if opts.get('remove'):
6752 if opts.get('remove'):
6748 editform = 'tag.remove'
6753 editform = 'tag.remove'
6749 else:
6754 else:
6750 editform = 'tag.add'
6755 editform = 'tag.add'
6751 editor = cmdutil.getcommiteditor(editform=editform, **opts)
6756 editor = cmdutil.getcommiteditor(editform=editform, **opts)
6752
6757
6753 # don't allow tagging the null rev
6758 # don't allow tagging the null rev
6754 if (not opts.get('remove') and
6759 if (not opts.get('remove') and
6755 scmutil.revsingle(repo, rev_).rev() == nullrev):
6760 scmutil.revsingle(repo, rev_).rev() == nullrev):
6756 raise error.Abort(_("cannot tag null revision"))
6761 raise error.Abort(_("cannot tag null revision"))
6757
6762
6758 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
6763 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
6759 editor=editor)
6764 editor=editor)
6760 finally:
6765 finally:
6761 release(lock, wlock)
6766 release(lock, wlock)
6762
6767
6763 @command('tags', formatteropts, '')
6768 @command('tags', formatteropts, '')
6764 def tags(ui, repo, **opts):
6769 def tags(ui, repo, **opts):
6765 """list repository tags
6770 """list repository tags
6766
6771
6767 This lists both regular and local tags. When the -v/--verbose
6772 This lists both regular and local tags. When the -v/--verbose
6768 switch is used, a third column "local" is printed for local tags.
6773 switch is used, a third column "local" is printed for local tags.
6769 When the -q/--quiet switch is used, only the tag name is printed.
6774 When the -q/--quiet switch is used, only the tag name is printed.
6770
6775
6771 Returns 0 on success.
6776 Returns 0 on success.
6772 """
6777 """
6773
6778
6774 fm = ui.formatter('tags', opts)
6779 fm = ui.formatter('tags', opts)
6775 hexfunc = fm.hexfunc
6780 hexfunc = fm.hexfunc
6776 tagtype = ""
6781 tagtype = ""
6777
6782
6778 for t, n in reversed(repo.tagslist()):
6783 for t, n in reversed(repo.tagslist()):
6779 hn = hexfunc(n)
6784 hn = hexfunc(n)
6780 label = 'tags.normal'
6785 label = 'tags.normal'
6781 tagtype = ''
6786 tagtype = ''
6782 if repo.tagtype(t) == 'local':
6787 if repo.tagtype(t) == 'local':
6783 label = 'tags.local'
6788 label = 'tags.local'
6784 tagtype = 'local'
6789 tagtype = 'local'
6785
6790
6786 fm.startitem()
6791 fm.startitem()
6787 fm.write('tag', '%s', t, label=label)
6792 fm.write('tag', '%s', t, label=label)
6788 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6793 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6789 fm.condwrite(not ui.quiet, 'rev node', fmt,
6794 fm.condwrite(not ui.quiet, 'rev node', fmt,
6790 repo.changelog.rev(n), hn, label=label)
6795 repo.changelog.rev(n), hn, label=label)
6791 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6796 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6792 tagtype, label=label)
6797 tagtype, label=label)
6793 fm.plain('\n')
6798 fm.plain('\n')
6794 fm.end()
6799 fm.end()
6795
6800
6796 @command('tip',
6801 @command('tip',
6797 [('p', 'patch', None, _('show patch')),
6802 [('p', 'patch', None, _('show patch')),
6798 ('g', 'git', None, _('use git extended diff format')),
6803 ('g', 'git', None, _('use git extended diff format')),
6799 ] + templateopts,
6804 ] + templateopts,
6800 _('[-p] [-g]'))
6805 _('[-p] [-g]'))
6801 def tip(ui, repo, **opts):
6806 def tip(ui, repo, **opts):
6802 """show the tip revision (DEPRECATED)
6807 """show the tip revision (DEPRECATED)
6803
6808
6804 The tip revision (usually just called the tip) is the changeset
6809 The tip revision (usually just called the tip) is the changeset
6805 most recently added to the repository (and therefore the most
6810 most recently added to the repository (and therefore the most
6806 recently changed head).
6811 recently changed head).
6807
6812
6808 If you have just made a commit, that commit will be the tip. If
6813 If you have just made a commit, that commit will be the tip. If
6809 you have just pulled changes from another repository, the tip of
6814 you have just pulled changes from another repository, the tip of
6810 that repository becomes the current tip. The "tip" tag is special
6815 that repository becomes the current tip. The "tip" tag is special
6811 and cannot be renamed or assigned to a different changeset.
6816 and cannot be renamed or assigned to a different changeset.
6812
6817
6813 This command is deprecated, please use :hg:`heads` instead.
6818 This command is deprecated, please use :hg:`heads` instead.
6814
6819
6815 Returns 0 on success.
6820 Returns 0 on success.
6816 """
6821 """
6817 displayer = cmdutil.show_changeset(ui, repo, opts)
6822 displayer = cmdutil.show_changeset(ui, repo, opts)
6818 displayer.show(repo['tip'])
6823 displayer.show(repo['tip'])
6819 displayer.close()
6824 displayer.close()
6820
6825
6821 @command('unbundle',
6826 @command('unbundle',
6822 [('u', 'update', None,
6827 [('u', 'update', None,
6823 _('update to new branch head if changesets were unbundled'))],
6828 _('update to new branch head if changesets were unbundled'))],
6824 _('[-u] FILE...'))
6829 _('[-u] FILE...'))
6825 def unbundle(ui, repo, fname1, *fnames, **opts):
6830 def unbundle(ui, repo, fname1, *fnames, **opts):
6826 """apply one or more changegroup files
6831 """apply one or more changegroup files
6827
6832
6828 Apply one or more compressed changegroup files generated by the
6833 Apply one or more compressed changegroup files generated by the
6829 bundle command.
6834 bundle command.
6830
6835
6831 Returns 0 on success, 1 if an update has unresolved files.
6836 Returns 0 on success, 1 if an update has unresolved files.
6832 """
6837 """
6833 fnames = (fname1,) + fnames
6838 fnames = (fname1,) + fnames
6834
6839
6835 with repo.lock():
6840 with repo.lock():
6836 for fname in fnames:
6841 for fname in fnames:
6837 f = hg.openpath(ui, fname)
6842 f = hg.openpath(ui, fname)
6838 gen = exchange.readbundle(ui, f, fname)
6843 gen = exchange.readbundle(ui, f, fname)
6839 if isinstance(gen, bundle2.unbundle20):
6844 if isinstance(gen, bundle2.unbundle20):
6840 tr = repo.transaction('unbundle')
6845 tr = repo.transaction('unbundle')
6841 try:
6846 try:
6842 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
6847 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
6843 url='bundle:' + fname)
6848 url='bundle:' + fname)
6844 tr.close()
6849 tr.close()
6845 except error.BundleUnknownFeatureError as exc:
6850 except error.BundleUnknownFeatureError as exc:
6846 raise error.Abort(_('%s: unknown bundle feature, %s')
6851 raise error.Abort(_('%s: unknown bundle feature, %s')
6847 % (fname, exc),
6852 % (fname, exc),
6848 hint=_("see https://mercurial-scm.org/"
6853 hint=_("see https://mercurial-scm.org/"
6849 "wiki/BundleFeature for more "
6854 "wiki/BundleFeature for more "
6850 "information"))
6855 "information"))
6851 finally:
6856 finally:
6852 if tr:
6857 if tr:
6853 tr.release()
6858 tr.release()
6854 changes = [r.get('return', 0)
6859 changes = [r.get('return', 0)
6855 for r in op.records['changegroup']]
6860 for r in op.records['changegroup']]
6856 modheads = changegroup.combineresults(changes)
6861 modheads = changegroup.combineresults(changes)
6857 elif isinstance(gen, streamclone.streamcloneapplier):
6862 elif isinstance(gen, streamclone.streamcloneapplier):
6858 raise error.Abort(
6863 raise error.Abort(
6859 _('packed bundles cannot be applied with '
6864 _('packed bundles cannot be applied with '
6860 '"hg unbundle"'),
6865 '"hg unbundle"'),
6861 hint=_('use "hg debugapplystreamclonebundle"'))
6866 hint=_('use "hg debugapplystreamclonebundle"'))
6862 else:
6867 else:
6863 modheads = gen.apply(repo, 'unbundle', 'bundle:' + fname)
6868 modheads = gen.apply(repo, 'unbundle', 'bundle:' + fname)
6864
6869
6865 return postincoming(ui, repo, modheads, opts.get('update'), None)
6870 return postincoming(ui, repo, modheads, opts.get('update'), None)
6866
6871
6867 @command('^update|up|checkout|co',
6872 @command('^update|up|checkout|co',
6868 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6873 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6869 ('c', 'check', None,
6874 ('c', 'check', None,
6870 _('update across branches if no uncommitted changes')),
6875 _('update across branches if no uncommitted changes')),
6871 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6876 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6872 ('r', 'rev', '', _('revision'), _('REV'))
6877 ('r', 'rev', '', _('revision'), _('REV'))
6873 ] + mergetoolopts,
6878 ] + mergetoolopts,
6874 _('[-c] [-C] [-d DATE] [[-r] REV]'))
6879 _('[-c] [-C] [-d DATE] [[-r] REV]'))
6875 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
6880 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
6876 tool=None):
6881 tool=None):
6877 """update working directory (or switch revisions)
6882 """update working directory (or switch revisions)
6878
6883
6879 Update the repository's working directory to the specified
6884 Update the repository's working directory to the specified
6880 changeset. If no changeset is specified, update to the tip of the
6885 changeset. If no changeset is specified, update to the tip of the
6881 current named branch and move the active bookmark (see :hg:`help
6886 current named branch and move the active bookmark (see :hg:`help
6882 bookmarks`).
6887 bookmarks`).
6883
6888
6884 Update sets the working directory's parent revision to the specified
6889 Update sets the working directory's parent revision to the specified
6885 changeset (see :hg:`help parents`).
6890 changeset (see :hg:`help parents`).
6886
6891
6887 If the changeset is not a descendant or ancestor of the working
6892 If the changeset is not a descendant or ancestor of the working
6888 directory's parent, the update is aborted. With the -c/--check
6893 directory's parent, the update is aborted. With the -c/--check
6889 option, the working directory is checked for uncommitted changes; if
6894 option, the working directory is checked for uncommitted changes; if
6890 none are found, the working directory is updated to the specified
6895 none are found, the working directory is updated to the specified
6891 changeset.
6896 changeset.
6892
6897
6893 .. container:: verbose
6898 .. container:: verbose
6894
6899
6895 The following rules apply when the working directory contains
6900 The following rules apply when the working directory contains
6896 uncommitted changes:
6901 uncommitted changes:
6897
6902
6898 1. If neither -c/--check nor -C/--clean is specified, and if
6903 1. If neither -c/--check nor -C/--clean is specified, and if
6899 the requested changeset is an ancestor or descendant of
6904 the requested changeset is an ancestor or descendant of
6900 the working directory's parent, the uncommitted changes
6905 the working directory's parent, the uncommitted changes
6901 are merged into the requested changeset and the merged
6906 are merged into the requested changeset and the merged
6902 result is left uncommitted. If the requested changeset is
6907 result is left uncommitted. If the requested changeset is
6903 not an ancestor or descendant (that is, it is on another
6908 not an ancestor or descendant (that is, it is on another
6904 branch), the update is aborted and the uncommitted changes
6909 branch), the update is aborted and the uncommitted changes
6905 are preserved.
6910 are preserved.
6906
6911
6907 2. With the -c/--check option, the update is aborted and the
6912 2. With the -c/--check option, the update is aborted and the
6908 uncommitted changes are preserved.
6913 uncommitted changes are preserved.
6909
6914
6910 3. With the -C/--clean option, uncommitted changes are discarded and
6915 3. With the -C/--clean option, uncommitted changes are discarded and
6911 the working directory is updated to the requested changeset.
6916 the working directory is updated to the requested changeset.
6912
6917
6913 To cancel an uncommitted merge (and lose your changes), use
6918 To cancel an uncommitted merge (and lose your changes), use
6914 :hg:`update --clean .`.
6919 :hg:`update --clean .`.
6915
6920
6916 Use null as the changeset to remove the working directory (like
6921 Use null as the changeset to remove the working directory (like
6917 :hg:`clone -U`).
6922 :hg:`clone -U`).
6918
6923
6919 If you want to revert just one file to an older revision, use
6924 If you want to revert just one file to an older revision, use
6920 :hg:`revert [-r REV] NAME`.
6925 :hg:`revert [-r REV] NAME`.
6921
6926
6922 See :hg:`help dates` for a list of formats valid for -d/--date.
6927 See :hg:`help dates` for a list of formats valid for -d/--date.
6923
6928
6924 Returns 0 on success, 1 if there are unresolved files.
6929 Returns 0 on success, 1 if there are unresolved files.
6925 """
6930 """
6926 movemarkfrom = None
6931 movemarkfrom = None
6927 if rev and node:
6932 if rev and node:
6928 raise error.Abort(_("please specify just one revision"))
6933 raise error.Abort(_("please specify just one revision"))
6929
6934
6930 if rev is None or rev == '':
6935 if rev is None or rev == '':
6931 rev = node
6936 rev = node
6932
6937
6933 with repo.wlock():
6938 with repo.wlock():
6934 cmdutil.clearunfinished(repo)
6939 cmdutil.clearunfinished(repo)
6935
6940
6936 if date:
6941 if date:
6937 if rev is not None:
6942 if rev is not None:
6938 raise error.Abort(_("you can't specify a revision and a date"))
6943 raise error.Abort(_("you can't specify a revision and a date"))
6939 rev = cmdutil.finddate(ui, repo, date)
6944 rev = cmdutil.finddate(ui, repo, date)
6940
6945
6941 # if we defined a bookmark, we have to remember the original name
6946 # if we defined a bookmark, we have to remember the original name
6942 brev = rev
6947 brev = rev
6943 rev = scmutil.revsingle(repo, rev, rev).rev()
6948 rev = scmutil.revsingle(repo, rev, rev).rev()
6944
6949
6945 if check and clean:
6950 if check and clean:
6946 raise error.Abort(_("cannot specify both -c/--check and -C/--clean")
6951 raise error.Abort(_("cannot specify both -c/--check and -C/--clean")
6947 )
6952 )
6948
6953
6949 if check:
6954 if check:
6950 cmdutil.bailifchanged(repo, merge=False)
6955 cmdutil.bailifchanged(repo, merge=False)
6951 if rev is None:
6956 if rev is None:
6952 updata = destutil.destupdate(repo, clean=clean, check=check)
6957 updata = destutil.destupdate(repo, clean=clean, check=check)
6953 rev, movemarkfrom, brev = updata
6958 rev, movemarkfrom, brev = updata
6954
6959
6955 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
6960 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
6956
6961
6957 if clean:
6962 if clean:
6958 ret = hg.clean(repo, rev)
6963 ret = hg.clean(repo, rev)
6959 else:
6964 else:
6960 ret = hg.update(repo, rev)
6965 ret = hg.update(repo, rev)
6961
6966
6962 if not ret and movemarkfrom:
6967 if not ret and movemarkfrom:
6963 if movemarkfrom == repo['.'].node():
6968 if movemarkfrom == repo['.'].node():
6964 pass # no-op update
6969 pass # no-op update
6965 elif bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
6970 elif bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
6966 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
6971 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
6967 else:
6972 else:
6968 # this can happen with a non-linear update
6973 # this can happen with a non-linear update
6969 ui.status(_("(leaving bookmark %s)\n") %
6974 ui.status(_("(leaving bookmark %s)\n") %
6970 repo._activebookmark)
6975 repo._activebookmark)
6971 bookmarks.deactivate(repo)
6976 bookmarks.deactivate(repo)
6972 elif brev in repo._bookmarks:
6977 elif brev in repo._bookmarks:
6973 bookmarks.activate(repo, brev)
6978 bookmarks.activate(repo, brev)
6974 ui.status(_("(activating bookmark %s)\n") % brev)
6979 ui.status(_("(activating bookmark %s)\n") % brev)
6975 elif brev:
6980 elif brev:
6976 if repo._activebookmark:
6981 if repo._activebookmark:
6977 ui.status(_("(leaving bookmark %s)\n") %
6982 ui.status(_("(leaving bookmark %s)\n") %
6978 repo._activebookmark)
6983 repo._activebookmark)
6979 bookmarks.deactivate(repo)
6984 bookmarks.deactivate(repo)
6980
6985
6981 return ret
6986 return ret
6982
6987
6983 @command('verify', [])
6988 @command('verify', [])
6984 def verify(ui, repo):
6989 def verify(ui, repo):
6985 """verify the integrity of the repository
6990 """verify the integrity of the repository
6986
6991
6987 Verify the integrity of the current repository.
6992 Verify the integrity of the current repository.
6988
6993
6989 This will perform an extensive check of the repository's
6994 This will perform an extensive check of the repository's
6990 integrity, validating the hashes and checksums of each entry in
6995 integrity, validating the hashes and checksums of each entry in
6991 the changelog, manifest, and tracked files, as well as the
6996 the changelog, manifest, and tracked files, as well as the
6992 integrity of their crosslinks and indices.
6997 integrity of their crosslinks and indices.
6993
6998
6994 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6999 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6995 for more information about recovery from corruption of the
7000 for more information about recovery from corruption of the
6996 repository.
7001 repository.
6997
7002
6998 Returns 0 on success, 1 if errors are encountered.
7003 Returns 0 on success, 1 if errors are encountered.
6999 """
7004 """
7000 return hg.verify(repo)
7005 return hg.verify(repo)
7001
7006
7002 @command('version', [], norepo=True)
7007 @command('version', [], norepo=True)
7003 def version_(ui):
7008 def version_(ui):
7004 """output version and copyright information"""
7009 """output version and copyright information"""
7005 ui.write(_("Mercurial Distributed SCM (version %s)\n")
7010 ui.write(_("Mercurial Distributed SCM (version %s)\n")
7006 % util.version())
7011 % util.version())
7007 ui.status(_(
7012 ui.status(_(
7008 "(see https://mercurial-scm.org for more information)\n"
7013 "(see https://mercurial-scm.org for more information)\n"
7009 "\nCopyright (C) 2005-2015 Matt Mackall and others\n"
7014 "\nCopyright (C) 2005-2015 Matt Mackall and others\n"
7010 "This is free software; see the source for copying conditions. "
7015 "This is free software; see the source for copying conditions. "
7011 "There is NO\nwarranty; "
7016 "There is NO\nwarranty; "
7012 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
7017 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
7013 ))
7018 ))
7014
7019
7015 ui.note(_("\nEnabled extensions:\n\n"))
7020 ui.note(_("\nEnabled extensions:\n\n"))
7016 if ui.verbose:
7021 if ui.verbose:
7017 # format names and versions into columns
7022 # format names and versions into columns
7018 names = []
7023 names = []
7019 vers = []
7024 vers = []
7020 for name, module in extensions.extensions():
7025 for name, module in extensions.extensions():
7021 names.append(name)
7026 names.append(name)
7022 vers.append(extensions.moduleversion(module))
7027 vers.append(extensions.moduleversion(module))
7023 if names:
7028 if names:
7024 maxnamelen = max(len(n) for n in names)
7029 maxnamelen = max(len(n) for n in names)
7025 for i, name in enumerate(names):
7030 for i, name in enumerate(names):
7026 ui.write(" %-*s %s\n" % (maxnamelen, name, vers[i]))
7031 ui.write(" %-*s %s\n" % (maxnamelen, name, vers[i]))
@@ -1,742 +1,742 b''
1 $ hg init basic
1 $ hg init basic
2 $ cd basic
2 $ cd basic
3
3
4 should complain
4 should complain
5
5
6 $ hg backout
6 $ hg backout
7 abort: please specify a revision to backout
7 abort: please specify a revision to backout
8 [255]
8 [255]
9 $ hg backout -r 0 0
9 $ hg backout -r 0 0
10 abort: please specify just one revision
10 abort: please specify just one revision
11 [255]
11 [255]
12
12
13 basic operation
13 basic operation
14 (this also tests that editor is invoked if the commit message is not
14 (this also tests that editor is invoked if the commit message is not
15 specified explicitly)
15 specified explicitly)
16
16
17 $ echo a > a
17 $ echo a > a
18 $ hg commit -d '0 0' -A -m a
18 $ hg commit -d '0 0' -A -m a
19 adding a
19 adding a
20 $ echo b >> a
20 $ echo b >> a
21 $ hg commit -d '1 0' -m b
21 $ hg commit -d '1 0' -m b
22
22
23 $ hg status --rev tip --rev "tip^1"
23 $ hg status --rev tip --rev "tip^1"
24 M a
24 M a
25 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true
25 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true
26 reverting a
26 reverting a
27 Backed out changeset a820f4f40a57
27 Backed out changeset a820f4f40a57
28
28
29
29
30 HG: Enter commit message. Lines beginning with 'HG:' are removed.
30 HG: Enter commit message. Lines beginning with 'HG:' are removed.
31 HG: Leave message empty to abort commit.
31 HG: Leave message empty to abort commit.
32 HG: --
32 HG: --
33 HG: user: test
33 HG: user: test
34 HG: branch 'default'
34 HG: branch 'default'
35 HG: changed a
35 HG: changed a
36 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
36 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
37 $ cat a
37 $ cat a
38 a
38 a
39 $ hg summary
39 $ hg summary
40 parent: 2:2929462c3dff tip
40 parent: 2:2929462c3dff tip
41 Backed out changeset a820f4f40a57
41 Backed out changeset a820f4f40a57
42 branch: default
42 branch: default
43 commit: (clean)
43 commit: (clean)
44 update: (current)
44 update: (current)
45 phases: 3 draft
45 phases: 3 draft
46
46
47 commit option
47 commit option
48
48
49 $ cd ..
49 $ cd ..
50 $ hg init commit
50 $ hg init commit
51 $ cd commit
51 $ cd commit
52
52
53 $ echo tomatoes > a
53 $ echo tomatoes > a
54 $ hg add a
54 $ hg add a
55 $ hg commit -d '0 0' -m tomatoes
55 $ hg commit -d '0 0' -m tomatoes
56
56
57 $ echo chair > b
57 $ echo chair > b
58 $ hg add b
58 $ hg add b
59 $ hg commit -d '1 0' -m chair
59 $ hg commit -d '1 0' -m chair
60
60
61 $ echo grapes >> a
61 $ echo grapes >> a
62 $ hg commit -d '2 0' -m grapes
62 $ hg commit -d '2 0' -m grapes
63
63
64 $ hg backout --commit -d '4 0' 1 --tool=:fail
64 $ hg backout -d '4 0' 1 --tool=:fail
65 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
65 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
66 changeset 3:1c2161e97c0a backs out changeset 1:22cb4f70d813
66 changeset 3:1c2161e97c0a backs out changeset 1:22cb4f70d813
67 $ hg summary
67 $ hg summary
68 parent: 3:1c2161e97c0a tip
68 parent: 3:1c2161e97c0a tip
69 Backed out changeset 22cb4f70d813
69 Backed out changeset 22cb4f70d813
70 branch: default
70 branch: default
71 commit: (clean)
71 commit: (clean)
72 update: (current)
72 update: (current)
73 phases: 4 draft
73 phases: 4 draft
74
74
75 $ echo ypples > a
75 $ echo ypples > a
76 $ hg commit -d '5 0' -m ypples
76 $ hg commit -d '5 0' -m ypples
77
77
78 $ hg backout --commit -d '6 0' 2 --tool=:fail
78 $ hg backout -d '6 0' 2 --tool=:fail
79 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
79 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
80 use 'hg resolve' to retry unresolved file merges
80 use 'hg resolve' to retry unresolved file merges
81 [1]
81 [1]
82 $ hg summary
82 $ hg summary
83 parent: 4:ed99997b793d tip
83 parent: 4:ed99997b793d tip
84 ypples
84 ypples
85 branch: default
85 branch: default
86 commit: 1 unresolved (clean)
86 commit: 1 unresolved (clean)
87 update: (current)
87 update: (current)
88 phases: 5 draft
88 phases: 5 draft
89
89
90 file that was removed is recreated
90 file that was removed is recreated
91 (this also tests that editor is not invoked if the commit message is
91 (this also tests that editor is not invoked if the commit message is
92 specified explicitly)
92 specified explicitly)
93
93
94 $ cd ..
94 $ cd ..
95 $ hg init remove
95 $ hg init remove
96 $ cd remove
96 $ cd remove
97
97
98 $ echo content > a
98 $ echo content > a
99 $ hg commit -d '0 0' -A -m a
99 $ hg commit -d '0 0' -A -m a
100 adding a
100 adding a
101
101
102 $ hg rm a
102 $ hg rm a
103 $ hg commit -d '1 0' -m b
103 $ hg commit -d '1 0' -m b
104
104
105 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true -m "Backed out changeset 76862dcce372"
105 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true -m "Backed out changeset 76862dcce372"
106 adding a
106 adding a
107 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
107 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
108 $ cat a
108 $ cat a
109 content
109 content
110 $ hg summary
110 $ hg summary
111 parent: 2:de31bdc76c0d tip
111 parent: 2:de31bdc76c0d tip
112 Backed out changeset 76862dcce372
112 Backed out changeset 76862dcce372
113 branch: default
113 branch: default
114 commit: (clean)
114 commit: (clean)
115 update: (current)
115 update: (current)
116 phases: 3 draft
116 phases: 3 draft
117
117
118 backout of backout is as if nothing happened
118 backout of backout is as if nothing happened
119
119
120 $ hg backout -d '3 0' --merge tip --tool=true
120 $ hg backout -d '3 0' --merge tip --tool=true
121 removing a
121 removing a
122 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
122 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
123 $ test -f a
123 $ test -f a
124 [1]
124 [1]
125 $ hg summary
125 $ hg summary
126 parent: 3:7f6d0f120113 tip
126 parent: 3:7f6d0f120113 tip
127 Backed out changeset de31bdc76c0d
127 Backed out changeset de31bdc76c0d
128 branch: default
128 branch: default
129 commit: (clean)
129 commit: (clean)
130 update: (current)
130 update: (current)
131 phases: 4 draft
131 phases: 4 draft
132
132
133 Test that 'hg rollback' restores dirstate just before opening
133 Test that 'hg rollback' restores dirstate just before opening
134 transaction: in-memory dirstate changes should be written into
134 transaction: in-memory dirstate changes should be written into
135 '.hg/journal.dirstate' as expected.
135 '.hg/journal.dirstate' as expected.
136
136
137 $ echo 'removed soon' > b
137 $ echo 'removed soon' > b
138 $ hg commit -A -d '4 0' -m 'prepare for subsequent removing'
138 $ hg commit -A -d '4 0' -m 'prepare for subsequent removing'
139 adding b
139 adding b
140 $ echo 'newly added' > c
140 $ echo 'newly added' > c
141 $ hg add c
141 $ hg add c
142 $ hg remove b
142 $ hg remove b
143 $ hg commit -d '5 0' -m 'prepare for subsequent backout'
143 $ hg commit -d '5 0' -m 'prepare for subsequent backout'
144 $ touch -t 200001010000 c
144 $ touch -t 200001010000 c
145 $ hg status -A
145 $ hg status -A
146 C c
146 C c
147 $ hg debugstate --nodates
147 $ hg debugstate --nodates
148 n 644 12 set c
148 n 644 12 set c
149 $ hg backout -d '6 0' -m 'to be rollback-ed soon' -r .
149 $ hg backout -d '6 0' -m 'to be rollback-ed soon' -r .
150 adding b
150 adding b
151 removing c
151 removing c
152 changeset 6:4bfec048029d backs out changeset 5:fac0b729a654
152 changeset 6:4bfec048029d backs out changeset 5:fac0b729a654
153 $ hg rollback -q
153 $ hg rollback -q
154 $ hg status -A
154 $ hg status -A
155 A b
155 A b
156 R c
156 R c
157 $ hg debugstate --nodates
157 $ hg debugstate --nodates
158 a 0 -1 unset b
158 a 0 -1 unset b
159 r 0 0 set c
159 r 0 0 set c
160
160
161 across branch
161 across branch
162
162
163 $ cd ..
163 $ cd ..
164 $ hg init branch
164 $ hg init branch
165 $ cd branch
165 $ cd branch
166 $ echo a > a
166 $ echo a > a
167 $ hg ci -Am0
167 $ hg ci -Am0
168 adding a
168 adding a
169 $ echo b > b
169 $ echo b > b
170 $ hg ci -Am1
170 $ hg ci -Am1
171 adding b
171 adding b
172 $ hg co -C 0
172 $ hg co -C 0
173 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
173 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
174 $ hg summary
174 $ hg summary
175 parent: 0:f7b1eb17ad24
175 parent: 0:f7b1eb17ad24
176 0
176 0
177 branch: default
177 branch: default
178 commit: (clean)
178 commit: (clean)
179 update: 1 new changesets (update)
179 update: 1 new changesets (update)
180 phases: 2 draft
180 phases: 2 draft
181
181
182 should fail
182 should fail
183
183
184 $ hg backout 1
184 $ hg backout 1
185 abort: cannot backout change that is not an ancestor
185 abort: cannot backout change that is not an ancestor
186 [255]
186 [255]
187 $ echo c > c
187 $ echo c > c
188 $ hg ci -Am2
188 $ hg ci -Am2
189 adding c
189 adding c
190 created new head
190 created new head
191 $ hg summary
191 $ hg summary
192 parent: 2:db815d6d32e6 tip
192 parent: 2:db815d6d32e6 tip
193 2
193 2
194 branch: default
194 branch: default
195 commit: (clean)
195 commit: (clean)
196 update: 1 new changesets, 2 branch heads (merge)
196 update: 1 new changesets, 2 branch heads (merge)
197 phases: 3 draft
197 phases: 3 draft
198
198
199 should fail
199 should fail
200
200
201 $ hg backout 1
201 $ hg backout 1
202 abort: cannot backout change that is not an ancestor
202 abort: cannot backout change that is not an ancestor
203 [255]
203 [255]
204 $ hg summary
204 $ hg summary
205 parent: 2:db815d6d32e6 tip
205 parent: 2:db815d6d32e6 tip
206 2
206 2
207 branch: default
207 branch: default
208 commit: (clean)
208 commit: (clean)
209 update: 1 new changesets, 2 branch heads (merge)
209 update: 1 new changesets, 2 branch heads (merge)
210 phases: 3 draft
210 phases: 3 draft
211
211
212 backout with merge
212 backout with merge
213
213
214 $ cd ..
214 $ cd ..
215 $ hg init merge
215 $ hg init merge
216 $ cd merge
216 $ cd merge
217
217
218 $ echo line 1 > a
218 $ echo line 1 > a
219 $ echo line 2 >> a
219 $ echo line 2 >> a
220 $ hg commit -d '0 0' -A -m a
220 $ hg commit -d '0 0' -A -m a
221 adding a
221 adding a
222 $ hg summary
222 $ hg summary
223 parent: 0:59395513a13a tip
223 parent: 0:59395513a13a tip
224 a
224 a
225 branch: default
225 branch: default
226 commit: (clean)
226 commit: (clean)
227 update: (current)
227 update: (current)
228 phases: 1 draft
228 phases: 1 draft
229
229
230 remove line 1
230 remove line 1
231
231
232 $ echo line 2 > a
232 $ echo line 2 > a
233 $ hg commit -d '1 0' -m b
233 $ hg commit -d '1 0' -m b
234
234
235 $ echo line 3 >> a
235 $ echo line 3 >> a
236 $ hg commit -d '2 0' -m c
236 $ hg commit -d '2 0' -m c
237
237
238 $ hg backout --merge -d '3 0' 1 --tool=true
238 $ hg backout --merge -d '3 0' 1 --tool=true
239 reverting a
239 reverting a
240 created new head
240 created new head
241 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
241 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
242 merging with changeset 3:26b8ccb9ad91
242 merging with changeset 3:26b8ccb9ad91
243 merging a
243 merging a
244 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
244 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
245 (branch merge, don't forget to commit)
245 (branch merge, don't forget to commit)
246 $ hg commit -d '4 0' -m d
246 $ hg commit -d '4 0' -m d
247 $ hg summary
247 $ hg summary
248 parent: 4:c7df5e0b9c09 tip
248 parent: 4:c7df5e0b9c09 tip
249 d
249 d
250 branch: default
250 branch: default
251 commit: (clean)
251 commit: (clean)
252 update: (current)
252 update: (current)
253 phases: 5 draft
253 phases: 5 draft
254
254
255 check line 1 is back
255 check line 1 is back
256
256
257 $ cat a
257 $ cat a
258 line 1
258 line 1
259 line 2
259 line 2
260 line 3
260 line 3
261
261
262 Test visibility of in-memory dirstate changes outside transaction to
262 Test visibility of in-memory dirstate changes outside transaction to
263 external hook process
263 external hook process
264
264
265 $ cat > $TESTTMP/checkvisibility.sh <<EOF
265 $ cat > $TESTTMP/checkvisibility.sh <<EOF
266 > echo "==== \$1:"
266 > echo "==== \$1:"
267 > hg parents --template "{rev}:{node|short}\n"
267 > hg parents --template "{rev}:{node|short}\n"
268 > echo "===="
268 > echo "===="
269 > EOF
269 > EOF
270
270
271 "hg backout --merge REV1" at REV2 below implies steps below:
271 "hg backout --merge REV1" at REV2 below implies steps below:
272
272
273 (1) update to REV1 (REV2 => REV1)
273 (1) update to REV1 (REV2 => REV1)
274 (2) revert by REV1^1
274 (2) revert by REV1^1
275 (3) commit backnig out revision (REV3)
275 (3) commit backnig out revision (REV3)
276 (4) update to REV2 (REV3 => REV2)
276 (4) update to REV2 (REV3 => REV2)
277 (5) merge with REV3 (REV2 => REV2, REV3)
277 (5) merge with REV3 (REV2 => REV2, REV3)
278
278
279 == test visibility to external preupdate hook
279 == test visibility to external preupdate hook
280
280
281 $ hg update -q -C 2
281 $ hg update -q -C 2
282 $ hg --config extensions.strip= strip 3
282 $ hg --config extensions.strip= strip 3
283 saved backup bundle to * (glob)
283 saved backup bundle to * (glob)
284
284
285 $ cat >> .hg/hgrc <<EOF
285 $ cat >> .hg/hgrc <<EOF
286 > [hooks]
286 > [hooks]
287 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
287 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
288 > EOF
288 > EOF
289
289
290 ("-m" is needed to avoid writing dirstte changes out at other than
290 ("-m" is needed to avoid writing dirstte changes out at other than
291 invocation of the hook to be examined)
291 invocation of the hook to be examined)
292
292
293 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
293 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
294 ==== preupdate:
294 ==== preupdate:
295 2:6ea3f2a197a2
295 2:6ea3f2a197a2
296 ====
296 ====
297 reverting a
297 reverting a
298 created new head
298 created new head
299 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
299 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
300 ==== preupdate:
300 ==== preupdate:
301 3:d92a3f57f067
301 3:d92a3f57f067
302 ====
302 ====
303 merging with changeset 3:d92a3f57f067
303 merging with changeset 3:d92a3f57f067
304 ==== preupdate:
304 ==== preupdate:
305 2:6ea3f2a197a2
305 2:6ea3f2a197a2
306 ====
306 ====
307 merging a
307 merging a
308 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
308 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
309 (branch merge, don't forget to commit)
309 (branch merge, don't forget to commit)
310
310
311 $ cat >> .hg/hgrc <<EOF
311 $ cat >> .hg/hgrc <<EOF
312 > [hooks]
312 > [hooks]
313 > preupdate.visibility =
313 > preupdate.visibility =
314 > EOF
314 > EOF
315
315
316 == test visibility to external update hook
316 == test visibility to external update hook
317
317
318 $ hg update -q -C 2
318 $ hg update -q -C 2
319 $ hg --config extensions.strip= strip 3
319 $ hg --config extensions.strip= strip 3
320 saved backup bundle to * (glob)
320 saved backup bundle to * (glob)
321
321
322 $ cat >> .hg/hgrc <<EOF
322 $ cat >> .hg/hgrc <<EOF
323 > [hooks]
323 > [hooks]
324 > update.visibility = sh $TESTTMP/checkvisibility.sh update
324 > update.visibility = sh $TESTTMP/checkvisibility.sh update
325 > EOF
325 > EOF
326
326
327 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
327 $ hg backout --merge -d '3 0' 1 --tool=true -m 'fixed comment'
328 ==== update:
328 ==== update:
329 1:5a50a024c182
329 1:5a50a024c182
330 ====
330 ====
331 reverting a
331 reverting a
332 created new head
332 created new head
333 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
333 changeset 3:d92a3f57f067 backs out changeset 1:5a50a024c182
334 ==== update:
334 ==== update:
335 2:6ea3f2a197a2
335 2:6ea3f2a197a2
336 ====
336 ====
337 merging with changeset 3:d92a3f57f067
337 merging with changeset 3:d92a3f57f067
338 merging a
338 merging a
339 ==== update:
339 ==== update:
340 2:6ea3f2a197a2
340 2:6ea3f2a197a2
341 3:d92a3f57f067
341 3:d92a3f57f067
342 ====
342 ====
343 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
343 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
344 (branch merge, don't forget to commit)
344 (branch merge, don't forget to commit)
345
345
346 $ cat >> .hg/hgrc <<EOF
346 $ cat >> .hg/hgrc <<EOF
347 > [hooks]
347 > [hooks]
348 > update.visibility =
348 > update.visibility =
349 > EOF
349 > EOF
350
350
351 $ cd ..
351 $ cd ..
352
352
353 backout should not back out subsequent changesets
353 backout should not back out subsequent changesets
354
354
355 $ hg init onecs
355 $ hg init onecs
356 $ cd onecs
356 $ cd onecs
357 $ echo 1 > a
357 $ echo 1 > a
358 $ hg commit -d '0 0' -A -m a
358 $ hg commit -d '0 0' -A -m a
359 adding a
359 adding a
360 $ echo 2 >> a
360 $ echo 2 >> a
361 $ hg commit -d '1 0' -m b
361 $ hg commit -d '1 0' -m b
362 $ echo 1 > b
362 $ echo 1 > b
363 $ hg commit -d '2 0' -A -m c
363 $ hg commit -d '2 0' -A -m c
364 adding b
364 adding b
365 $ hg summary
365 $ hg summary
366 parent: 2:882396649954 tip
366 parent: 2:882396649954 tip
367 c
367 c
368 branch: default
368 branch: default
369 commit: (clean)
369 commit: (clean)
370 update: (current)
370 update: (current)
371 phases: 3 draft
371 phases: 3 draft
372
372
373 without --merge
373 without --merge
374 $ hg backout -d '3 0' 1 --tool=true
374 $ hg backout --no-commit -d '3 0' 1 --tool=true
375 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
375 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 changeset 22bca4c721e5 backed out, don't forget to commit.
376 changeset 22bca4c721e5 backed out, don't forget to commit.
377 $ hg locate b
377 $ hg locate b
378 b
378 b
379 $ hg update -C tip
379 $ hg update -C tip
380 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
380 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
381 $ hg locate b
381 $ hg locate b
382 b
382 b
383 $ hg summary
383 $ hg summary
384 parent: 2:882396649954 tip
384 parent: 2:882396649954 tip
385 c
385 c
386 branch: default
386 branch: default
387 commit: (clean)
387 commit: (clean)
388 update: (current)
388 update: (current)
389 phases: 3 draft
389 phases: 3 draft
390
390
391 with --merge
391 with --merge
392 $ hg backout --merge -d '3 0' 1 --tool=true
392 $ hg backout --merge -d '3 0' 1 --tool=true
393 reverting a
393 reverting a
394 created new head
394 created new head
395 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
395 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
396 merging with changeset 3:3202beb76721
396 merging with changeset 3:3202beb76721
397 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
397 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
398 (branch merge, don't forget to commit)
398 (branch merge, don't forget to commit)
399 $ hg locate b
399 $ hg locate b
400 b
400 b
401 $ hg update -C tip
401 $ hg update -C tip
402 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
402 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
403 $ hg locate b
403 $ hg locate b
404 [1]
404 [1]
405
405
406 $ cd ..
406 $ cd ..
407 $ hg init m
407 $ hg init m
408 $ cd m
408 $ cd m
409 $ echo a > a
409 $ echo a > a
410 $ hg commit -d '0 0' -A -m a
410 $ hg commit -d '0 0' -A -m a
411 adding a
411 adding a
412 $ echo b > b
412 $ echo b > b
413 $ hg commit -d '1 0' -A -m b
413 $ hg commit -d '1 0' -A -m b
414 adding b
414 adding b
415 $ echo c > c
415 $ echo c > c
416 $ hg commit -d '2 0' -A -m b
416 $ hg commit -d '2 0' -A -m b
417 adding c
417 adding c
418 $ hg update 1
418 $ hg update 1
419 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
419 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
420 $ echo d > d
420 $ echo d > d
421 $ hg commit -d '3 0' -A -m c
421 $ hg commit -d '3 0' -A -m c
422 adding d
422 adding d
423 created new head
423 created new head
424 $ hg merge 2
424 $ hg merge 2
425 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
425 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
426 (branch merge, don't forget to commit)
426 (branch merge, don't forget to commit)
427 $ hg commit -d '4 0' -A -m d
427 $ hg commit -d '4 0' -A -m d
428 $ hg summary
428 $ hg summary
429 parent: 4:b2f3bb92043e tip
429 parent: 4:b2f3bb92043e tip
430 d
430 d
431 branch: default
431 branch: default
432 commit: (clean)
432 commit: (clean)
433 update: (current)
433 update: (current)
434 phases: 5 draft
434 phases: 5 draft
435
435
436 backout of merge should fail
436 backout of merge should fail
437
437
438 $ hg backout 4
438 $ hg backout 4
439 abort: cannot backout a merge changeset
439 abort: cannot backout a merge changeset
440 [255]
440 [255]
441
441
442 backout of merge with bad parent should fail
442 backout of merge with bad parent should fail
443
443
444 $ hg backout --parent 0 4
444 $ hg backout --parent 0 4
445 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
445 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
446 [255]
446 [255]
447
447
448 backout of non-merge with parent should fail
448 backout of non-merge with parent should fail
449
449
450 $ hg backout --parent 0 3
450 $ hg backout --parent 0 3
451 abort: cannot use --parent on non-merge changeset
451 abort: cannot use --parent on non-merge changeset
452 [255]
452 [255]
453
453
454 backout with valid parent should be ok
454 backout with valid parent should be ok
455
455
456 $ hg backout -d '5 0' --parent 2 4 --tool=true
456 $ hg backout -d '5 0' --parent 2 4 --tool=true
457 removing d
457 removing d
458 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
458 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
459 $ hg summary
459 $ hg summary
460 parent: 5:10e5328c8435 tip
460 parent: 5:10e5328c8435 tip
461 Backed out changeset b2f3bb92043e
461 Backed out changeset b2f3bb92043e
462 branch: default
462 branch: default
463 commit: (clean)
463 commit: (clean)
464 update: (current)
464 update: (current)
465 phases: 6 draft
465 phases: 6 draft
466
466
467 $ hg rollback
467 $ hg rollback
468 repository tip rolled back to revision 4 (undo commit)
468 repository tip rolled back to revision 4 (undo commit)
469 working directory now based on revision 4
469 working directory now based on revision 4
470 $ hg update -C
470 $ hg update -C
471 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
471 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
472 $ hg summary
472 $ hg summary
473 parent: 4:b2f3bb92043e tip
473 parent: 4:b2f3bb92043e tip
474 d
474 d
475 branch: default
475 branch: default
476 commit: (clean)
476 commit: (clean)
477 update: (current)
477 update: (current)
478 phases: 5 draft
478 phases: 5 draft
479
479
480 $ hg backout -d '6 0' --parent 3 4 --tool=true
480 $ hg backout -d '6 0' --parent 3 4 --tool=true
481 removing c
481 removing c
482 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
482 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
483 $ hg summary
483 $ hg summary
484 parent: 5:033590168430 tip
484 parent: 5:033590168430 tip
485 Backed out changeset b2f3bb92043e
485 Backed out changeset b2f3bb92043e
486 branch: default
486 branch: default
487 commit: (clean)
487 commit: (clean)
488 update: (current)
488 update: (current)
489 phases: 6 draft
489 phases: 6 draft
490
490
491 $ cd ..
491 $ cd ..
492
492
493 named branches
493 named branches
494
494
495 $ hg init named_branches
495 $ hg init named_branches
496 $ cd named_branches
496 $ cd named_branches
497
497
498 $ echo default > default
498 $ echo default > default
499 $ hg ci -d '0 0' -Am default
499 $ hg ci -d '0 0' -Am default
500 adding default
500 adding default
501 $ hg branch branch1
501 $ hg branch branch1
502 marked working directory as branch branch1
502 marked working directory as branch branch1
503 (branches are permanent and global, did you want a bookmark?)
503 (branches are permanent and global, did you want a bookmark?)
504 $ echo branch1 > file1
504 $ echo branch1 > file1
505 $ hg ci -d '1 0' -Am file1
505 $ hg ci -d '1 0' -Am file1
506 adding file1
506 adding file1
507 $ hg branch branch2
507 $ hg branch branch2
508 marked working directory as branch branch2
508 marked working directory as branch branch2
509 $ echo branch2 > file2
509 $ echo branch2 > file2
510 $ hg ci -d '2 0' -Am file2
510 $ hg ci -d '2 0' -Am file2
511 adding file2
511 adding file2
512
512
513 without --merge
513 without --merge
514 $ hg backout -r 1 --tool=true
514 $ hg backout --no-commit -r 1 --tool=true
515 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
515 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
516 changeset bf1602f437f3 backed out, don't forget to commit.
516 changeset bf1602f437f3 backed out, don't forget to commit.
517 $ hg branch
517 $ hg branch
518 branch2
518 branch2
519 $ hg status -A
519 $ hg status -A
520 R file1
520 R file1
521 C default
521 C default
522 C file2
522 C file2
523 $ hg summary
523 $ hg summary
524 parent: 2:45bbcd363bf0 tip
524 parent: 2:45bbcd363bf0 tip
525 file2
525 file2
526 branch: branch2
526 branch: branch2
527 commit: 1 removed
527 commit: 1 removed
528 update: (current)
528 update: (current)
529 phases: 3 draft
529 phases: 3 draft
530
530
531 with --merge
531 with --merge
532 (this also tests that editor is invoked if '--edit' is specified
532 (this also tests that editor is invoked if '--edit' is specified
533 explicitly regardless of '--message')
533 explicitly regardless of '--message')
534
534
535 $ hg update -qC
535 $ hg update -qC
536 $ HGEDITOR=cat hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true --edit
536 $ HGEDITOR=cat hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true --edit
537 removing file1
537 removing file1
538 backout on branch1
538 backout on branch1
539
539
540
540
541 HG: Enter commit message. Lines beginning with 'HG:' are removed.
541 HG: Enter commit message. Lines beginning with 'HG:' are removed.
542 HG: Leave message empty to abort commit.
542 HG: Leave message empty to abort commit.
543 HG: --
543 HG: --
544 HG: user: test
544 HG: user: test
545 HG: branch 'branch2'
545 HG: branch 'branch2'
546 HG: removed file1
546 HG: removed file1
547 created new head
547 created new head
548 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
548 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
549 merging with changeset 3:d4e8f6db59fb
549 merging with changeset 3:d4e8f6db59fb
550 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
550 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
551 (branch merge, don't forget to commit)
551 (branch merge, don't forget to commit)
552 $ hg summary
552 $ hg summary
553 parent: 2:45bbcd363bf0
553 parent: 2:45bbcd363bf0
554 file2
554 file2
555 parent: 3:d4e8f6db59fb tip
555 parent: 3:d4e8f6db59fb tip
556 backout on branch1
556 backout on branch1
557 branch: branch2
557 branch: branch2
558 commit: 1 removed (merge)
558 commit: 1 removed (merge)
559 update: (current)
559 update: (current)
560 phases: 4 draft
560 phases: 4 draft
561 $ hg update -q -C 2
561 $ hg update -q -C 2
562
562
563 on branch2 with branch1 not merged, so file1 should still exist:
563 on branch2 with branch1 not merged, so file1 should still exist:
564
564
565 $ hg id
565 $ hg id
566 45bbcd363bf0 (branch2)
566 45bbcd363bf0 (branch2)
567 $ hg st -A
567 $ hg st -A
568 C default
568 C default
569 C file1
569 C file1
570 C file2
570 C file2
571 $ hg summary
571 $ hg summary
572 parent: 2:45bbcd363bf0
572 parent: 2:45bbcd363bf0
573 file2
573 file2
574 branch: branch2
574 branch: branch2
575 commit: (clean)
575 commit: (clean)
576 update: 1 new changesets, 2 branch heads (merge)
576 update: 1 new changesets, 2 branch heads (merge)
577 phases: 4 draft
577 phases: 4 draft
578
578
579 on branch2 with branch1 merged, so file1 should be gone:
579 on branch2 with branch1 merged, so file1 should be gone:
580
580
581 $ hg merge
581 $ hg merge
582 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
582 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
583 (branch merge, don't forget to commit)
583 (branch merge, don't forget to commit)
584 $ hg ci -d '4 0' -m 'merge backout of branch1'
584 $ hg ci -d '4 0' -m 'merge backout of branch1'
585 $ hg id
585 $ hg id
586 22149cdde76d (branch2) tip
586 22149cdde76d (branch2) tip
587 $ hg st -A
587 $ hg st -A
588 C default
588 C default
589 C file2
589 C file2
590 $ hg summary
590 $ hg summary
591 parent: 4:22149cdde76d tip
591 parent: 4:22149cdde76d tip
592 merge backout of branch1
592 merge backout of branch1
593 branch: branch2
593 branch: branch2
594 commit: (clean)
594 commit: (clean)
595 update: (current)
595 update: (current)
596 phases: 5 draft
596 phases: 5 draft
597
597
598 on branch1, so no file1 and file2:
598 on branch1, so no file1 and file2:
599
599
600 $ hg co -C branch1
600 $ hg co -C branch1
601 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
601 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
602 $ hg id
602 $ hg id
603 bf1602f437f3 (branch1)
603 bf1602f437f3 (branch1)
604 $ hg st -A
604 $ hg st -A
605 C default
605 C default
606 C file1
606 C file1
607 $ hg summary
607 $ hg summary
608 parent: 1:bf1602f437f3
608 parent: 1:bf1602f437f3
609 file1
609 file1
610 branch: branch1
610 branch: branch1
611 commit: (clean)
611 commit: (clean)
612 update: (current)
612 update: (current)
613 phases: 5 draft
613 phases: 5 draft
614
614
615 $ cd ..
615 $ cd ..
616
616
617 backout of empty changeset (issue4190)
617 backout of empty changeset (issue4190)
618
618
619 $ hg init emptycommit
619 $ hg init emptycommit
620 $ cd emptycommit
620 $ cd emptycommit
621
621
622 $ touch file1
622 $ touch file1
623 $ hg ci -Aqm file1
623 $ hg ci -Aqm file1
624 $ hg branch -q branch1
624 $ hg branch -q branch1
625 $ hg ci -qm branch1
625 $ hg ci -qm branch1
626 $ hg backout -v 1
626 $ hg backout -v 1
627 resolving manifests
627 resolving manifests
628 nothing changed
628 nothing changed
629 [1]
629 [1]
630
630
631 $ cd ..
631 $ cd ..
632
632
633
633
634 Test usage of `hg resolve` in case of conflict
634 Test usage of `hg resolve` in case of conflict
635 (issue4163)
635 (issue4163)
636
636
637 $ hg init issue4163
637 $ hg init issue4163
638 $ cd issue4163
638 $ cd issue4163
639 $ touch foo
639 $ touch foo
640 $ hg add foo
640 $ hg add foo
641 $ cat > foo << EOF
641 $ cat > foo << EOF
642 > one
642 > one
643 > two
643 > two
644 > three
644 > three
645 > four
645 > four
646 > five
646 > five
647 > six
647 > six
648 > seven
648 > seven
649 > height
649 > height
650 > nine
650 > nine
651 > ten
651 > ten
652 > EOF
652 > EOF
653 $ hg ci -m 'initial'
653 $ hg ci -m 'initial'
654 $ cat > foo << EOF
654 $ cat > foo << EOF
655 > one
655 > one
656 > two
656 > two
657 > THREE
657 > THREE
658 > four
658 > four
659 > five
659 > five
660 > six
660 > six
661 > seven
661 > seven
662 > height
662 > height
663 > nine
663 > nine
664 > ten
664 > ten
665 > EOF
665 > EOF
666 $ hg ci -m 'capital three'
666 $ hg ci -m 'capital three'
667 $ cat > foo << EOF
667 $ cat > foo << EOF
668 > one
668 > one
669 > two
669 > two
670 > THREE
670 > THREE
671 > four
671 > four
672 > five
672 > five
673 > six
673 > six
674 > seven
674 > seven
675 > height
675 > height
676 > nine
676 > nine
677 > TEN
677 > TEN
678 > EOF
678 > EOF
679 $ hg ci -m 'capital ten'
679 $ hg ci -m 'capital ten'
680 $ hg backout -r 'desc("capital three")' --tool internal:fail
680 $ hg backout -r 'desc("capital three")' --tool internal:fail
681 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
681 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
682 use 'hg resolve' to retry unresolved file merges
682 use 'hg resolve' to retry unresolved file merges
683 [1]
683 [1]
684 $ hg status
684 $ hg status
685 $ hg debugmergestate
685 $ hg debugmergestate
686 * version 2 records
686 * version 2 records
687 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
687 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
688 other: a30dd8addae3ce71b8667868478542bc417439e6
688 other: a30dd8addae3ce71b8667868478542bc417439e6
689 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
689 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
690 local path: foo (flags "")
690 local path: foo (flags "")
691 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
691 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
692 other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
692 other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
693 $ mv .hg/merge/state2 .hg/merge/state2-moved
693 $ mv .hg/merge/state2 .hg/merge/state2-moved
694 $ hg debugmergestate
694 $ hg debugmergestate
695 * version 1 records
695 * version 1 records
696 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
696 local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
697 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
697 file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
698 local path: foo (flags "")
698 local path: foo (flags "")
699 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
699 ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
700 other path: foo (node not stored in v1 format)
700 other path: foo (node not stored in v1 format)
701 $ mv .hg/merge/state2-moved .hg/merge/state2
701 $ mv .hg/merge/state2-moved .hg/merge/state2
702 $ hg resolve -l # still unresolved
702 $ hg resolve -l # still unresolved
703 U foo
703 U foo
704 $ hg summary
704 $ hg summary
705 parent: 2:b71750c4b0fd tip
705 parent: 2:b71750c4b0fd tip
706 capital ten
706 capital ten
707 branch: default
707 branch: default
708 commit: 1 unresolved (clean)
708 commit: 1 unresolved (clean)
709 update: (current)
709 update: (current)
710 phases: 3 draft
710 phases: 3 draft
711 $ hg resolve --all --debug
711 $ hg resolve --all --debug
712 picked tool ':merge' for foo (binary False symlink False changedelete False)
712 picked tool ':merge' for foo (binary False symlink False changedelete False)
713 merging foo
713 merging foo
714 my foo@b71750c4b0fd+ other foo@a30dd8addae3 ancestor foo@913609522437
714 my foo@b71750c4b0fd+ other foo@a30dd8addae3 ancestor foo@913609522437
715 premerge successful
715 premerge successful
716 (no more unresolved files)
716 (no more unresolved files)
717 continue: hg commit
717 continue: hg commit
718 $ hg status
718 $ hg status
719 M foo
719 M foo
720 ? foo.orig
720 ? foo.orig
721 $ hg resolve -l
721 $ hg resolve -l
722 R foo
722 R foo
723 $ hg summary
723 $ hg summary
724 parent: 2:b71750c4b0fd tip
724 parent: 2:b71750c4b0fd tip
725 capital ten
725 capital ten
726 branch: default
726 branch: default
727 commit: 1 modified, 1 unknown
727 commit: 1 modified, 1 unknown
728 update: (current)
728 update: (current)
729 phases: 3 draft
729 phases: 3 draft
730 $ cat foo
730 $ cat foo
731 one
731 one
732 two
732 two
733 three
733 three
734 four
734 four
735 five
735 five
736 six
736 six
737 seven
737 seven
738 height
738 height
739 nine
739 nine
740 TEN
740 TEN
741
741
742
742
@@ -1,350 +1,350 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 add
3 add
4 addremove
4 addremove
5 annotate
5 annotate
6 archive
6 archive
7 backout
7 backout
8 bisect
8 bisect
9 bookmarks
9 bookmarks
10 branch
10 branch
11 branches
11 branches
12 bundle
12 bundle
13 cat
13 cat
14 clone
14 clone
15 commit
15 commit
16 config
16 config
17 copy
17 copy
18 diff
18 diff
19 export
19 export
20 files
20 files
21 forget
21 forget
22 graft
22 graft
23 grep
23 grep
24 heads
24 heads
25 help
25 help
26 identify
26 identify
27 import
27 import
28 incoming
28 incoming
29 init
29 init
30 locate
30 locate
31 log
31 log
32 manifest
32 manifest
33 merge
33 merge
34 outgoing
34 outgoing
35 parents
35 parents
36 paths
36 paths
37 phase
37 phase
38 pull
38 pull
39 push
39 push
40 recover
40 recover
41 remove
41 remove
42 rename
42 rename
43 resolve
43 resolve
44 revert
44 revert
45 rollback
45 rollback
46 root
46 root
47 serve
47 serve
48 status
48 status
49 summary
49 summary
50 tag
50 tag
51 tags
51 tags
52 tip
52 tip
53 unbundle
53 unbundle
54 update
54 update
55 verify
55 verify
56 version
56 version
57
57
58 Show all commands that start with "a"
58 Show all commands that start with "a"
59 $ hg debugcomplete a
59 $ hg debugcomplete a
60 add
60 add
61 addremove
61 addremove
62 annotate
62 annotate
63 archive
63 archive
64
64
65 Do not show debug commands if there are other candidates
65 Do not show debug commands if there are other candidates
66 $ hg debugcomplete d
66 $ hg debugcomplete d
67 diff
67 diff
68
68
69 Show debug commands if there are no other candidates
69 Show debug commands if there are no other candidates
70 $ hg debugcomplete debug
70 $ hg debugcomplete debug
71 debugancestor
71 debugancestor
72 debugapplystreamclonebundle
72 debugapplystreamclonebundle
73 debugbuilddag
73 debugbuilddag
74 debugbundle
74 debugbundle
75 debugcheckstate
75 debugcheckstate
76 debugcommands
76 debugcommands
77 debugcomplete
77 debugcomplete
78 debugconfig
78 debugconfig
79 debugcreatestreamclonebundle
79 debugcreatestreamclonebundle
80 debugdag
80 debugdag
81 debugdata
81 debugdata
82 debugdate
82 debugdate
83 debugdeltachain
83 debugdeltachain
84 debugdirstate
84 debugdirstate
85 debugdiscovery
85 debugdiscovery
86 debugextensions
86 debugextensions
87 debugfileset
87 debugfileset
88 debugfsinfo
88 debugfsinfo
89 debuggetbundle
89 debuggetbundle
90 debugignore
90 debugignore
91 debugindex
91 debugindex
92 debugindexdot
92 debugindexdot
93 debuginstall
93 debuginstall
94 debugknown
94 debugknown
95 debuglabelcomplete
95 debuglabelcomplete
96 debuglocks
96 debuglocks
97 debugmergestate
97 debugmergestate
98 debugnamecomplete
98 debugnamecomplete
99 debugobsolete
99 debugobsolete
100 debugpathcomplete
100 debugpathcomplete
101 debugpushkey
101 debugpushkey
102 debugpvec
102 debugpvec
103 debugrebuilddirstate
103 debugrebuilddirstate
104 debugrebuildfncache
104 debugrebuildfncache
105 debugrename
105 debugrename
106 debugrevlog
106 debugrevlog
107 debugrevspec
107 debugrevspec
108 debugsetparents
108 debugsetparents
109 debugsub
109 debugsub
110 debugsuccessorssets
110 debugsuccessorssets
111 debugwalk
111 debugwalk
112 debugwireargs
112 debugwireargs
113
113
114 Do not show the alias of a debug command if there are other candidates
114 Do not show the alias of a debug command if there are other candidates
115 (this should hide rawcommit)
115 (this should hide rawcommit)
116 $ hg debugcomplete r
116 $ hg debugcomplete r
117 recover
117 recover
118 remove
118 remove
119 rename
119 rename
120 resolve
120 resolve
121 revert
121 revert
122 rollback
122 rollback
123 root
123 root
124 Show the alias of a debug command if there are no other candidates
124 Show the alias of a debug command if there are no other candidates
125 $ hg debugcomplete rawc
125 $ hg debugcomplete rawc
126
126
127
127
128 Show the global options
128 Show the global options
129 $ hg debugcomplete --options | sort
129 $ hg debugcomplete --options | sort
130 --config
130 --config
131 --cwd
131 --cwd
132 --debug
132 --debug
133 --debugger
133 --debugger
134 --encoding
134 --encoding
135 --encodingmode
135 --encodingmode
136 --help
136 --help
137 --hidden
137 --hidden
138 --noninteractive
138 --noninteractive
139 --profile
139 --profile
140 --quiet
140 --quiet
141 --repository
141 --repository
142 --time
142 --time
143 --traceback
143 --traceback
144 --verbose
144 --verbose
145 --version
145 --version
146 -R
146 -R
147 -h
147 -h
148 -q
148 -q
149 -v
149 -v
150 -y
150 -y
151
151
152 Show the options for the "serve" command
152 Show the options for the "serve" command
153 $ hg debugcomplete --options serve | sort
153 $ hg debugcomplete --options serve | sort
154 --accesslog
154 --accesslog
155 --address
155 --address
156 --certificate
156 --certificate
157 --cmdserver
157 --cmdserver
158 --config
158 --config
159 --cwd
159 --cwd
160 --daemon
160 --daemon
161 --daemon-pipefds
161 --daemon-pipefds
162 --debug
162 --debug
163 --debugger
163 --debugger
164 --encoding
164 --encoding
165 --encodingmode
165 --encodingmode
166 --errorlog
166 --errorlog
167 --help
167 --help
168 --hidden
168 --hidden
169 --ipv6
169 --ipv6
170 --name
170 --name
171 --noninteractive
171 --noninteractive
172 --pid-file
172 --pid-file
173 --port
173 --port
174 --prefix
174 --prefix
175 --profile
175 --profile
176 --quiet
176 --quiet
177 --repository
177 --repository
178 --stdio
178 --stdio
179 --style
179 --style
180 --templates
180 --templates
181 --time
181 --time
182 --traceback
182 --traceback
183 --verbose
183 --verbose
184 --version
184 --version
185 --web-conf
185 --web-conf
186 -6
186 -6
187 -A
187 -A
188 -E
188 -E
189 -R
189 -R
190 -a
190 -a
191 -d
191 -d
192 -h
192 -h
193 -n
193 -n
194 -p
194 -p
195 -q
195 -q
196 -t
196 -t
197 -v
197 -v
198 -y
198 -y
199
199
200 Show an error if we use --options with an ambiguous abbreviation
200 Show an error if we use --options with an ambiguous abbreviation
201 $ hg debugcomplete --options s
201 $ hg debugcomplete --options s
202 hg: command 's' is ambiguous:
202 hg: command 's' is ambiguous:
203 serve showconfig status summary
203 serve showconfig status summary
204 [255]
204 [255]
205
205
206 Show all commands + options
206 Show all commands + options
207 $ hg debugcommands
207 $ hg debugcommands
208 add: include, exclude, subrepos, dry-run
208 add: include, exclude, subrepos, dry-run
209 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, ignore-all-space, ignore-space-change, ignore-blank-lines, include, exclude, template
209 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, ignore-all-space, ignore-space-change, ignore-blank-lines, include, exclude, template
210 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
210 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
211 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
211 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
212 diff: rev, change, text, git, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, root, include, exclude, subrepos
212 diff: rev, change, text, git, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, root, include, exclude, subrepos
213 export: output, switch-parent, rev, text, git, nodates
213 export: output, switch-parent, rev, text, git, nodates
214 forget: include, exclude
214 forget: include, exclude
215 init: ssh, remotecmd, insecure
215 init: ssh, remotecmd, insecure
216 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
216 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
217 merge: force, rev, preview, tool
217 merge: force, rev, preview, tool
218 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
218 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
219 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
219 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
220 remove: after, force, subrepos, include, exclude
220 remove: after, force, subrepos, include, exclude
221 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
221 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
222 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
222 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
223 summary: remote
223 summary: remote
224 update: clean, check, date, rev, tool
224 update: clean, check, date, rev, tool
225 addremove: similarity, subrepos, include, exclude, dry-run
225 addremove: similarity, subrepos, include, exclude, dry-run
226 archive: no-decode, prefix, rev, type, subrepos, include, exclude
226 archive: no-decode, prefix, rev, type, subrepos, include, exclude
227 backout: merge, commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
227 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
228 bisect: reset, good, bad, skip, extend, command, noupdate
228 bisect: reset, good, bad, skip, extend, command, noupdate
229 bookmarks: force, rev, delete, rename, inactive, template
229 bookmarks: force, rev, delete, rename, inactive, template
230 branch: force, clean
230 branch: force, clean
231 branches: active, closed, template
231 branches: active, closed, template
232 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
232 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
233 cat: output, rev, decode, include, exclude
233 cat: output, rev, decode, include, exclude
234 config: untrusted, edit, local, global
234 config: untrusted, edit, local, global
235 copy: after, force, include, exclude, dry-run
235 copy: after, force, include, exclude, dry-run
236 debugancestor:
236 debugancestor:
237 debugapplystreamclonebundle:
237 debugapplystreamclonebundle:
238 debugbuilddag: mergeable-file, overwritten-file, new-file
238 debugbuilddag: mergeable-file, overwritten-file, new-file
239 debugbundle: all, spec
239 debugbundle: all, spec
240 debugcheckstate:
240 debugcheckstate:
241 debugcommands:
241 debugcommands:
242 debugcomplete: options
242 debugcomplete: options
243 debugcreatestreamclonebundle:
243 debugcreatestreamclonebundle:
244 debugdag: tags, branches, dots, spaces
244 debugdag: tags, branches, dots, spaces
245 debugdata: changelog, manifest, dir
245 debugdata: changelog, manifest, dir
246 debugdate: extended
246 debugdate: extended
247 debugdeltachain: changelog, manifest, dir, template
247 debugdeltachain: changelog, manifest, dir, template
248 debugdirstate: nodates, datesort
248 debugdirstate: nodates, datesort
249 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
249 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
250 debugextensions: template
250 debugextensions: template
251 debugfileset: rev
251 debugfileset: rev
252 debugfsinfo:
252 debugfsinfo:
253 debuggetbundle: head, common, type
253 debuggetbundle: head, common, type
254 debugignore:
254 debugignore:
255 debugindex: changelog, manifest, dir, format
255 debugindex: changelog, manifest, dir, format
256 debugindexdot: changelog, manifest, dir
256 debugindexdot: changelog, manifest, dir
257 debuginstall:
257 debuginstall:
258 debugknown:
258 debugknown:
259 debuglabelcomplete:
259 debuglabelcomplete:
260 debuglocks: force-lock, force-wlock
260 debuglocks: force-lock, force-wlock
261 debugmergestate:
261 debugmergestate:
262 debugnamecomplete:
262 debugnamecomplete:
263 debugobsolete: flags, record-parents, rev, date, user
263 debugobsolete: flags, record-parents, rev, date, user
264 debugpathcomplete: full, normal, added, removed
264 debugpathcomplete: full, normal, added, removed
265 debugpushkey:
265 debugpushkey:
266 debugpvec:
266 debugpvec:
267 debugrebuilddirstate: rev, minimal
267 debugrebuilddirstate: rev, minimal
268 debugrebuildfncache:
268 debugrebuildfncache:
269 debugrename: rev
269 debugrename: rev
270 debugrevlog: changelog, manifest, dir, dump
270 debugrevlog: changelog, manifest, dir, dump
271 debugrevspec: optimize
271 debugrevspec: optimize
272 debugsetparents:
272 debugsetparents:
273 debugsub: rev
273 debugsub: rev
274 debugsuccessorssets:
274 debugsuccessorssets:
275 debugwalk: include, exclude
275 debugwalk: include, exclude
276 debugwireargs: three, four, five, ssh, remotecmd, insecure
276 debugwireargs: three, four, five, ssh, remotecmd, insecure
277 files: rev, print0, include, exclude, template, subrepos
277 files: rev, print0, include, exclude, template, subrepos
278 graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
278 graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
279 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
279 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
280 heads: rev, topo, active, closed, style, template
280 heads: rev, topo, active, closed, style, template
281 help: extension, command, keyword, system
281 help: extension, command, keyword, system
282 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
282 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
283 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
283 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
284 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
284 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
285 locate: rev, print0, fullpath, include, exclude
285 locate: rev, print0, fullpath, include, exclude
286 manifest: rev, all, template
286 manifest: rev, all, template
287 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
287 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
288 parents: rev, style, template
288 parents: rev, style, template
289 paths: template
289 paths: template
290 phase: public, draft, secret, force, rev
290 phase: public, draft, secret, force, rev
291 recover:
291 recover:
292 rename: after, force, include, exclude, dry-run
292 rename: after, force, include, exclude, dry-run
293 resolve: all, list, mark, unmark, no-status, tool, include, exclude, template
293 resolve: all, list, mark, unmark, no-status, tool, include, exclude, template
294 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
294 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
295 rollback: dry-run, force
295 rollback: dry-run, force
296 root:
296 root:
297 tag: force, local, rev, remove, edit, message, date, user
297 tag: force, local, rev, remove, edit, message, date, user
298 tags: template
298 tags: template
299 tip: patch, git, style, template
299 tip: patch, git, style, template
300 unbundle: update
300 unbundle: update
301 verify:
301 verify:
302 version:
302 version:
303
303
304 $ hg init a
304 $ hg init a
305 $ cd a
305 $ cd a
306 $ echo fee > fee
306 $ echo fee > fee
307 $ hg ci -q -Amfee
307 $ hg ci -q -Amfee
308 $ hg tag fee
308 $ hg tag fee
309 $ mkdir fie
309 $ mkdir fie
310 $ echo dead > fie/dead
310 $ echo dead > fie/dead
311 $ echo live > fie/live
311 $ echo live > fie/live
312 $ hg bookmark fo
312 $ hg bookmark fo
313 $ hg branch -q fie
313 $ hg branch -q fie
314 $ hg ci -q -Amfie
314 $ hg ci -q -Amfie
315 $ echo fo > fo
315 $ echo fo > fo
316 $ hg branch -qf default
316 $ hg branch -qf default
317 $ hg ci -q -Amfo
317 $ hg ci -q -Amfo
318 $ echo Fum > Fum
318 $ echo Fum > Fum
319 $ hg ci -q -AmFum
319 $ hg ci -q -AmFum
320 $ hg bookmark Fum
320 $ hg bookmark Fum
321
321
322 Test debugpathcomplete
322 Test debugpathcomplete
323
323
324 $ hg debugpathcomplete f
324 $ hg debugpathcomplete f
325 fee
325 fee
326 fie
326 fie
327 fo
327 fo
328 $ hg debugpathcomplete -f f
328 $ hg debugpathcomplete -f f
329 fee
329 fee
330 fie/dead
330 fie/dead
331 fie/live
331 fie/live
332 fo
332 fo
333
333
334 $ hg rm Fum
334 $ hg rm Fum
335 $ hg debugpathcomplete -r F
335 $ hg debugpathcomplete -r F
336 Fum
336 Fum
337
337
338 Test debugnamecomplete
338 Test debugnamecomplete
339
339
340 $ hg debugnamecomplete
340 $ hg debugnamecomplete
341 Fum
341 Fum
342 default
342 default
343 fee
343 fee
344 fie
344 fie
345 fo
345 fo
346 tip
346 tip
347 $ hg debugnamecomplete f
347 $ hg debugnamecomplete f
348 fee
348 fee
349 fie
349 fie
350 fo
350 fo
@@ -1,1338 +1,1338 b''
1 $ cat <<EOF >> $HGRCPATH
1 $ cat <<EOF >> $HGRCPATH
2 > [extensions]
2 > [extensions]
3 > keyword =
3 > keyword =
4 > mq =
4 > mq =
5 > notify =
5 > notify =
6 > record =
6 > record =
7 > transplant =
7 > transplant =
8 > [ui]
8 > [ui]
9 > interactive = true
9 > interactive = true
10 > EOF
10 > EOF
11
11
12 hide outer repo
12 hide outer repo
13 $ hg init
13 $ hg init
14
14
15 Run kwdemo before [keyword] files are set up
15 Run kwdemo before [keyword] files are set up
16 as it would succeed without uisetup otherwise
16 as it would succeed without uisetup otherwise
17
17
18 $ hg --quiet kwdemo
18 $ hg --quiet kwdemo
19 [extensions]
19 [extensions]
20 keyword =
20 keyword =
21 [keyword]
21 [keyword]
22 demo.txt =
22 demo.txt =
23 [keywordset]
23 [keywordset]
24 svn = False
24 svn = False
25 [keywordmaps]
25 [keywordmaps]
26 Author = {author|user}
26 Author = {author|user}
27 Date = {date|utcdate}
27 Date = {date|utcdate}
28 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
28 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
29 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
29 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
30 RCSFile = {file|basename},v
30 RCSFile = {file|basename},v
31 RCSfile = {file|basename},v
31 RCSfile = {file|basename},v
32 Revision = {node|short}
32 Revision = {node|short}
33 Source = {root}/{file},v
33 Source = {root}/{file},v
34 $Author: test $
34 $Author: test $
35 $Date: ????/??/?? ??:??:?? $ (glob)
35 $Date: ????/??/?? ??:??:?? $ (glob)
36 $Header: */demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
36 $Header: */demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
37 $Id: demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
37 $Id: demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
38 $RCSFile: demo.txt,v $
38 $RCSFile: demo.txt,v $
39 $RCSfile: demo.txt,v $
39 $RCSfile: demo.txt,v $
40 $Revision: ???????????? $ (glob)
40 $Revision: ???????????? $ (glob)
41 $Source: */demo.txt,v $ (glob)
41 $Source: */demo.txt,v $ (glob)
42
42
43 $ hg --quiet kwdemo "Branch = {branches}"
43 $ hg --quiet kwdemo "Branch = {branches}"
44 [extensions]
44 [extensions]
45 keyword =
45 keyword =
46 [keyword]
46 [keyword]
47 demo.txt =
47 demo.txt =
48 [keywordset]
48 [keywordset]
49 svn = False
49 svn = False
50 [keywordmaps]
50 [keywordmaps]
51 Branch = {branches}
51 Branch = {branches}
52 $Branch: demobranch $
52 $Branch: demobranch $
53
53
54 $ cat <<EOF >> $HGRCPATH
54 $ cat <<EOF >> $HGRCPATH
55 > [keyword]
55 > [keyword]
56 > ** =
56 > ** =
57 > b = ignore
57 > b = ignore
58 > i = ignore
58 > i = ignore
59 > [hooks]
59 > [hooks]
60 > EOF
60 > EOF
61 $ cp $HGRCPATH $HGRCPATH.nohooks
61 $ cp $HGRCPATH $HGRCPATH.nohooks
62 > cat <<EOF >> $HGRCPATH
62 > cat <<EOF >> $HGRCPATH
63 > commit=
63 > commit=
64 > commit.test=cp a hooktest
64 > commit.test=cp a hooktest
65 > EOF
65 > EOF
66
66
67 $ hg init Test-bndl
67 $ hg init Test-bndl
68 $ cd Test-bndl
68 $ cd Test-bndl
69
69
70 kwshrink should exit silently in empty/invalid repo
70 kwshrink should exit silently in empty/invalid repo
71
71
72 $ hg kwshrink
72 $ hg kwshrink
73
73
74 Symlinks cannot be created on Windows.
74 Symlinks cannot be created on Windows.
75 A bundle to test this was made with:
75 A bundle to test this was made with:
76 hg init t
76 hg init t
77 cd t
77 cd t
78 echo a > a
78 echo a > a
79 ln -s a sym
79 ln -s a sym
80 hg add sym
80 hg add sym
81 hg ci -m addsym -u mercurial
81 hg ci -m addsym -u mercurial
82 hg bundle --base null ../test-keyword.hg
82 hg bundle --base null ../test-keyword.hg
83
83
84 $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
84 $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
85 pulling from *test-keyword.hg (glob)
85 pulling from *test-keyword.hg (glob)
86 requesting all changes
86 requesting all changes
87 adding changesets
87 adding changesets
88 adding manifests
88 adding manifests
89 adding file changes
89 adding file changes
90 added 1 changesets with 1 changes to 1 files
90 added 1 changesets with 1 changes to 1 files
91 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
92
92
93 $ echo 'expand $Id$' > a
93 $ echo 'expand $Id$' > a
94 $ echo 'do not process $Id:' >> a
94 $ echo 'do not process $Id:' >> a
95 $ echo 'xxx $' >> a
95 $ echo 'xxx $' >> a
96 $ echo 'ignore $Id$' > b
96 $ echo 'ignore $Id$' > b
97
97
98 Output files as they were created
98 Output files as they were created
99
99
100 $ cat a b
100 $ cat a b
101 expand $Id$
101 expand $Id$
102 do not process $Id:
102 do not process $Id:
103 xxx $
103 xxx $
104 ignore $Id$
104 ignore $Id$
105
105
106 no kwfiles
106 no kwfiles
107
107
108 $ hg kwfiles
108 $ hg kwfiles
109
109
110 untracked candidates
110 untracked candidates
111
111
112 $ hg -v kwfiles --unknown
112 $ hg -v kwfiles --unknown
113 k a
113 k a
114
114
115 Add files and check status
115 Add files and check status
116
116
117 $ hg addremove
117 $ hg addremove
118 adding a
118 adding a
119 adding b
119 adding b
120 $ hg status
120 $ hg status
121 A a
121 A a
122 A b
122 A b
123
123
124
124
125 Default keyword expansion including commit hook
125 Default keyword expansion including commit hook
126 Interrupted commit should not change state or run commit hook
126 Interrupted commit should not change state or run commit hook
127
127
128 $ hg --debug commit
128 $ hg --debug commit
129 abort: empty commit message
129 abort: empty commit message
130 [255]
130 [255]
131 $ hg status
131 $ hg status
132 A a
132 A a
133 A b
133 A b
134
134
135 Commit with several checks
135 Commit with several checks
136
136
137 $ hg --debug commit -mabsym -u 'User Name <user@example.com>'
137 $ hg --debug commit -mabsym -u 'User Name <user@example.com>'
138 committing files:
138 committing files:
139 a
139 a
140 b
140 b
141 committing manifest
141 committing manifest
142 committing changelog
142 committing changelog
143 overwriting a expanding keywords
143 overwriting a expanding keywords
144 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
144 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
145 running hook commit.test: cp a hooktest
145 running hook commit.test: cp a hooktest
146 $ hg status
146 $ hg status
147 ? hooktest
147 ? hooktest
148 $ hg debugrebuildstate
148 $ hg debugrebuildstate
149 $ hg --quiet identify
149 $ hg --quiet identify
150 ef63ca68695b
150 ef63ca68695b
151
151
152 cat files in working directory with keywords expanded
152 cat files in working directory with keywords expanded
153
153
154 $ cat a b
154 $ cat a b
155 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
155 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
156 do not process $Id:
156 do not process $Id:
157 xxx $
157 xxx $
158 ignore $Id$
158 ignore $Id$
159
159
160 hg cat files and symlink, no expansion
160 hg cat files and symlink, no expansion
161
161
162 $ hg cat sym a b && echo
162 $ hg cat sym a b && echo
163 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
163 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
164 do not process $Id:
164 do not process $Id:
165 xxx $
165 xxx $
166 ignore $Id$
166 ignore $Id$
167 a
167 a
168
168
169 $ diff a hooktest
169 $ diff a hooktest
170
170
171 $ cp $HGRCPATH.nohooks $HGRCPATH
171 $ cp $HGRCPATH.nohooks $HGRCPATH
172 $ rm hooktest
172 $ rm hooktest
173
173
174 hg status of kw-ignored binary file starting with '\1\n'
174 hg status of kw-ignored binary file starting with '\1\n'
175
175
176 >>> open("i", "wb").write("\1\nfoo")
176 >>> open("i", "wb").write("\1\nfoo")
177 $ hg -q commit -Am metasep i
177 $ hg -q commit -Am metasep i
178 $ hg status
178 $ hg status
179 >>> open("i", "wb").write("\1\nbar")
179 >>> open("i", "wb").write("\1\nbar")
180 $ hg status
180 $ hg status
181 M i
181 M i
182 $ hg -q commit -m "modify metasep" i
182 $ hg -q commit -m "modify metasep" i
183 $ hg status --rev 2:3
183 $ hg status --rev 2:3
184 M i
184 M i
185 $ touch empty
185 $ touch empty
186 $ hg -q commit -A -m "another file"
186 $ hg -q commit -A -m "another file"
187 $ hg status -A --rev 3:4 i
187 $ hg status -A --rev 3:4 i
188 C i
188 C i
189
189
190 $ hg -q strip --no-backup 2
190 $ hg -q strip --no-backup 2
191
191
192 Test hook execution
192 Test hook execution
193
193
194 bundle
194 bundle
195
195
196 $ hg bundle --base null ../kw.hg
196 $ hg bundle --base null ../kw.hg
197 2 changesets found
197 2 changesets found
198 $ cd ..
198 $ cd ..
199 $ hg init Test
199 $ hg init Test
200 $ cd Test
200 $ cd Test
201
201
202 Notify on pull to check whether keywords stay as is in email
202 Notify on pull to check whether keywords stay as is in email
203 ie. if patch.diff wrapper acts as it should
203 ie. if patch.diff wrapper acts as it should
204
204
205 $ cat <<EOF >> $HGRCPATH
205 $ cat <<EOF >> $HGRCPATH
206 > [hooks]
206 > [hooks]
207 > incoming.notify = python:hgext.notify.hook
207 > incoming.notify = python:hgext.notify.hook
208 > [notify]
208 > [notify]
209 > sources = pull
209 > sources = pull
210 > diffstat = False
210 > diffstat = False
211 > maxsubject = 15
211 > maxsubject = 15
212 > [reposubs]
212 > [reposubs]
213 > * = Test
213 > * = Test
214 > EOF
214 > EOF
215
215
216 Pull from bundle and trigger notify
216 Pull from bundle and trigger notify
217
217
218 $ hg pull -u ../kw.hg
218 $ hg pull -u ../kw.hg
219 pulling from ../kw.hg
219 pulling from ../kw.hg
220 requesting all changes
220 requesting all changes
221 adding changesets
221 adding changesets
222 adding manifests
222 adding manifests
223 adding file changes
223 adding file changes
224 added 2 changesets with 3 changes to 3 files
224 added 2 changesets with 3 changes to 3 files
225 Content-Type: text/plain; charset="us-ascii"
225 Content-Type: text/plain; charset="us-ascii"
226 MIME-Version: 1.0
226 MIME-Version: 1.0
227 Content-Transfer-Encoding: 7bit
227 Content-Transfer-Encoding: 7bit
228 Date: * (glob)
228 Date: * (glob)
229 Subject: changeset in...
229 Subject: changeset in...
230 From: mercurial
230 From: mercurial
231 X-Hg-Notification: changeset a2392c293916
231 X-Hg-Notification: changeset a2392c293916
232 Message-Id: <hg.a2392c293916*> (glob)
232 Message-Id: <hg.a2392c293916*> (glob)
233 To: Test
233 To: Test
234
234
235 changeset a2392c293916 in $TESTTMP/Test (glob)
235 changeset a2392c293916 in $TESTTMP/Test (glob)
236 details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
236 details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
237 description:
237 description:
238 addsym
238 addsym
239
239
240 diffs (6 lines):
240 diffs (6 lines):
241
241
242 diff -r 000000000000 -r a2392c293916 sym
242 diff -r 000000000000 -r a2392c293916 sym
243 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
243 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
244 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
244 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
245 @@ -0,0 +1,1 @@
245 @@ -0,0 +1,1 @@
246 +a
246 +a
247 \ No newline at end of file
247 \ No newline at end of file
248 Content-Type: text/plain; charset="us-ascii"
248 Content-Type: text/plain; charset="us-ascii"
249 MIME-Version: 1.0
249 MIME-Version: 1.0
250 Content-Transfer-Encoding: 7bit
250 Content-Transfer-Encoding: 7bit
251 Date:* (glob)
251 Date:* (glob)
252 Subject: changeset in...
252 Subject: changeset in...
253 From: User Name <user@example.com>
253 From: User Name <user@example.com>
254 X-Hg-Notification: changeset ef63ca68695b
254 X-Hg-Notification: changeset ef63ca68695b
255 Message-Id: <hg.ef63ca68695b*> (glob)
255 Message-Id: <hg.ef63ca68695b*> (glob)
256 To: Test
256 To: Test
257
257
258 changeset ef63ca68695b in $TESTTMP/Test (glob)
258 changeset ef63ca68695b in $TESTTMP/Test (glob)
259 details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
259 details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
260 description:
260 description:
261 absym
261 absym
262
262
263 diffs (12 lines):
263 diffs (12 lines):
264
264
265 diff -r a2392c293916 -r ef63ca68695b a
265 diff -r a2392c293916 -r ef63ca68695b a
266 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
266 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
267 +++ b/a Thu Jan 01 00:00:00 1970 +0000
267 +++ b/a Thu Jan 01 00:00:00 1970 +0000
268 @@ -0,0 +1,3 @@
268 @@ -0,0 +1,3 @@
269 +expand $Id$
269 +expand $Id$
270 +do not process $Id:
270 +do not process $Id:
271 +xxx $
271 +xxx $
272 diff -r a2392c293916 -r ef63ca68695b b
272 diff -r a2392c293916 -r ef63ca68695b b
273 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
273 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
274 +++ b/b Thu Jan 01 00:00:00 1970 +0000
274 +++ b/b Thu Jan 01 00:00:00 1970 +0000
275 @@ -0,0 +1,1 @@
275 @@ -0,0 +1,1 @@
276 +ignore $Id$
276 +ignore $Id$
277 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
278
278
279 $ cp $HGRCPATH.nohooks $HGRCPATH
279 $ cp $HGRCPATH.nohooks $HGRCPATH
280
280
281 Touch files and check with status
281 Touch files and check with status
282
282
283 $ touch a b
283 $ touch a b
284 $ hg status
284 $ hg status
285
285
286 Update and expand
286 Update and expand
287
287
288 $ rm sym a b
288 $ rm sym a b
289 $ hg update -C
289 $ hg update -C
290 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
290 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 $ cat a b
291 $ cat a b
292 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
292 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
293 do not process $Id:
293 do not process $Id:
294 xxx $
294 xxx $
295 ignore $Id$
295 ignore $Id$
296
296
297 Check whether expansion is filewise and file mode is preserved
297 Check whether expansion is filewise and file mode is preserved
298
298
299 $ echo '$Id$' > c
299 $ echo '$Id$' > c
300 $ echo 'tests for different changenodes' >> c
300 $ echo 'tests for different changenodes' >> c
301 #if unix-permissions
301 #if unix-permissions
302 $ chmod 600 c
302 $ chmod 600 c
303 $ ls -l c | cut -b 1-10
303 $ ls -l c | cut -b 1-10
304 -rw-------
304 -rw-------
305 #endif
305 #endif
306
306
307 commit file c
307 commit file c
308
308
309 $ hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
309 $ hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
310 adding c
310 adding c
311 #if unix-permissions
311 #if unix-permissions
312 $ ls -l c | cut -b 1-10
312 $ ls -l c | cut -b 1-10
313 -rw-------
313 -rw-------
314 #endif
314 #endif
315
315
316 force expansion
316 force expansion
317
317
318 $ hg -v kwexpand
318 $ hg -v kwexpand
319 overwriting a expanding keywords
319 overwriting a expanding keywords
320 overwriting c expanding keywords
320 overwriting c expanding keywords
321
321
322 compare changenodes in a and c
322 compare changenodes in a and c
323
323
324 $ cat a c
324 $ cat a c
325 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
325 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
326 do not process $Id:
326 do not process $Id:
327 xxx $
327 xxx $
328 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
328 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
329 tests for different changenodes
329 tests for different changenodes
330
330
331 record
331 record
332
332
333 $ echo '$Id$' > r
333 $ echo '$Id$' > r
334 $ hg add r
334 $ hg add r
335
335
336 record chunk
336 record chunk
337
337
338 >>> lines = open('a', 'rb').readlines()
338 >>> lines = open('a', 'rb').readlines()
339 >>> lines.insert(1, 'foo\n')
339 >>> lines.insert(1, 'foo\n')
340 >>> lines.append('bar\n')
340 >>> lines.append('bar\n')
341 >>> open('a', 'wb').writelines(lines)
341 >>> open('a', 'wb').writelines(lines)
342 $ hg record -d '10 1' -m rectest a<<EOF
342 $ hg record -d '10 1' -m rectest a<<EOF
343 > y
343 > y
344 > y
344 > y
345 > n
345 > n
346 > EOF
346 > EOF
347 diff --git a/a b/a
347 diff --git a/a b/a
348 2 hunks, 2 lines changed
348 2 hunks, 2 lines changed
349 examine changes to 'a'? [Ynesfdaq?] y
349 examine changes to 'a'? [Ynesfdaq?] y
350
350
351 @@ -1,3 +1,4 @@
351 @@ -1,3 +1,4 @@
352 expand $Id$
352 expand $Id$
353 +foo
353 +foo
354 do not process $Id:
354 do not process $Id:
355 xxx $
355 xxx $
356 record change 1/2 to 'a'? [Ynesfdaq?] y
356 record change 1/2 to 'a'? [Ynesfdaq?] y
357
357
358 @@ -2,2 +3,3 @@
358 @@ -2,2 +3,3 @@
359 do not process $Id:
359 do not process $Id:
360 xxx $
360 xxx $
361 +bar
361 +bar
362 record change 2/2 to 'a'? [Ynesfdaq?] n
362 record change 2/2 to 'a'? [Ynesfdaq?] n
363
363
364
364
365 $ hg identify
365 $ hg identify
366 5f5eb23505c3+ tip
366 5f5eb23505c3+ tip
367 $ hg status
367 $ hg status
368 M a
368 M a
369 A r
369 A r
370
370
371 Cat modified file a
371 Cat modified file a
372
372
373 $ cat a
373 $ cat a
374 expand $Id: a,v 5f5eb23505c3 1970/01/01 00:00:10 test $
374 expand $Id: a,v 5f5eb23505c3 1970/01/01 00:00:10 test $
375 foo
375 foo
376 do not process $Id:
376 do not process $Id:
377 xxx $
377 xxx $
378 bar
378 bar
379
379
380 Diff remaining chunk
380 Diff remaining chunk
381
381
382 $ hg diff a
382 $ hg diff a
383 diff -r 5f5eb23505c3 a
383 diff -r 5f5eb23505c3 a
384 --- a/a Thu Jan 01 00:00:09 1970 -0000
384 --- a/a Thu Jan 01 00:00:09 1970 -0000
385 +++ b/a * (glob)
385 +++ b/a * (glob)
386 @@ -2,3 +2,4 @@
386 @@ -2,3 +2,4 @@
387 foo
387 foo
388 do not process $Id:
388 do not process $Id:
389 xxx $
389 xxx $
390 +bar
390 +bar
391
391
392 $ hg rollback
392 $ hg rollback
393 repository tip rolled back to revision 2 (undo commit)
393 repository tip rolled back to revision 2 (undo commit)
394 working directory now based on revision 2
394 working directory now based on revision 2
395
395
396 Record all chunks in file a
396 Record all chunks in file a
397
397
398 $ echo foo > msg
398 $ echo foo > msg
399
399
400 - do not use "hg record -m" here!
400 - do not use "hg record -m" here!
401
401
402 $ hg record -l msg -d '11 1' a<<EOF
402 $ hg record -l msg -d '11 1' a<<EOF
403 > y
403 > y
404 > y
404 > y
405 > y
405 > y
406 > EOF
406 > EOF
407 diff --git a/a b/a
407 diff --git a/a b/a
408 2 hunks, 2 lines changed
408 2 hunks, 2 lines changed
409 examine changes to 'a'? [Ynesfdaq?] y
409 examine changes to 'a'? [Ynesfdaq?] y
410
410
411 @@ -1,3 +1,4 @@
411 @@ -1,3 +1,4 @@
412 expand $Id$
412 expand $Id$
413 +foo
413 +foo
414 do not process $Id:
414 do not process $Id:
415 xxx $
415 xxx $
416 record change 1/2 to 'a'? [Ynesfdaq?] y
416 record change 1/2 to 'a'? [Ynesfdaq?] y
417
417
418 @@ -2,2 +3,3 @@
418 @@ -2,2 +3,3 @@
419 do not process $Id:
419 do not process $Id:
420 xxx $
420 xxx $
421 +bar
421 +bar
422 record change 2/2 to 'a'? [Ynesfdaq?] y
422 record change 2/2 to 'a'? [Ynesfdaq?] y
423
423
424
424
425 File a should be clean
425 File a should be clean
426
426
427 $ hg status -A a
427 $ hg status -A a
428 C a
428 C a
429
429
430 rollback and revert expansion
430 rollback and revert expansion
431
431
432 $ cat a
432 $ cat a
433 expand $Id: a,v 78e0a02d76aa 1970/01/01 00:00:11 test $
433 expand $Id: a,v 78e0a02d76aa 1970/01/01 00:00:11 test $
434 foo
434 foo
435 do not process $Id:
435 do not process $Id:
436 xxx $
436 xxx $
437 bar
437 bar
438 $ hg --verbose rollback
438 $ hg --verbose rollback
439 repository tip rolled back to revision 2 (undo commit)
439 repository tip rolled back to revision 2 (undo commit)
440 working directory now based on revision 2
440 working directory now based on revision 2
441 overwriting a expanding keywords
441 overwriting a expanding keywords
442 $ hg status a
442 $ hg status a
443 M a
443 M a
444 $ cat a
444 $ cat a
445 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
445 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
446 foo
446 foo
447 do not process $Id:
447 do not process $Id:
448 xxx $
448 xxx $
449 bar
449 bar
450 $ echo '$Id$' > y
450 $ echo '$Id$' > y
451 $ echo '$Id$' > z
451 $ echo '$Id$' > z
452 $ hg add y
452 $ hg add y
453 $ hg commit -Am "rollback only" z
453 $ hg commit -Am "rollback only" z
454 $ cat z
454 $ cat z
455 $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $
455 $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $
456 $ hg --verbose rollback
456 $ hg --verbose rollback
457 repository tip rolled back to revision 2 (undo commit)
457 repository tip rolled back to revision 2 (undo commit)
458 working directory now based on revision 2
458 working directory now based on revision 2
459 overwriting z shrinking keywords
459 overwriting z shrinking keywords
460
460
461 Only z should be overwritten
461 Only z should be overwritten
462
462
463 $ hg status a y z
463 $ hg status a y z
464 M a
464 M a
465 A y
465 A y
466 A z
466 A z
467 $ cat z
467 $ cat z
468 $Id$
468 $Id$
469 $ hg forget y z
469 $ hg forget y z
470 $ rm y z
470 $ rm y z
471
471
472 record added file alone
472 record added file alone
473
473
474 $ hg -v record -l msg -d '12 2' r<<EOF
474 $ hg -v record -l msg -d '12 2' r<<EOF
475 > y
475 > y
476 > y
476 > y
477 > EOF
477 > EOF
478 diff --git a/r b/r
478 diff --git a/r b/r
479 new file mode 100644
479 new file mode 100644
480 examine changes to 'r'? [Ynesfdaq?] y
480 examine changes to 'r'? [Ynesfdaq?] y
481
481
482 @@ -0,0 +1,1 @@
482 @@ -0,0 +1,1 @@
483 +$Id$
483 +$Id$
484 record this change to 'r'? [Ynesfdaq?] y
484 record this change to 'r'? [Ynesfdaq?] y
485
485
486 resolving manifests
486 resolving manifests
487 patching file r
487 patching file r
488 committing files:
488 committing files:
489 r
489 r
490 committing manifest
490 committing manifest
491 committing changelog
491 committing changelog
492 committed changeset 3:82a2f715724d
492 committed changeset 3:82a2f715724d
493 overwriting r expanding keywords
493 overwriting r expanding keywords
494 $ hg status r
494 $ hg status r
495 $ hg --verbose rollback
495 $ hg --verbose rollback
496 repository tip rolled back to revision 2 (undo commit)
496 repository tip rolled back to revision 2 (undo commit)
497 working directory now based on revision 2
497 working directory now based on revision 2
498 overwriting r shrinking keywords
498 overwriting r shrinking keywords
499 $ hg forget r
499 $ hg forget r
500 $ rm msg r
500 $ rm msg r
501 $ hg update -C
501 $ hg update -C
502 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
502 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
503
503
504 record added keyword ignored file
504 record added keyword ignored file
505
505
506 $ echo '$Id$' > i
506 $ echo '$Id$' > i
507 $ hg add i
507 $ hg add i
508 $ hg --verbose record -d '13 1' -m recignored<<EOF
508 $ hg --verbose record -d '13 1' -m recignored<<EOF
509 > y
509 > y
510 > y
510 > y
511 > EOF
511 > EOF
512 diff --git a/i b/i
512 diff --git a/i b/i
513 new file mode 100644
513 new file mode 100644
514 examine changes to 'i'? [Ynesfdaq?] y
514 examine changes to 'i'? [Ynesfdaq?] y
515
515
516 @@ -0,0 +1,1 @@
516 @@ -0,0 +1,1 @@
517 +$Id$
517 +$Id$
518 record this change to 'i'? [Ynesfdaq?] y
518 record this change to 'i'? [Ynesfdaq?] y
519
519
520 resolving manifests
520 resolving manifests
521 patching file i
521 patching file i
522 committing files:
522 committing files:
523 i
523 i
524 committing manifest
524 committing manifest
525 committing changelog
525 committing changelog
526 committed changeset 3:9f40ceb5a072
526 committed changeset 3:9f40ceb5a072
527 $ cat i
527 $ cat i
528 $Id$
528 $Id$
529 $ hg -q rollback
529 $ hg -q rollback
530 $ hg forget i
530 $ hg forget i
531 $ rm i
531 $ rm i
532
532
533 amend
533 amend
534
534
535 $ echo amend >> a
535 $ echo amend >> a
536 $ echo amend >> b
536 $ echo amend >> b
537 $ hg -q commit -d '14 1' -m 'prepare amend'
537 $ hg -q commit -d '14 1' -m 'prepare amend'
538
538
539 $ hg --debug commit --amend -d '15 1' -m 'amend without changes' | grep keywords
539 $ hg --debug commit --amend -d '15 1' -m 'amend without changes' | grep keywords
540 overwriting a expanding keywords
540 overwriting a expanding keywords
541 $ hg -q id
541 $ hg -q id
542 67d8c481a6be
542 67d8c481a6be
543 $ head -1 a
543 $ head -1 a
544 expand $Id: a,v 67d8c481a6be 1970/01/01 00:00:15 test $
544 expand $Id: a,v 67d8c481a6be 1970/01/01 00:00:15 test $
545
545
546 $ hg -q strip --no-backup tip
546 $ hg -q strip --no-backup tip
547
547
548 Test patch queue repo
548 Test patch queue repo
549
549
550 $ hg init --mq
550 $ hg init --mq
551 $ hg qimport -r tip -n mqtest.diff
551 $ hg qimport -r tip -n mqtest.diff
552 $ hg commit --mq -m mqtest
552 $ hg commit --mq -m mqtest
553
553
554 Keywords should not be expanded in patch
554 Keywords should not be expanded in patch
555
555
556 $ cat .hg/patches/mqtest.diff
556 $ cat .hg/patches/mqtest.diff
557 # HG changeset patch
557 # HG changeset patch
558 # User User Name <user@example.com>
558 # User User Name <user@example.com>
559 # Date 1 0
559 # Date 1 0
560 # Thu Jan 01 00:00:01 1970 +0000
560 # Thu Jan 01 00:00:01 1970 +0000
561 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
561 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
562 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
562 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
563 cndiff
563 cndiff
564
564
565 diff -r ef63ca68695b -r 40a904bbbe4c c
565 diff -r ef63ca68695b -r 40a904bbbe4c c
566 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
566 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
567 +++ b/c Thu Jan 01 00:00:01 1970 +0000
567 +++ b/c Thu Jan 01 00:00:01 1970 +0000
568 @@ -0,0 +1,2 @@
568 @@ -0,0 +1,2 @@
569 +$Id$
569 +$Id$
570 +tests for different changenodes
570 +tests for different changenodes
571
571
572 $ hg qpop
572 $ hg qpop
573 popping mqtest.diff
573 popping mqtest.diff
574 patch queue now empty
574 patch queue now empty
575
575
576 qgoto, implying qpush, should expand
576 qgoto, implying qpush, should expand
577
577
578 $ hg qgoto mqtest.diff
578 $ hg qgoto mqtest.diff
579 applying mqtest.diff
579 applying mqtest.diff
580 now at: mqtest.diff
580 now at: mqtest.diff
581 $ cat c
581 $ cat c
582 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
582 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
583 tests for different changenodes
583 tests for different changenodes
584 $ hg cat c
584 $ hg cat c
585 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
585 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
586 tests for different changenodes
586 tests for different changenodes
587
587
588 Keywords should not be expanded in filelog
588 Keywords should not be expanded in filelog
589
589
590 $ hg --config 'extensions.keyword=!' cat c
590 $ hg --config 'extensions.keyword=!' cat c
591 $Id$
591 $Id$
592 tests for different changenodes
592 tests for different changenodes
593
593
594 qpop and move on
594 qpop and move on
595
595
596 $ hg qpop
596 $ hg qpop
597 popping mqtest.diff
597 popping mqtest.diff
598 patch queue now empty
598 patch queue now empty
599
599
600 Copy and show added kwfiles
600 Copy and show added kwfiles
601
601
602 $ hg cp a c
602 $ hg cp a c
603 $ hg kwfiles
603 $ hg kwfiles
604 a
604 a
605 c
605 c
606
606
607 Commit and show expansion in original and copy
607 Commit and show expansion in original and copy
608
608
609 $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
609 $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
610 committing files:
610 committing files:
611 c
611 c
612 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
612 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
613 committing manifest
613 committing manifest
614 committing changelog
614 committing changelog
615 overwriting c expanding keywords
615 overwriting c expanding keywords
616 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
616 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
617 $ cat a c
617 $ cat a c
618 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
618 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
619 do not process $Id:
619 do not process $Id:
620 xxx $
620 xxx $
621 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
621 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
622 do not process $Id:
622 do not process $Id:
623 xxx $
623 xxx $
624
624
625 Touch copied c and check its status
625 Touch copied c and check its status
626
626
627 $ touch c
627 $ touch c
628 $ hg status
628 $ hg status
629
629
630 Copy kwfile to keyword ignored file unexpanding keywords
630 Copy kwfile to keyword ignored file unexpanding keywords
631
631
632 $ hg --verbose copy a i
632 $ hg --verbose copy a i
633 copying a to i
633 copying a to i
634 overwriting i shrinking keywords
634 overwriting i shrinking keywords
635 $ head -n 1 i
635 $ head -n 1 i
636 expand $Id$
636 expand $Id$
637 $ hg forget i
637 $ hg forget i
638 $ rm i
638 $ rm i
639
639
640 Copy ignored file to ignored file: no overwriting
640 Copy ignored file to ignored file: no overwriting
641
641
642 $ hg --verbose copy b i
642 $ hg --verbose copy b i
643 copying b to i
643 copying b to i
644 $ hg forget i
644 $ hg forget i
645 $ rm i
645 $ rm i
646
646
647 cp symlink file; hg cp -A symlink file (part1)
647 cp symlink file; hg cp -A symlink file (part1)
648 - copied symlink points to kwfile: overwrite
648 - copied symlink points to kwfile: overwrite
649
649
650 #if symlink
650 #if symlink
651 $ cp sym i
651 $ cp sym i
652 $ ls -l i
652 $ ls -l i
653 -rw-r--r--* (glob)
653 -rw-r--r--* (glob)
654 $ head -1 i
654 $ head -1 i
655 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
655 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
656 $ hg copy --after --verbose sym i
656 $ hg copy --after --verbose sym i
657 copying sym to i
657 copying sym to i
658 overwriting i shrinking keywords
658 overwriting i shrinking keywords
659 $ head -1 i
659 $ head -1 i
660 expand $Id$
660 expand $Id$
661 $ hg forget i
661 $ hg forget i
662 $ rm i
662 $ rm i
663 #endif
663 #endif
664
664
665 Test different options of hg kwfiles
665 Test different options of hg kwfiles
666
666
667 $ hg kwfiles
667 $ hg kwfiles
668 a
668 a
669 c
669 c
670 $ hg -v kwfiles --ignore
670 $ hg -v kwfiles --ignore
671 I b
671 I b
672 I sym
672 I sym
673 $ hg kwfiles --all
673 $ hg kwfiles --all
674 K a
674 K a
675 K c
675 K c
676 I b
676 I b
677 I sym
677 I sym
678
678
679 Diff specific revision
679 Diff specific revision
680
680
681 $ hg diff --rev 1
681 $ hg diff --rev 1
682 diff -r ef63ca68695b c
682 diff -r ef63ca68695b c
683 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
683 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
684 +++ b/c * (glob)
684 +++ b/c * (glob)
685 @@ -0,0 +1,3 @@
685 @@ -0,0 +1,3 @@
686 +expand $Id$
686 +expand $Id$
687 +do not process $Id:
687 +do not process $Id:
688 +xxx $
688 +xxx $
689
689
690 Status after rollback:
690 Status after rollback:
691
691
692 $ hg rollback
692 $ hg rollback
693 repository tip rolled back to revision 1 (undo commit)
693 repository tip rolled back to revision 1 (undo commit)
694 working directory now based on revision 1
694 working directory now based on revision 1
695 $ hg status
695 $ hg status
696 A c
696 A c
697 $ hg update --clean
697 $ hg update --clean
698 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
698 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
699
699
700 #if symlink
700 #if symlink
701
701
702 cp symlink file; hg cp -A symlink file (part2)
702 cp symlink file; hg cp -A symlink file (part2)
703 - copied symlink points to kw ignored file: do not overwrite
703 - copied symlink points to kw ignored file: do not overwrite
704
704
705 $ cat a > i
705 $ cat a > i
706 $ ln -s i symignored
706 $ ln -s i symignored
707 $ hg commit -Am 'fake expansion in ignored and symlink' i symignored
707 $ hg commit -Am 'fake expansion in ignored and symlink' i symignored
708 $ cp symignored x
708 $ cp symignored x
709 $ hg copy --after --verbose symignored x
709 $ hg copy --after --verbose symignored x
710 copying symignored to x
710 copying symignored to x
711 $ head -n 1 x
711 $ head -n 1 x
712 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
712 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
713 $ hg forget x
713 $ hg forget x
714 $ rm x
714 $ rm x
715
715
716 $ hg rollback
716 $ hg rollback
717 repository tip rolled back to revision 1 (undo commit)
717 repository tip rolled back to revision 1 (undo commit)
718 working directory now based on revision 1
718 working directory now based on revision 1
719 $ hg update --clean
719 $ hg update --clean
720 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
720 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
721 $ rm i symignored
721 $ rm i symignored
722
722
723 #endif
723 #endif
724
724
725 Custom keywordmaps as argument to kwdemo
725 Custom keywordmaps as argument to kwdemo
726
726
727 $ hg --quiet kwdemo "Xinfo = {author}: {desc}"
727 $ hg --quiet kwdemo "Xinfo = {author}: {desc}"
728 [extensions]
728 [extensions]
729 keyword =
729 keyword =
730 [keyword]
730 [keyword]
731 ** =
731 ** =
732 b = ignore
732 b = ignore
733 demo.txt =
733 demo.txt =
734 i = ignore
734 i = ignore
735 [keywordset]
735 [keywordset]
736 svn = False
736 svn = False
737 [keywordmaps]
737 [keywordmaps]
738 Xinfo = {author}: {desc}
738 Xinfo = {author}: {desc}
739 $Xinfo: test: hg keyword configuration and expansion example $
739 $Xinfo: test: hg keyword configuration and expansion example $
740
740
741 Configure custom keywordmaps
741 Configure custom keywordmaps
742
742
743 $ cat <<EOF >>$HGRCPATH
743 $ cat <<EOF >>$HGRCPATH
744 > [keywordmaps]
744 > [keywordmaps]
745 > Id = {file} {node|short} {date|rfc822date} {author|user}
745 > Id = {file} {node|short} {date|rfc822date} {author|user}
746 > Xinfo = {author}: {desc}
746 > Xinfo = {author}: {desc}
747 > EOF
747 > EOF
748
748
749 Cat and hg cat files before custom expansion
749 Cat and hg cat files before custom expansion
750
750
751 $ cat a b
751 $ cat a b
752 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
752 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
753 do not process $Id:
753 do not process $Id:
754 xxx $
754 xxx $
755 ignore $Id$
755 ignore $Id$
756 $ hg cat sym a b && echo
756 $ hg cat sym a b && echo
757 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
757 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
758 do not process $Id:
758 do not process $Id:
759 xxx $
759 xxx $
760 ignore $Id$
760 ignore $Id$
761 a
761 a
762
762
763 Write custom keyword and prepare multi-line commit message
763 Write custom keyword and prepare multi-line commit message
764
764
765 $ echo '$Xinfo$' >> a
765 $ echo '$Xinfo$' >> a
766 $ cat <<EOF >> log
766 $ cat <<EOF >> log
767 > firstline
767 > firstline
768 > secondline
768 > secondline
769 > EOF
769 > EOF
770
770
771 Interrupted commit should not change state
771 Interrupted commit should not change state
772
772
773 $ hg commit
773 $ hg commit
774 abort: empty commit message
774 abort: empty commit message
775 [255]
775 [255]
776 $ hg status
776 $ hg status
777 M a
777 M a
778 ? c
778 ? c
779 ? log
779 ? log
780
780
781 Commit with multi-line message and custom expansion
781 Commit with multi-line message and custom expansion
782
782
783 $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
783 $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
784 committing files:
784 committing files:
785 a
785 a
786 committing manifest
786 committing manifest
787 committing changelog
787 committing changelog
788 overwriting a expanding keywords
788 overwriting a expanding keywords
789 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
789 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
790 $ rm log
790 $ rm log
791
791
792 Stat, verify and show custom expansion (firstline)
792 Stat, verify and show custom expansion (firstline)
793
793
794 $ hg status
794 $ hg status
795 ? c
795 ? c
796 $ hg verify
796 $ hg verify
797 checking changesets
797 checking changesets
798 checking manifests
798 checking manifests
799 crosschecking files in changesets and manifests
799 crosschecking files in changesets and manifests
800 checking files
800 checking files
801 3 files, 3 changesets, 4 total revisions
801 3 files, 3 changesets, 4 total revisions
802 $ cat a b
802 $ cat a b
803 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
803 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
804 do not process $Id:
804 do not process $Id:
805 xxx $
805 xxx $
806 $Xinfo: User Name <user@example.com>: firstline $
806 $Xinfo: User Name <user@example.com>: firstline $
807 ignore $Id$
807 ignore $Id$
808 $ hg cat sym a b && echo
808 $ hg cat sym a b && echo
809 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
809 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
810 do not process $Id:
810 do not process $Id:
811 xxx $
811 xxx $
812 $Xinfo: User Name <user@example.com>: firstline $
812 $Xinfo: User Name <user@example.com>: firstline $
813 ignore $Id$
813 ignore $Id$
814 a
814 a
815
815
816 annotate
816 annotate
817
817
818 $ hg annotate a
818 $ hg annotate a
819 1: expand $Id$
819 1: expand $Id$
820 1: do not process $Id:
820 1: do not process $Id:
821 1: xxx $
821 1: xxx $
822 2: $Xinfo$
822 2: $Xinfo$
823
823
824 remove with status checks
824 remove with status checks
825
825
826 $ hg debugrebuildstate
826 $ hg debugrebuildstate
827 $ hg remove a
827 $ hg remove a
828 $ hg --debug commit -m rma
828 $ hg --debug commit -m rma
829 committing files:
829 committing files:
830 committing manifest
830 committing manifest
831 committing changelog
831 committing changelog
832 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
832 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
833 $ hg status
833 $ hg status
834 ? c
834 ? c
835
835
836 Rollback, revert, and check expansion
836 Rollback, revert, and check expansion
837
837
838 $ hg rollback
838 $ hg rollback
839 repository tip rolled back to revision 2 (undo commit)
839 repository tip rolled back to revision 2 (undo commit)
840 working directory now based on revision 2
840 working directory now based on revision 2
841 $ hg status
841 $ hg status
842 R a
842 R a
843 ? c
843 ? c
844 $ hg revert --no-backup --rev tip a
844 $ hg revert --no-backup --rev tip a
845 $ cat a
845 $ cat a
846 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
846 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
847 do not process $Id:
847 do not process $Id:
848 xxx $
848 xxx $
849 $Xinfo: User Name <user@example.com>: firstline $
849 $Xinfo: User Name <user@example.com>: firstline $
850
850
851 Clone to test global and local configurations
851 Clone to test global and local configurations
852
852
853 $ cd ..
853 $ cd ..
854
854
855 Expansion in destination with global configuration
855 Expansion in destination with global configuration
856
856
857 $ hg --quiet clone Test globalconf
857 $ hg --quiet clone Test globalconf
858 $ cat globalconf/a
858 $ cat globalconf/a
859 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
859 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
860 do not process $Id:
860 do not process $Id:
861 xxx $
861 xxx $
862 $Xinfo: User Name <user@example.com>: firstline $
862 $Xinfo: User Name <user@example.com>: firstline $
863
863
864 No expansion in destination with local configuration in origin only
864 No expansion in destination with local configuration in origin only
865
865
866 $ hg --quiet --config 'keyword.**=ignore' clone Test localconf
866 $ hg --quiet --config 'keyword.**=ignore' clone Test localconf
867 $ cat localconf/a
867 $ cat localconf/a
868 expand $Id$
868 expand $Id$
869 do not process $Id:
869 do not process $Id:
870 xxx $
870 xxx $
871 $Xinfo$
871 $Xinfo$
872
872
873 Clone to test incoming
873 Clone to test incoming
874
874
875 $ hg clone -r1 Test Test-a
875 $ hg clone -r1 Test Test-a
876 adding changesets
876 adding changesets
877 adding manifests
877 adding manifests
878 adding file changes
878 adding file changes
879 added 2 changesets with 3 changes to 3 files
879 added 2 changesets with 3 changes to 3 files
880 updating to branch default
880 updating to branch default
881 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
881 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
882 $ cd Test-a
882 $ cd Test-a
883 $ cat <<EOF >> .hg/hgrc
883 $ cat <<EOF >> .hg/hgrc
884 > [paths]
884 > [paths]
885 > default = ../Test
885 > default = ../Test
886 > EOF
886 > EOF
887 $ hg incoming
887 $ hg incoming
888 comparing with $TESTTMP/Test (glob)
888 comparing with $TESTTMP/Test (glob)
889 searching for changes
889 searching for changes
890 changeset: 2:bb948857c743
890 changeset: 2:bb948857c743
891 tag: tip
891 tag: tip
892 user: User Name <user@example.com>
892 user: User Name <user@example.com>
893 date: Thu Jan 01 00:00:02 1970 +0000
893 date: Thu Jan 01 00:00:02 1970 +0000
894 summary: firstline
894 summary: firstline
895
895
896 Imported patch should not be rejected
896 Imported patch should not be rejected
897
897
898 >>> import re
898 >>> import re
899 >>> text = re.sub(r'(Id.*)', r'\1 rejecttest', open('a').read())
899 >>> text = re.sub(r'(Id.*)', r'\1 rejecttest', open('a').read())
900 >>> open('a', 'wb').write(text)
900 >>> open('a', 'wb').write(text)
901 $ hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
901 $ hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
902 committing files:
902 committing files:
903 a
903 a
904 committing manifest
904 committing manifest
905 committing changelog
905 committing changelog
906 overwriting a expanding keywords
906 overwriting a expanding keywords
907 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
907 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
908 $ hg export -o ../rejecttest.diff tip
908 $ hg export -o ../rejecttest.diff tip
909 $ cd ../Test
909 $ cd ../Test
910 $ hg import ../rejecttest.diff
910 $ hg import ../rejecttest.diff
911 applying ../rejecttest.diff
911 applying ../rejecttest.diff
912 $ cat a b
912 $ cat a b
913 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
913 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
914 do not process $Id: rejecttest
914 do not process $Id: rejecttest
915 xxx $
915 xxx $
916 $Xinfo: User Name <user@example.com>: rejects? $
916 $Xinfo: User Name <user@example.com>: rejects? $
917 ignore $Id$
917 ignore $Id$
918
918
919 $ hg rollback
919 $ hg rollback
920 repository tip rolled back to revision 2 (undo import)
920 repository tip rolled back to revision 2 (undo import)
921 working directory now based on revision 2
921 working directory now based on revision 2
922 $ hg update --clean
922 $ hg update --clean
923 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
923 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
924
924
925 kwexpand/kwshrink on selected files
925 kwexpand/kwshrink on selected files
926
926
927 $ mkdir x
927 $ mkdir x
928 $ hg copy a x/a
928 $ hg copy a x/a
929 $ hg --verbose kwshrink a
929 $ hg --verbose kwshrink a
930 overwriting a shrinking keywords
930 overwriting a shrinking keywords
931 - sleep required for dirstate.normal() check
931 - sleep required for dirstate.normal() check
932 $ sleep 1
932 $ sleep 1
933 $ hg status a
933 $ hg status a
934 $ hg --verbose kwexpand a
934 $ hg --verbose kwexpand a
935 overwriting a expanding keywords
935 overwriting a expanding keywords
936 $ hg status a
936 $ hg status a
937
937
938 kwexpand x/a should abort
938 kwexpand x/a should abort
939
939
940 $ hg --verbose kwexpand x/a
940 $ hg --verbose kwexpand x/a
941 abort: outstanding uncommitted changes
941 abort: outstanding uncommitted changes
942 [255]
942 [255]
943 $ cd x
943 $ cd x
944 $ hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
944 $ hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
945 committing files:
945 committing files:
946 x/a
946 x/a
947 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
947 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
948 committing manifest
948 committing manifest
949 committing changelog
949 committing changelog
950 overwriting x/a expanding keywords
950 overwriting x/a expanding keywords
951 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
951 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
952 $ cat a
952 $ cat a
953 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
953 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
954 do not process $Id:
954 do not process $Id:
955 xxx $
955 xxx $
956 $Xinfo: User Name <user@example.com>: xa $
956 $Xinfo: User Name <user@example.com>: xa $
957
957
958 kwshrink a inside directory x
958 kwshrink a inside directory x
959
959
960 $ hg --verbose kwshrink a
960 $ hg --verbose kwshrink a
961 overwriting x/a shrinking keywords
961 overwriting x/a shrinking keywords
962 $ cat a
962 $ cat a
963 expand $Id$
963 expand $Id$
964 do not process $Id:
964 do not process $Id:
965 xxx $
965 xxx $
966 $Xinfo$
966 $Xinfo$
967 $ cd ..
967 $ cd ..
968
968
969 kwexpand nonexistent
969 kwexpand nonexistent
970
970
971 $ hg kwexpand nonexistent
971 $ hg kwexpand nonexistent
972 nonexistent:* (glob)
972 nonexistent:* (glob)
973
973
974
974
975 #if serve
975 #if serve
976 hg serve
976 hg serve
977 - expand with hgweb file
977 - expand with hgweb file
978 - no expansion with hgweb annotate/changeset/filediff
978 - no expansion with hgweb annotate/changeset/filediff
979 - check errors
979 - check errors
980
980
981 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
981 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
982 $ cat hg.pid >> $DAEMON_PIDS
982 $ cat hg.pid >> $DAEMON_PIDS
983 $ get-with-headers.py localhost:$HGPORT 'file/tip/a/?style=raw'
983 $ get-with-headers.py localhost:$HGPORT 'file/tip/a/?style=raw'
984 200 Script output follows
984 200 Script output follows
985
985
986 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
986 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
987 do not process $Id:
987 do not process $Id:
988 xxx $
988 xxx $
989 $Xinfo: User Name <user@example.com>: firstline $
989 $Xinfo: User Name <user@example.com>: firstline $
990 $ get-with-headers.py localhost:$HGPORT 'annotate/tip/a/?style=raw'
990 $ get-with-headers.py localhost:$HGPORT 'annotate/tip/a/?style=raw'
991 200 Script output follows
991 200 Script output follows
992
992
993
993
994 user@1: expand $Id$
994 user@1: expand $Id$
995 user@1: do not process $Id:
995 user@1: do not process $Id:
996 user@1: xxx $
996 user@1: xxx $
997 user@2: $Xinfo$
997 user@2: $Xinfo$
998
998
999
999
1000
1000
1001
1001
1002 $ get-with-headers.py localhost:$HGPORT 'rev/tip/?style=raw'
1002 $ get-with-headers.py localhost:$HGPORT 'rev/tip/?style=raw'
1003 200 Script output follows
1003 200 Script output follows
1004
1004
1005
1005
1006 # HG changeset patch
1006 # HG changeset patch
1007 # User User Name <user@example.com>
1007 # User User Name <user@example.com>
1008 # Date 3 0
1008 # Date 3 0
1009 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
1009 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
1010 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
1010 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
1011 xa
1011 xa
1012
1012
1013 diff -r bb948857c743 -r b4560182a3f9 x/a
1013 diff -r bb948857c743 -r b4560182a3f9 x/a
1014 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1014 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1015 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
1015 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
1016 @@ -0,0 +1,4 @@
1016 @@ -0,0 +1,4 @@
1017 +expand $Id$
1017 +expand $Id$
1018 +do not process $Id:
1018 +do not process $Id:
1019 +xxx $
1019 +xxx $
1020 +$Xinfo$
1020 +$Xinfo$
1021
1021
1022 $ get-with-headers.py localhost:$HGPORT 'diff/bb948857c743/a?style=raw'
1022 $ get-with-headers.py localhost:$HGPORT 'diff/bb948857c743/a?style=raw'
1023 200 Script output follows
1023 200 Script output follows
1024
1024
1025
1025
1026 diff -r ef63ca68695b -r bb948857c743 a
1026 diff -r ef63ca68695b -r bb948857c743 a
1027 --- a/a Thu Jan 01 00:00:00 1970 +0000
1027 --- a/a Thu Jan 01 00:00:00 1970 +0000
1028 +++ b/a Thu Jan 01 00:00:02 1970 +0000
1028 +++ b/a Thu Jan 01 00:00:02 1970 +0000
1029 @@ -1,3 +1,4 @@
1029 @@ -1,3 +1,4 @@
1030 expand $Id$
1030 expand $Id$
1031 do not process $Id:
1031 do not process $Id:
1032 xxx $
1032 xxx $
1033 +$Xinfo$
1033 +$Xinfo$
1034
1034
1035
1035
1036
1036
1037
1037
1038 $ cat errors.log
1038 $ cat errors.log
1039 #endif
1039 #endif
1040
1040
1041 Prepare merge and resolve tests
1041 Prepare merge and resolve tests
1042
1042
1043 $ echo '$Id$' > m
1043 $ echo '$Id$' > m
1044 $ hg add m
1044 $ hg add m
1045 $ hg commit -m 4kw
1045 $ hg commit -m 4kw
1046 $ echo foo >> m
1046 $ echo foo >> m
1047 $ hg commit -m 5foo
1047 $ hg commit -m 5foo
1048
1048
1049 simplemerge
1049 simplemerge
1050
1050
1051 $ hg update 4
1051 $ hg update 4
1052 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1052 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1053 $ echo foo >> m
1053 $ echo foo >> m
1054 $ hg commit -m 6foo
1054 $ hg commit -m 6foo
1055 created new head
1055 created new head
1056 $ hg merge
1056 $ hg merge
1057 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1057 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1058 (branch merge, don't forget to commit)
1058 (branch merge, don't forget to commit)
1059 $ hg commit -m simplemerge
1059 $ hg commit -m simplemerge
1060 $ cat m
1060 $ cat m
1061 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
1061 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
1062 foo
1062 foo
1063
1063
1064 conflict: keyword should stay outside conflict zone
1064 conflict: keyword should stay outside conflict zone
1065
1065
1066 $ hg update 4
1066 $ hg update 4
1067 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1067 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1068 $ echo bar >> m
1068 $ echo bar >> m
1069 $ hg commit -m 8bar
1069 $ hg commit -m 8bar
1070 created new head
1070 created new head
1071 $ hg merge
1071 $ hg merge
1072 merging m
1072 merging m
1073 warning: conflicts while merging m! (edit, then use 'hg resolve --mark')
1073 warning: conflicts while merging m! (edit, then use 'hg resolve --mark')
1074 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1074 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1075 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1075 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1076 [1]
1076 [1]
1077 $ cat m
1077 $ cat m
1078 $Id$
1078 $Id$
1079 <<<<<<< local: 88a80c8d172e - test: 8bar
1079 <<<<<<< local: 88a80c8d172e - test: 8bar
1080 bar
1080 bar
1081 =======
1081 =======
1082 foo
1082 foo
1083 >>>>>>> other: 85d2d2d732a5 - test: simplemerge
1083 >>>>>>> other: 85d2d2d732a5 - test: simplemerge
1084
1084
1085 resolve to local, m must contain hash of last change (local parent)
1085 resolve to local, m must contain hash of last change (local parent)
1086
1086
1087 $ hg resolve -t internal:local -a
1087 $ hg resolve -t internal:local -a
1088 (no more unresolved files)
1088 (no more unresolved files)
1089 $ hg commit -m localresolve
1089 $ hg commit -m localresolve
1090 $ cat m
1090 $ cat m
1091 $Id: m 88a80c8d172e Thu, 01 Jan 1970 00:00:00 +0000 test $
1091 $Id: m 88a80c8d172e Thu, 01 Jan 1970 00:00:00 +0000 test $
1092 bar
1092 bar
1093
1093
1094 Test restricted mode with transplant -b
1094 Test restricted mode with transplant -b
1095
1095
1096 $ hg update 6
1096 $ hg update 6
1097 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1097 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1098 $ hg branch foo
1098 $ hg branch foo
1099 marked working directory as branch foo
1099 marked working directory as branch foo
1100 (branches are permanent and global, did you want a bookmark?)
1100 (branches are permanent and global, did you want a bookmark?)
1101 $ mv a a.bak
1101 $ mv a a.bak
1102 $ echo foobranch > a
1102 $ echo foobranch > a
1103 $ cat a.bak >> a
1103 $ cat a.bak >> a
1104 $ rm a.bak
1104 $ rm a.bak
1105 $ hg commit -m 9foobranch
1105 $ hg commit -m 9foobranch
1106 $ hg update default
1106 $ hg update default
1107 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1107 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1108 $ hg -y transplant -b foo tip
1108 $ hg -y transplant -b foo tip
1109 applying 4aa30d025d50
1109 applying 4aa30d025d50
1110 4aa30d025d50 transplanted to e00abbf63521
1110 4aa30d025d50 transplanted to e00abbf63521
1111
1111
1112 Expansion in changeset but not in file
1112 Expansion in changeset but not in file
1113
1113
1114 $ hg tip -p
1114 $ hg tip -p
1115 changeset: 11:e00abbf63521
1115 changeset: 11:e00abbf63521
1116 tag: tip
1116 tag: tip
1117 parent: 9:800511b3a22d
1117 parent: 9:800511b3a22d
1118 user: test
1118 user: test
1119 date: Thu Jan 01 00:00:00 1970 +0000
1119 date: Thu Jan 01 00:00:00 1970 +0000
1120 summary: 9foobranch
1120 summary: 9foobranch
1121
1121
1122 diff -r 800511b3a22d -r e00abbf63521 a
1122 diff -r 800511b3a22d -r e00abbf63521 a
1123 --- a/a Thu Jan 01 00:00:00 1970 +0000
1123 --- a/a Thu Jan 01 00:00:00 1970 +0000
1124 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1124 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1125 @@ -1,3 +1,4 @@
1125 @@ -1,3 +1,4 @@
1126 +foobranch
1126 +foobranch
1127 expand $Id$
1127 expand $Id$
1128 do not process $Id:
1128 do not process $Id:
1129 xxx $
1129 xxx $
1130
1130
1131 $ head -n 2 a
1131 $ head -n 2 a
1132 foobranch
1132 foobranch
1133 expand $Id: a e00abbf63521 Thu, 01 Jan 1970 00:00:00 +0000 test $
1133 expand $Id: a e00abbf63521 Thu, 01 Jan 1970 00:00:00 +0000 test $
1134
1134
1135 Turn off expansion
1135 Turn off expansion
1136
1136
1137 $ hg -q rollback
1137 $ hg -q rollback
1138 $ hg -q update -C
1138 $ hg -q update -C
1139
1139
1140 kwshrink with unknown file u
1140 kwshrink with unknown file u
1141
1141
1142 $ cp a u
1142 $ cp a u
1143 $ hg --verbose kwshrink
1143 $ hg --verbose kwshrink
1144 overwriting a shrinking keywords
1144 overwriting a shrinking keywords
1145 overwriting m shrinking keywords
1145 overwriting m shrinking keywords
1146 overwriting x/a shrinking keywords
1146 overwriting x/a shrinking keywords
1147
1147
1148 Keywords shrunk in working directory, but not yet disabled
1148 Keywords shrunk in working directory, but not yet disabled
1149 - cat shows unexpanded keywords
1149 - cat shows unexpanded keywords
1150 - hg cat shows expanded keywords
1150 - hg cat shows expanded keywords
1151
1151
1152 $ cat a b
1152 $ cat a b
1153 expand $Id$
1153 expand $Id$
1154 do not process $Id:
1154 do not process $Id:
1155 xxx $
1155 xxx $
1156 $Xinfo$
1156 $Xinfo$
1157 ignore $Id$
1157 ignore $Id$
1158 $ hg cat sym a b && echo
1158 $ hg cat sym a b && echo
1159 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
1159 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
1160 do not process $Id:
1160 do not process $Id:
1161 xxx $
1161 xxx $
1162 $Xinfo: User Name <user@example.com>: firstline $
1162 $Xinfo: User Name <user@example.com>: firstline $
1163 ignore $Id$
1163 ignore $Id$
1164 a
1164 a
1165
1165
1166 Now disable keyword expansion
1166 Now disable keyword expansion
1167
1167
1168 $ cp $HGRCPATH $HGRCPATH.backup
1168 $ cp $HGRCPATH $HGRCPATH.backup
1169 $ rm "$HGRCPATH"
1169 $ rm "$HGRCPATH"
1170 $ cat a b
1170 $ cat a b
1171 expand $Id$
1171 expand $Id$
1172 do not process $Id:
1172 do not process $Id:
1173 xxx $
1173 xxx $
1174 $Xinfo$
1174 $Xinfo$
1175 ignore $Id$
1175 ignore $Id$
1176 $ hg cat sym a b && echo
1176 $ hg cat sym a b && echo
1177 expand $Id$
1177 expand $Id$
1178 do not process $Id:
1178 do not process $Id:
1179 xxx $
1179 xxx $
1180 $Xinfo$
1180 $Xinfo$
1181 ignore $Id$
1181 ignore $Id$
1182 a
1182 a
1183
1183
1184 enable keyword expansion again
1184 enable keyword expansion again
1185
1185
1186 $ cat $HGRCPATH.backup >> $HGRCPATH
1186 $ cat $HGRCPATH.backup >> $HGRCPATH
1187
1187
1188 Test restricted mode with unshelve
1188 Test restricted mode with unshelve
1189
1189
1190 $ cat <<EOF >> $HGRCPATH
1190 $ cat <<EOF >> $HGRCPATH
1191 > [extensions]
1191 > [extensions]
1192 > shelve =
1192 > shelve =
1193 > EOF
1193 > EOF
1194
1194
1195 $ echo xxxx >> a
1195 $ echo xxxx >> a
1196 $ hg diff
1196 $ hg diff
1197 diff -r 800511b3a22d a
1197 diff -r 800511b3a22d a
1198 --- a/a Thu Jan 01 00:00:00 1970 +0000
1198 --- a/a Thu Jan 01 00:00:00 1970 +0000
1199 +++ b/a * (glob)
1199 +++ b/a * (glob)
1200 @@ -2,3 +2,4 @@
1200 @@ -2,3 +2,4 @@
1201 do not process $Id:
1201 do not process $Id:
1202 xxx $
1202 xxx $
1203 $Xinfo$
1203 $Xinfo$
1204 +xxxx
1204 +xxxx
1205 $ hg shelve -q --name tmp
1205 $ hg shelve -q --name tmp
1206 $ hg shelve --list --patch
1206 $ hg shelve --list --patch
1207 tmp (*)* changes to: localresolve (glob)
1207 tmp (*)* changes to: localresolve (glob)
1208
1208
1209 diff --git a/a b/a
1209 diff --git a/a b/a
1210 --- a/a
1210 --- a/a
1211 +++ b/a
1211 +++ b/a
1212 @@ -2,3 +2,4 @@
1212 @@ -2,3 +2,4 @@
1213 do not process $Id:
1213 do not process $Id:
1214 xxx $
1214 xxx $
1215 $Xinfo$
1215 $Xinfo$
1216 +xxxx
1216 +xxxx
1217
1217
1218 $ hg update -q -C 10
1218 $ hg update -q -C 10
1219 $ hg unshelve -q tmp
1219 $ hg unshelve -q tmp
1220 $ hg diff
1220 $ hg diff
1221 diff -r 4aa30d025d50 a
1221 diff -r 4aa30d025d50 a
1222 --- a/a Thu Jan 01 00:00:00 1970 +0000
1222 --- a/a Thu Jan 01 00:00:00 1970 +0000
1223 +++ b/a * (glob)
1223 +++ b/a * (glob)
1224 @@ -3,3 +3,4 @@
1224 @@ -3,3 +3,4 @@
1225 do not process $Id:
1225 do not process $Id:
1226 xxx $
1226 xxx $
1227 $Xinfo$
1227 $Xinfo$
1228 +xxxx
1228 +xxxx
1229
1229
1230 Test restricted mode with rebase
1230 Test restricted mode with rebase
1231
1231
1232 $ cat <<EOF >> $HGRCPATH
1232 $ cat <<EOF >> $HGRCPATH
1233 > [extensions]
1233 > [extensions]
1234 > rebase =
1234 > rebase =
1235 > EOF
1235 > EOF
1236
1236
1237 $ hg update -q -C 9
1237 $ hg update -q -C 9
1238
1238
1239 $ echo xxxx >> a
1239 $ echo xxxx >> a
1240 $ hg commit -m '#11'
1240 $ hg commit -m '#11'
1241 $ hg diff -c 11
1241 $ hg diff -c 11
1242 diff -r 800511b3a22d -r b07670694489 a
1242 diff -r 800511b3a22d -r b07670694489 a
1243 --- a/a Thu Jan 01 00:00:00 1970 +0000
1243 --- a/a Thu Jan 01 00:00:00 1970 +0000
1244 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1244 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1245 @@ -2,3 +2,4 @@
1245 @@ -2,3 +2,4 @@
1246 do not process $Id:
1246 do not process $Id:
1247 xxx $
1247 xxx $
1248 $Xinfo$
1248 $Xinfo$
1249 +xxxx
1249 +xxxx
1250
1250
1251 $ hg diff -c 10
1251 $ hg diff -c 10
1252 diff -r 27d48ee14f67 -r 4aa30d025d50 a
1252 diff -r 27d48ee14f67 -r 4aa30d025d50 a
1253 --- a/a Thu Jan 01 00:00:00 1970 +0000
1253 --- a/a Thu Jan 01 00:00:00 1970 +0000
1254 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1254 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1255 @@ -1,3 +1,4 @@
1255 @@ -1,3 +1,4 @@
1256 +foobranch
1256 +foobranch
1257 expand $Id$
1257 expand $Id$
1258 do not process $Id:
1258 do not process $Id:
1259 xxx $
1259 xxx $
1260
1260
1261 $ hg rebase -q -s 10 -d 11 --keep
1261 $ hg rebase -q -s 10 -d 11 --keep
1262 $ hg diff -r 9 -r 12 a
1262 $ hg diff -r 9 -r 12 a
1263 diff -r 800511b3a22d -r 1939b927726c a
1263 diff -r 800511b3a22d -r 1939b927726c a
1264 --- a/a Thu Jan 01 00:00:00 1970 +0000
1264 --- a/a Thu Jan 01 00:00:00 1970 +0000
1265 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1265 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1266 @@ -1,4 +1,6 @@
1266 @@ -1,4 +1,6 @@
1267 +foobranch
1267 +foobranch
1268 expand $Id$
1268 expand $Id$
1269 do not process $Id:
1269 do not process $Id:
1270 xxx $
1270 xxx $
1271 $Xinfo$
1271 $Xinfo$
1272 +xxxx
1272 +xxxx
1273
1273
1274 Test restricted mode with graft
1274 Test restricted mode with graft
1275
1275
1276 $ hg graft -q 10
1276 $ hg graft -q 10
1277 $ hg diff -r 9 -r 13 a
1277 $ hg diff -r 9 -r 13 a
1278 diff -r 800511b3a22d -r 01a68de1003a a
1278 diff -r 800511b3a22d -r 01a68de1003a a
1279 --- a/a Thu Jan 01 00:00:00 1970 +0000
1279 --- a/a Thu Jan 01 00:00:00 1970 +0000
1280 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1280 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1281 @@ -1,4 +1,6 @@
1281 @@ -1,4 +1,6 @@
1282 +foobranch
1282 +foobranch
1283 expand $Id$
1283 expand $Id$
1284 do not process $Id:
1284 do not process $Id:
1285 xxx $
1285 xxx $
1286 $Xinfo$
1286 $Xinfo$
1287 +xxxx
1287 +xxxx
1288
1288
1289 Test restricted mode with backout
1289 Test restricted mode with backout
1290
1290
1291 $ hg backout -q 11
1291 $ hg backout -q 11 --no-commit
1292 $ hg diff a
1292 $ hg diff a
1293 diff -r 01a68de1003a a
1293 diff -r 01a68de1003a a
1294 --- a/a Thu Jan 01 00:00:00 1970 +0000
1294 --- a/a Thu Jan 01 00:00:00 1970 +0000
1295 +++ b/a * (glob)
1295 +++ b/a * (glob)
1296 @@ -3,4 +3,3 @@
1296 @@ -3,4 +3,3 @@
1297 do not process $Id:
1297 do not process $Id:
1298 xxx $
1298 xxx $
1299 $Xinfo$
1299 $Xinfo$
1300 -xxxx
1300 -xxxx
1301
1301
1302 Test restricted mode with histedit
1302 Test restricted mode with histedit
1303
1303
1304 $ cat <<EOF >> $HGRCPATH
1304 $ cat <<EOF >> $HGRCPATH
1305 > [extensions]
1305 > [extensions]
1306 > histedit =
1306 > histedit =
1307 > EOF
1307 > EOF
1308
1308
1309 $ hg commit -m 'backout #11'
1309 $ hg commit -m 'backout #11'
1310 $ hg histedit -q --command - 13 <<EOF
1310 $ hg histedit -q --command - 13 <<EOF
1311 > pick 49f5f2d940c3 14 backout #11
1311 > pick 49f5f2d940c3 14 backout #11
1312 > pick 01a68de1003a 13 9foobranch
1312 > pick 01a68de1003a 13 9foobranch
1313 > EOF
1313 > EOF
1314
1314
1315 Test restricted mode with fetch (with merge)
1315 Test restricted mode with fetch (with merge)
1316
1316
1317 $ cat <<EOF >> $HGRCPATH
1317 $ cat <<EOF >> $HGRCPATH
1318 > [extensions]
1318 > [extensions]
1319 > fetch =
1319 > fetch =
1320 > EOF
1320 > EOF
1321
1321
1322 $ hg clone -q -r 9 . ../fetch-merge
1322 $ hg clone -q -r 9 . ../fetch-merge
1323 $ cd ../fetch-merge
1323 $ cd ../fetch-merge
1324 $ hg -R ../Test export 10 | hg import -q -
1324 $ hg -R ../Test export 10 | hg import -q -
1325 $ hg fetch -q -r 11
1325 $ hg fetch -q -r 11
1326 $ hg diff -r 9 a
1326 $ hg diff -r 9 a
1327 diff -r 800511b3a22d a
1327 diff -r 800511b3a22d a
1328 --- a/a Thu Jan 01 00:00:00 1970 +0000
1328 --- a/a Thu Jan 01 00:00:00 1970 +0000
1329 +++ b/a * (glob)
1329 +++ b/a * (glob)
1330 @@ -1,4 +1,6 @@
1330 @@ -1,4 +1,6 @@
1331 +foobranch
1331 +foobranch
1332 expand $Id$
1332 expand $Id$
1333 do not process $Id:
1333 do not process $Id:
1334 xxx $
1334 xxx $
1335 $Xinfo$
1335 $Xinfo$
1336 +xxxx
1336 +xxxx
1337
1337
1338 $ cd ..
1338 $ cd ..
@@ -1,1759 +1,1759 b''
1 Let commit recurse into subrepos by default to match pre-2.0 behavior:
1 Let commit recurse into subrepos by default to match pre-2.0 behavior:
2
2
3 $ echo "[ui]" >> $HGRCPATH
3 $ echo "[ui]" >> $HGRCPATH
4 $ echo "commitsubrepos = Yes" >> $HGRCPATH
4 $ echo "commitsubrepos = Yes" >> $HGRCPATH
5
5
6 $ hg init t
6 $ hg init t
7 $ cd t
7 $ cd t
8
8
9 first revision, no sub
9 first revision, no sub
10
10
11 $ echo a > a
11 $ echo a > a
12 $ hg ci -Am0
12 $ hg ci -Am0
13 adding a
13 adding a
14
14
15 add first sub
15 add first sub
16
16
17 $ echo s = s > .hgsub
17 $ echo s = s > .hgsub
18 $ hg add .hgsub
18 $ hg add .hgsub
19 $ hg init s
19 $ hg init s
20 $ echo a > s/a
20 $ echo a > s/a
21
21
22 Issue2232: committing a subrepo without .hgsub
22 Issue2232: committing a subrepo without .hgsub
23
23
24 $ hg ci -mbad s
24 $ hg ci -mbad s
25 abort: can't commit subrepos without .hgsub
25 abort: can't commit subrepos without .hgsub
26 [255]
26 [255]
27
27
28 $ hg -R s add s/a
28 $ hg -R s add s/a
29 $ hg files -S
29 $ hg files -S
30 .hgsub
30 .hgsub
31 a
31 a
32 s/a (glob)
32 s/a (glob)
33
33
34 $ hg -R s ci -Ams0
34 $ hg -R s ci -Ams0
35 $ hg sum
35 $ hg sum
36 parent: 0:f7b1eb17ad24 tip
36 parent: 0:f7b1eb17ad24 tip
37 0
37 0
38 branch: default
38 branch: default
39 commit: 1 added, 1 subrepos
39 commit: 1 added, 1 subrepos
40 update: (current)
40 update: (current)
41 phases: 1 draft
41 phases: 1 draft
42 $ hg ci -m1
42 $ hg ci -m1
43
43
44 test handling .hgsubstate "added" explicitly.
44 test handling .hgsubstate "added" explicitly.
45
45
46 $ hg parents --template '{node}\n{files}\n'
46 $ hg parents --template '{node}\n{files}\n'
47 7cf8cfea66e410e8e3336508dfeec07b3192de51
47 7cf8cfea66e410e8e3336508dfeec07b3192de51
48 .hgsub .hgsubstate
48 .hgsub .hgsubstate
49 $ hg rollback -q
49 $ hg rollback -q
50 $ hg add .hgsubstate
50 $ hg add .hgsubstate
51 $ hg ci -m1
51 $ hg ci -m1
52 $ hg parents --template '{node}\n{files}\n'
52 $ hg parents --template '{node}\n{files}\n'
53 7cf8cfea66e410e8e3336508dfeec07b3192de51
53 7cf8cfea66e410e8e3336508dfeec07b3192de51
54 .hgsub .hgsubstate
54 .hgsub .hgsubstate
55
55
56 Revert subrepo and test subrepo fileset keyword:
56 Revert subrepo and test subrepo fileset keyword:
57
57
58 $ echo b > s/a
58 $ echo b > s/a
59 $ hg revert --dry-run "set:subrepo('glob:s*')"
59 $ hg revert --dry-run "set:subrepo('glob:s*')"
60 reverting subrepo s
60 reverting subrepo s
61 reverting s/a (glob)
61 reverting s/a (glob)
62 $ cat s/a
62 $ cat s/a
63 b
63 b
64 $ hg revert "set:subrepo('glob:s*')"
64 $ hg revert "set:subrepo('glob:s*')"
65 reverting subrepo s
65 reverting subrepo s
66 reverting s/a (glob)
66 reverting s/a (glob)
67 $ cat s/a
67 $ cat s/a
68 a
68 a
69 $ rm s/a.orig
69 $ rm s/a.orig
70
70
71 Revert subrepo with no backup. The "reverting s/a" line is gone since
71 Revert subrepo with no backup. The "reverting s/a" line is gone since
72 we're really running 'hg update' in the subrepo:
72 we're really running 'hg update' in the subrepo:
73
73
74 $ echo b > s/a
74 $ echo b > s/a
75 $ hg revert --no-backup s
75 $ hg revert --no-backup s
76 reverting subrepo s
76 reverting subrepo s
77
77
78 Issue2022: update -C
78 Issue2022: update -C
79
79
80 $ echo b > s/a
80 $ echo b > s/a
81 $ hg sum
81 $ hg sum
82 parent: 1:7cf8cfea66e4 tip
82 parent: 1:7cf8cfea66e4 tip
83 1
83 1
84 branch: default
84 branch: default
85 commit: 1 subrepos
85 commit: 1 subrepos
86 update: (current)
86 update: (current)
87 phases: 2 draft
87 phases: 2 draft
88 $ hg co -C 1
88 $ hg co -C 1
89 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 $ hg sum
90 $ hg sum
91 parent: 1:7cf8cfea66e4 tip
91 parent: 1:7cf8cfea66e4 tip
92 1
92 1
93 branch: default
93 branch: default
94 commit: (clean)
94 commit: (clean)
95 update: (current)
95 update: (current)
96 phases: 2 draft
96 phases: 2 draft
97
97
98 commands that require a clean repo should respect subrepos
98 commands that require a clean repo should respect subrepos
99
99
100 $ echo b >> s/a
100 $ echo b >> s/a
101 $ hg backout tip
101 $ hg backout tip
102 abort: uncommitted changes in subrepository 's'
102 abort: uncommitted changes in subrepository 's'
103 [255]
103 [255]
104 $ hg revert -C -R s s/a
104 $ hg revert -C -R s s/a
105
105
106 add sub sub
106 add sub sub
107
107
108 $ echo ss = ss > s/.hgsub
108 $ echo ss = ss > s/.hgsub
109 $ hg init s/ss
109 $ hg init s/ss
110 $ echo a > s/ss/a
110 $ echo a > s/ss/a
111 $ hg -R s add s/.hgsub
111 $ hg -R s add s/.hgsub
112 $ hg -R s/ss add s/ss/a
112 $ hg -R s/ss add s/ss/a
113 $ hg sum
113 $ hg sum
114 parent: 1:7cf8cfea66e4 tip
114 parent: 1:7cf8cfea66e4 tip
115 1
115 1
116 branch: default
116 branch: default
117 commit: 1 subrepos
117 commit: 1 subrepos
118 update: (current)
118 update: (current)
119 phases: 2 draft
119 phases: 2 draft
120 $ hg ci -m2
120 $ hg ci -m2
121 committing subrepository s
121 committing subrepository s
122 committing subrepository s/ss (glob)
122 committing subrepository s/ss (glob)
123 $ hg sum
123 $ hg sum
124 parent: 2:df30734270ae tip
124 parent: 2:df30734270ae tip
125 2
125 2
126 branch: default
126 branch: default
127 commit: (clean)
127 commit: (clean)
128 update: (current)
128 update: (current)
129 phases: 3 draft
129 phases: 3 draft
130
130
131 test handling .hgsubstate "modified" explicitly.
131 test handling .hgsubstate "modified" explicitly.
132
132
133 $ hg parents --template '{node}\n{files}\n'
133 $ hg parents --template '{node}\n{files}\n'
134 df30734270ae757feb35e643b7018e818e78a9aa
134 df30734270ae757feb35e643b7018e818e78a9aa
135 .hgsubstate
135 .hgsubstate
136 $ hg rollback -q
136 $ hg rollback -q
137 $ hg status -A .hgsubstate
137 $ hg status -A .hgsubstate
138 M .hgsubstate
138 M .hgsubstate
139 $ hg ci -m2
139 $ hg ci -m2
140 $ hg parents --template '{node}\n{files}\n'
140 $ hg parents --template '{node}\n{files}\n'
141 df30734270ae757feb35e643b7018e818e78a9aa
141 df30734270ae757feb35e643b7018e818e78a9aa
142 .hgsubstate
142 .hgsubstate
143
143
144 bump sub rev (and check it is ignored by ui.commitsubrepos)
144 bump sub rev (and check it is ignored by ui.commitsubrepos)
145
145
146 $ echo b > s/a
146 $ echo b > s/a
147 $ hg -R s ci -ms1
147 $ hg -R s ci -ms1
148 $ hg --config ui.commitsubrepos=no ci -m3
148 $ hg --config ui.commitsubrepos=no ci -m3
149
149
150 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
150 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
151
151
152 $ echo c > s/a
152 $ echo c > s/a
153 $ hg --config ui.commitsubrepos=no ci -m4
153 $ hg --config ui.commitsubrepos=no ci -m4
154 abort: uncommitted changes in subrepository 's'
154 abort: uncommitted changes in subrepository 's'
155 (use --subrepos for recursive commit)
155 (use --subrepos for recursive commit)
156 [255]
156 [255]
157 $ hg id
157 $ hg id
158 f6affe3fbfaa+ tip
158 f6affe3fbfaa+ tip
159 $ hg -R s ci -mc
159 $ hg -R s ci -mc
160 $ hg id
160 $ hg id
161 f6affe3fbfaa+ tip
161 f6affe3fbfaa+ tip
162 $ echo d > s/a
162 $ echo d > s/a
163 $ hg ci -m4
163 $ hg ci -m4
164 committing subrepository s
164 committing subrepository s
165 $ hg tip -R s
165 $ hg tip -R s
166 changeset: 4:02dcf1d70411
166 changeset: 4:02dcf1d70411
167 tag: tip
167 tag: tip
168 user: test
168 user: test
169 date: Thu Jan 01 00:00:00 1970 +0000
169 date: Thu Jan 01 00:00:00 1970 +0000
170 summary: 4
170 summary: 4
171
171
172
172
173 check caching
173 check caching
174
174
175 $ hg co 0
175 $ hg co 0
176 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
176 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
177 $ hg debugsub
177 $ hg debugsub
178
178
179 restore
179 restore
180
180
181 $ hg co
181 $ hg co
182 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
182 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
183 $ hg debugsub
183 $ hg debugsub
184 path s
184 path s
185 source s
185 source s
186 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
186 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
187
187
188 new branch for merge tests
188 new branch for merge tests
189
189
190 $ hg co 1
190 $ hg co 1
191 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
192 $ echo t = t >> .hgsub
192 $ echo t = t >> .hgsub
193 $ hg init t
193 $ hg init t
194 $ echo t > t/t
194 $ echo t > t/t
195 $ hg -R t add t
195 $ hg -R t add t
196 adding t/t (glob)
196 adding t/t (glob)
197
197
198 5
198 5
199
199
200 $ hg ci -m5 # add sub
200 $ hg ci -m5 # add sub
201 committing subrepository t
201 committing subrepository t
202 created new head
202 created new head
203 $ echo t2 > t/t
203 $ echo t2 > t/t
204
204
205 6
205 6
206
206
207 $ hg st -R s
207 $ hg st -R s
208 $ hg ci -m6 # change sub
208 $ hg ci -m6 # change sub
209 committing subrepository t
209 committing subrepository t
210 $ hg debugsub
210 $ hg debugsub
211 path s
211 path s
212 source s
212 source s
213 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
213 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
214 path t
214 path t
215 source t
215 source t
216 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
216 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
217 $ echo t3 > t/t
217 $ echo t3 > t/t
218
218
219 7
219 7
220
220
221 $ hg ci -m7 # change sub again for conflict test
221 $ hg ci -m7 # change sub again for conflict test
222 committing subrepository t
222 committing subrepository t
223 $ hg rm .hgsub
223 $ hg rm .hgsub
224
224
225 8
225 8
226
226
227 $ hg ci -m8 # remove sub
227 $ hg ci -m8 # remove sub
228
228
229 test handling .hgsubstate "removed" explicitly.
229 test handling .hgsubstate "removed" explicitly.
230
230
231 $ hg parents --template '{node}\n{files}\n'
231 $ hg parents --template '{node}\n{files}\n'
232 96615c1dad2dc8e3796d7332c77ce69156f7b78e
232 96615c1dad2dc8e3796d7332c77ce69156f7b78e
233 .hgsub .hgsubstate
233 .hgsub .hgsubstate
234 $ hg rollback -q
234 $ hg rollback -q
235 $ hg remove .hgsubstate
235 $ hg remove .hgsubstate
236 $ hg ci -m8
236 $ hg ci -m8
237 $ hg parents --template '{node}\n{files}\n'
237 $ hg parents --template '{node}\n{files}\n'
238 96615c1dad2dc8e3796d7332c77ce69156f7b78e
238 96615c1dad2dc8e3796d7332c77ce69156f7b78e
239 .hgsub .hgsubstate
239 .hgsub .hgsubstate
240
240
241 merge tests
241 merge tests
242
242
243 $ hg co -C 3
243 $ hg co -C 3
244 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
244 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
245 $ hg merge 5 # test adding
245 $ hg merge 5 # test adding
246 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
246 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
247 (branch merge, don't forget to commit)
247 (branch merge, don't forget to commit)
248 $ hg debugsub
248 $ hg debugsub
249 path s
249 path s
250 source s
250 source s
251 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
251 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
252 path t
252 path t
253 source t
253 source t
254 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
254 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
255 $ hg ci -m9
255 $ hg ci -m9
256 created new head
256 created new head
257 $ hg merge 6 --debug # test change
257 $ hg merge 6 --debug # test change
258 searching for copies back to rev 2
258 searching for copies back to rev 2
259 resolving manifests
259 resolving manifests
260 branchmerge: True, force: False, partial: False
260 branchmerge: True, force: False, partial: False
261 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
261 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
262 .hgsubstate: versions differ -> m (premerge)
262 .hgsubstate: versions differ -> m (premerge)
263 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
263 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
264 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
264 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
265 getting subrepo t
265 getting subrepo t
266 resolving manifests
266 resolving manifests
267 branchmerge: False, force: False, partial: False
267 branchmerge: False, force: False, partial: False
268 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
268 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
269 t: remote is newer -> g
269 t: remote is newer -> g
270 getting t
270 getting t
271 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
271 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
272 (branch merge, don't forget to commit)
272 (branch merge, don't forget to commit)
273 $ hg debugsub
273 $ hg debugsub
274 path s
274 path s
275 source s
275 source s
276 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
276 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
277 path t
277 path t
278 source t
278 source t
279 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
279 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
280 $ echo conflict > t/t
280 $ echo conflict > t/t
281 $ hg ci -m10
281 $ hg ci -m10
282 committing subrepository t
282 committing subrepository t
283 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
283 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
284 searching for copies back to rev 2
284 searching for copies back to rev 2
285 resolving manifests
285 resolving manifests
286 branchmerge: True, force: False, partial: False
286 branchmerge: True, force: False, partial: False
287 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
287 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
288 .hgsubstate: versions differ -> m (premerge)
288 .hgsubstate: versions differ -> m (premerge)
289 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
289 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
290 subrepo t: both sides changed
290 subrepo t: both sides changed
291 subrepository t diverged (local revision: 20a0db6fbf6c, remote revision: 7af322bc1198)
291 subrepository t diverged (local revision: 20a0db6fbf6c, remote revision: 7af322bc1198)
292 (M)erge, keep (l)ocal or keep (r)emote? m
292 (M)erge, keep (l)ocal or keep (r)emote? m
293 merging subrepo t
293 merging subrepo t
294 searching for copies back to rev 2
294 searching for copies back to rev 2
295 resolving manifests
295 resolving manifests
296 branchmerge: True, force: False, partial: False
296 branchmerge: True, force: False, partial: False
297 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
297 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
298 preserving t for resolve of t
298 preserving t for resolve of t
299 t: versions differ -> m (premerge)
299 t: versions differ -> m (premerge)
300 picked tool ':merge' for t (binary False symlink False changedelete False)
300 picked tool ':merge' for t (binary False symlink False changedelete False)
301 merging t
301 merging t
302 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
302 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
303 t: versions differ -> m (merge)
303 t: versions differ -> m (merge)
304 picked tool ':merge' for t (binary False symlink False changedelete False)
304 picked tool ':merge' for t (binary False symlink False changedelete False)
305 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
305 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
306 warning: conflicts while merging t! (edit, then use 'hg resolve --mark')
306 warning: conflicts while merging t! (edit, then use 'hg resolve --mark')
307 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
307 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
308 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
308 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
309 subrepo t: merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
309 subrepo t: merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
310 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
311 (branch merge, don't forget to commit)
311 (branch merge, don't forget to commit)
312
312
313 should conflict
313 should conflict
314
314
315 $ cat t/t
315 $ cat t/t
316 <<<<<<< local: 20a0db6fbf6c - test: 10
316 <<<<<<< local: 20a0db6fbf6c - test: 10
317 conflict
317 conflict
318 =======
318 =======
319 t3
319 t3
320 >>>>>>> other: 7af322bc1198 - test: 7
320 >>>>>>> other: 7af322bc1198 - test: 7
321
321
322 11: remove subrepo t
322 11: remove subrepo t
323
323
324 $ hg co -C 5
324 $ hg co -C 5
325 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
325 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
326 $ hg revert -r 4 .hgsub # remove t
326 $ hg revert -r 4 .hgsub # remove t
327 $ hg ci -m11
327 $ hg ci -m11
328 created new head
328 created new head
329 $ hg debugsub
329 $ hg debugsub
330 path s
330 path s
331 source s
331 source s
332 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
332 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
333
333
334 local removed, remote changed, keep changed
334 local removed, remote changed, keep changed
335
335
336 $ hg merge 6
336 $ hg merge 6
337 remote changed subrepository t which local removed
337 remote changed subrepository t which local removed
338 use (c)hanged version or (d)elete? c
338 use (c)hanged version or (d)elete? c
339 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
339 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 (branch merge, don't forget to commit)
340 (branch merge, don't forget to commit)
341 BROKEN: should include subrepo t
341 BROKEN: should include subrepo t
342 $ hg debugsub
342 $ hg debugsub
343 path s
343 path s
344 source s
344 source s
345 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
345 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
346 $ cat .hgsubstate
346 $ cat .hgsubstate
347 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
347 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
348 6747d179aa9a688023c4b0cad32e4c92bb7f34ad t
348 6747d179aa9a688023c4b0cad32e4c92bb7f34ad t
349 $ hg ci -m 'local removed, remote changed, keep changed'
349 $ hg ci -m 'local removed, remote changed, keep changed'
350 BROKEN: should include subrepo t
350 BROKEN: should include subrepo t
351 $ hg debugsub
351 $ hg debugsub
352 path s
352 path s
353 source s
353 source s
354 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
354 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
355 BROKEN: should include subrepo t
355 BROKEN: should include subrepo t
356 $ cat .hgsubstate
356 $ cat .hgsubstate
357 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
357 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
358 $ cat t/t
358 $ cat t/t
359 t2
359 t2
360
360
361 local removed, remote changed, keep removed
361 local removed, remote changed, keep removed
362
362
363 $ hg co -C 11
363 $ hg co -C 11
364 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
364 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
365 $ hg merge --config ui.interactive=true 6 <<EOF
365 $ hg merge --config ui.interactive=true 6 <<EOF
366 > d
366 > d
367 > EOF
367 > EOF
368 remote changed subrepository t which local removed
368 remote changed subrepository t which local removed
369 use (c)hanged version or (d)elete? d
369 use (c)hanged version or (d)elete? d
370 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
370 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
371 (branch merge, don't forget to commit)
371 (branch merge, don't forget to commit)
372 $ hg debugsub
372 $ hg debugsub
373 path s
373 path s
374 source s
374 source s
375 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
375 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
376 $ cat .hgsubstate
376 $ cat .hgsubstate
377 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
377 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
378 $ hg ci -m 'local removed, remote changed, keep removed'
378 $ hg ci -m 'local removed, remote changed, keep removed'
379 created new head
379 created new head
380 $ hg debugsub
380 $ hg debugsub
381 path s
381 path s
382 source s
382 source s
383 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
383 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
384 $ cat .hgsubstate
384 $ cat .hgsubstate
385 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
385 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
386
386
387 local changed, remote removed, keep changed
387 local changed, remote removed, keep changed
388
388
389 $ hg co -C 6
389 $ hg co -C 6
390 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
390 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
391 $ hg merge 11
391 $ hg merge 11
392 local changed subrepository t which remote removed
392 local changed subrepository t which remote removed
393 use (c)hanged version or (d)elete? c
393 use (c)hanged version or (d)elete? c
394 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
394 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
395 (branch merge, don't forget to commit)
395 (branch merge, don't forget to commit)
396 BROKEN: should include subrepo t
396 BROKEN: should include subrepo t
397 $ hg debugsub
397 $ hg debugsub
398 path s
398 path s
399 source s
399 source s
400 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
400 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
401 BROKEN: should include subrepo t
401 BROKEN: should include subrepo t
402 $ cat .hgsubstate
402 $ cat .hgsubstate
403 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
403 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
404 $ hg ci -m 'local changed, remote removed, keep changed'
404 $ hg ci -m 'local changed, remote removed, keep changed'
405 created new head
405 created new head
406 BROKEN: should include subrepo t
406 BROKEN: should include subrepo t
407 $ hg debugsub
407 $ hg debugsub
408 path s
408 path s
409 source s
409 source s
410 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
410 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
411 BROKEN: should include subrepo t
411 BROKEN: should include subrepo t
412 $ cat .hgsubstate
412 $ cat .hgsubstate
413 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
413 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
414 $ cat t/t
414 $ cat t/t
415 t2
415 t2
416
416
417 local changed, remote removed, keep removed
417 local changed, remote removed, keep removed
418
418
419 $ hg co -C 6
419 $ hg co -C 6
420 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
420 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
421 $ hg merge --config ui.interactive=true 11 <<EOF
421 $ hg merge --config ui.interactive=true 11 <<EOF
422 > d
422 > d
423 > EOF
423 > EOF
424 local changed subrepository t which remote removed
424 local changed subrepository t which remote removed
425 use (c)hanged version or (d)elete? d
425 use (c)hanged version or (d)elete? d
426 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
426 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
427 (branch merge, don't forget to commit)
427 (branch merge, don't forget to commit)
428 $ hg debugsub
428 $ hg debugsub
429 path s
429 path s
430 source s
430 source s
431 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
431 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
432 $ cat .hgsubstate
432 $ cat .hgsubstate
433 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
433 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
434 $ hg ci -m 'local changed, remote removed, keep removed'
434 $ hg ci -m 'local changed, remote removed, keep removed'
435 created new head
435 created new head
436 $ hg debugsub
436 $ hg debugsub
437 path s
437 path s
438 source s
438 source s
439 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
439 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
440 $ cat .hgsubstate
440 $ cat .hgsubstate
441 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
441 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
442
442
443 clean up to avoid having to fix up the tests below
443 clean up to avoid having to fix up the tests below
444
444
445 $ hg co -C 10
445 $ hg co -C 10
446 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
446 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
447 $ cat >> $HGRCPATH <<EOF
447 $ cat >> $HGRCPATH <<EOF
448 > [extensions]
448 > [extensions]
449 > strip=
449 > strip=
450 > EOF
450 > EOF
451 $ hg strip -r 11:15
451 $ hg strip -r 11:15
452 saved backup bundle to $TESTTMP/t/.hg/strip-backup/*-backup.hg (glob)
452 saved backup bundle to $TESTTMP/t/.hg/strip-backup/*-backup.hg (glob)
453
453
454 clone
454 clone
455
455
456 $ cd ..
456 $ cd ..
457 $ hg clone t tc
457 $ hg clone t tc
458 updating to branch default
458 updating to branch default
459 cloning subrepo s from $TESTTMP/t/s
459 cloning subrepo s from $TESTTMP/t/s
460 cloning subrepo s/ss from $TESTTMP/t/s/ss (glob)
460 cloning subrepo s/ss from $TESTTMP/t/s/ss (glob)
461 cloning subrepo t from $TESTTMP/t/t
461 cloning subrepo t from $TESTTMP/t/t
462 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
462 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
463 $ cd tc
463 $ cd tc
464 $ hg debugsub
464 $ hg debugsub
465 path s
465 path s
466 source s
466 source s
467 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
467 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
468 path t
468 path t
469 source t
469 source t
470 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
470 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
471
471
472 push
472 push
473
473
474 $ echo bah > t/t
474 $ echo bah > t/t
475 $ hg ci -m11
475 $ hg ci -m11
476 committing subrepository t
476 committing subrepository t
477 $ hg push
477 $ hg push
478 pushing to $TESTTMP/t (glob)
478 pushing to $TESTTMP/t (glob)
479 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
479 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
480 no changes made to subrepo s since last push to $TESTTMP/t/s
480 no changes made to subrepo s since last push to $TESTTMP/t/s
481 pushing subrepo t to $TESTTMP/t/t
481 pushing subrepo t to $TESTTMP/t/t
482 searching for changes
482 searching for changes
483 adding changesets
483 adding changesets
484 adding manifests
484 adding manifests
485 adding file changes
485 adding file changes
486 added 1 changesets with 1 changes to 1 files
486 added 1 changesets with 1 changes to 1 files
487 searching for changes
487 searching for changes
488 adding changesets
488 adding changesets
489 adding manifests
489 adding manifests
490 adding file changes
490 adding file changes
491 added 1 changesets with 1 changes to 1 files
491 added 1 changesets with 1 changes to 1 files
492
492
493 push -f
493 push -f
494
494
495 $ echo bah > s/a
495 $ echo bah > s/a
496 $ hg ci -m12
496 $ hg ci -m12
497 committing subrepository s
497 committing subrepository s
498 $ hg push
498 $ hg push
499 pushing to $TESTTMP/t (glob)
499 pushing to $TESTTMP/t (glob)
500 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
500 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
501 pushing subrepo s to $TESTTMP/t/s
501 pushing subrepo s to $TESTTMP/t/s
502 searching for changes
502 searching for changes
503 abort: push creates new remote head 12a213df6fa9! (in subrepo s)
503 abort: push creates new remote head 12a213df6fa9! (in subrepo s)
504 (merge or see "hg help push" for details about pushing new heads)
504 (merge or see "hg help push" for details about pushing new heads)
505 [255]
505 [255]
506 $ hg push -f
506 $ hg push -f
507 pushing to $TESTTMP/t (glob)
507 pushing to $TESTTMP/t (glob)
508 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
508 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
509 searching for changes
509 searching for changes
510 no changes found
510 no changes found
511 pushing subrepo s to $TESTTMP/t/s
511 pushing subrepo s to $TESTTMP/t/s
512 searching for changes
512 searching for changes
513 adding changesets
513 adding changesets
514 adding manifests
514 adding manifests
515 adding file changes
515 adding file changes
516 added 1 changesets with 1 changes to 1 files (+1 heads)
516 added 1 changesets with 1 changes to 1 files (+1 heads)
517 pushing subrepo t to $TESTTMP/t/t
517 pushing subrepo t to $TESTTMP/t/t
518 searching for changes
518 searching for changes
519 no changes found
519 no changes found
520 searching for changes
520 searching for changes
521 adding changesets
521 adding changesets
522 adding manifests
522 adding manifests
523 adding file changes
523 adding file changes
524 added 1 changesets with 1 changes to 1 files
524 added 1 changesets with 1 changes to 1 files
525
525
526 check that unmodified subrepos are not pushed
526 check that unmodified subrepos are not pushed
527
527
528 $ hg clone . ../tcc
528 $ hg clone . ../tcc
529 updating to branch default
529 updating to branch default
530 cloning subrepo s from $TESTTMP/tc/s
530 cloning subrepo s from $TESTTMP/tc/s
531 cloning subrepo s/ss from $TESTTMP/tc/s/ss (glob)
531 cloning subrepo s/ss from $TESTTMP/tc/s/ss (glob)
532 cloning subrepo t from $TESTTMP/tc/t
532 cloning subrepo t from $TESTTMP/tc/t
533 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
533 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
534
534
535 the subrepos on the new clone have nothing to push to its source
535 the subrepos on the new clone have nothing to push to its source
536
536
537 $ hg push -R ../tcc .
537 $ hg push -R ../tcc .
538 pushing to .
538 pushing to .
539 no changes made to subrepo s/ss since last push to s/ss (glob)
539 no changes made to subrepo s/ss since last push to s/ss (glob)
540 no changes made to subrepo s since last push to s
540 no changes made to subrepo s since last push to s
541 no changes made to subrepo t since last push to t
541 no changes made to subrepo t since last push to t
542 searching for changes
542 searching for changes
543 no changes found
543 no changes found
544 [1]
544 [1]
545
545
546 the subrepos on the source do not have a clean store versus the clone target
546 the subrepos on the source do not have a clean store versus the clone target
547 because they were never explicitly pushed to the source
547 because they were never explicitly pushed to the source
548
548
549 $ hg push ../tcc
549 $ hg push ../tcc
550 pushing to ../tcc
550 pushing to ../tcc
551 pushing subrepo s/ss to ../tcc/s/ss (glob)
551 pushing subrepo s/ss to ../tcc/s/ss (glob)
552 searching for changes
552 searching for changes
553 no changes found
553 no changes found
554 pushing subrepo s to ../tcc/s
554 pushing subrepo s to ../tcc/s
555 searching for changes
555 searching for changes
556 no changes found
556 no changes found
557 pushing subrepo t to ../tcc/t
557 pushing subrepo t to ../tcc/t
558 searching for changes
558 searching for changes
559 no changes found
559 no changes found
560 searching for changes
560 searching for changes
561 no changes found
561 no changes found
562 [1]
562 [1]
563
563
564 after push their stores become clean
564 after push their stores become clean
565
565
566 $ hg push ../tcc
566 $ hg push ../tcc
567 pushing to ../tcc
567 pushing to ../tcc
568 no changes made to subrepo s/ss since last push to ../tcc/s/ss (glob)
568 no changes made to subrepo s/ss since last push to ../tcc/s/ss (glob)
569 no changes made to subrepo s since last push to ../tcc/s
569 no changes made to subrepo s since last push to ../tcc/s
570 no changes made to subrepo t since last push to ../tcc/t
570 no changes made to subrepo t since last push to ../tcc/t
571 searching for changes
571 searching for changes
572 no changes found
572 no changes found
573 [1]
573 [1]
574
574
575 updating a subrepo to a different revision or changing
575 updating a subrepo to a different revision or changing
576 its working directory does not make its store dirty
576 its working directory does not make its store dirty
577
577
578 $ hg -R s update '.^'
578 $ hg -R s update '.^'
579 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
579 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
580 $ hg push
580 $ hg push
581 pushing to $TESTTMP/t (glob)
581 pushing to $TESTTMP/t (glob)
582 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
582 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
583 no changes made to subrepo s since last push to $TESTTMP/t/s
583 no changes made to subrepo s since last push to $TESTTMP/t/s
584 no changes made to subrepo t since last push to $TESTTMP/t/t
584 no changes made to subrepo t since last push to $TESTTMP/t/t
585 searching for changes
585 searching for changes
586 no changes found
586 no changes found
587 [1]
587 [1]
588 $ echo foo >> s/a
588 $ echo foo >> s/a
589 $ hg push
589 $ hg push
590 pushing to $TESTTMP/t (glob)
590 pushing to $TESTTMP/t (glob)
591 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
591 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
592 no changes made to subrepo s since last push to $TESTTMP/t/s
592 no changes made to subrepo s since last push to $TESTTMP/t/s
593 no changes made to subrepo t since last push to $TESTTMP/t/t
593 no changes made to subrepo t since last push to $TESTTMP/t/t
594 searching for changes
594 searching for changes
595 no changes found
595 no changes found
596 [1]
596 [1]
597 $ hg -R s update -C tip
597 $ hg -R s update -C tip
598 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
598 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
599
599
600 committing into a subrepo makes its store (but not its parent's store) dirty
600 committing into a subrepo makes its store (but not its parent's store) dirty
601
601
602 $ echo foo >> s/ss/a
602 $ echo foo >> s/ss/a
603 $ hg -R s/ss commit -m 'test dirty store detection'
603 $ hg -R s/ss commit -m 'test dirty store detection'
604
604
605 $ hg out -S -r `hg log -r tip -T "{node|short}"`
605 $ hg out -S -r `hg log -r tip -T "{node|short}"`
606 comparing with $TESTTMP/t (glob)
606 comparing with $TESTTMP/t (glob)
607 searching for changes
607 searching for changes
608 no changes found
608 no changes found
609 comparing with $TESTTMP/t/s
609 comparing with $TESTTMP/t/s
610 searching for changes
610 searching for changes
611 no changes found
611 no changes found
612 comparing with $TESTTMP/t/s/ss
612 comparing with $TESTTMP/t/s/ss
613 searching for changes
613 searching for changes
614 changeset: 1:79ea5566a333
614 changeset: 1:79ea5566a333
615 tag: tip
615 tag: tip
616 user: test
616 user: test
617 date: Thu Jan 01 00:00:00 1970 +0000
617 date: Thu Jan 01 00:00:00 1970 +0000
618 summary: test dirty store detection
618 summary: test dirty store detection
619
619
620 comparing with $TESTTMP/t/t
620 comparing with $TESTTMP/t/t
621 searching for changes
621 searching for changes
622 no changes found
622 no changes found
623
623
624 $ hg push
624 $ hg push
625 pushing to $TESTTMP/t (glob)
625 pushing to $TESTTMP/t (glob)
626 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
626 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
627 searching for changes
627 searching for changes
628 adding changesets
628 adding changesets
629 adding manifests
629 adding manifests
630 adding file changes
630 adding file changes
631 added 1 changesets with 1 changes to 1 files
631 added 1 changesets with 1 changes to 1 files
632 no changes made to subrepo s since last push to $TESTTMP/t/s
632 no changes made to subrepo s since last push to $TESTTMP/t/s
633 no changes made to subrepo t since last push to $TESTTMP/t/t
633 no changes made to subrepo t since last push to $TESTTMP/t/t
634 searching for changes
634 searching for changes
635 no changes found
635 no changes found
636 [1]
636 [1]
637
637
638 a subrepo store may be clean versus one repo but not versus another
638 a subrepo store may be clean versus one repo but not versus another
639
639
640 $ hg push
640 $ hg push
641 pushing to $TESTTMP/t (glob)
641 pushing to $TESTTMP/t (glob)
642 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
642 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
643 no changes made to subrepo s since last push to $TESTTMP/t/s
643 no changes made to subrepo s since last push to $TESTTMP/t/s
644 no changes made to subrepo t since last push to $TESTTMP/t/t
644 no changes made to subrepo t since last push to $TESTTMP/t/t
645 searching for changes
645 searching for changes
646 no changes found
646 no changes found
647 [1]
647 [1]
648 $ hg push ../tcc
648 $ hg push ../tcc
649 pushing to ../tcc
649 pushing to ../tcc
650 pushing subrepo s/ss to ../tcc/s/ss (glob)
650 pushing subrepo s/ss to ../tcc/s/ss (glob)
651 searching for changes
651 searching for changes
652 adding changesets
652 adding changesets
653 adding manifests
653 adding manifests
654 adding file changes
654 adding file changes
655 added 1 changesets with 1 changes to 1 files
655 added 1 changesets with 1 changes to 1 files
656 no changes made to subrepo s since last push to ../tcc/s
656 no changes made to subrepo s since last push to ../tcc/s
657 no changes made to subrepo t since last push to ../tcc/t
657 no changes made to subrepo t since last push to ../tcc/t
658 searching for changes
658 searching for changes
659 no changes found
659 no changes found
660 [1]
660 [1]
661
661
662 update
662 update
663
663
664 $ cd ../t
664 $ cd ../t
665 $ hg up -C # discard our earlier merge
665 $ hg up -C # discard our earlier merge
666 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
666 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
667 $ echo blah > t/t
667 $ echo blah > t/t
668 $ hg ci -m13
668 $ hg ci -m13
669 committing subrepository t
669 committing subrepository t
670
670
671 backout calls revert internally with minimal opts, which should not raise
671 backout calls revert internally with minimal opts, which should not raise
672 KeyError
672 KeyError
673
673
674 $ hg backout ".^"
674 $ hg backout ".^" --no-commit
675 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
675 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
676 changeset c373c8102e68 backed out, don't forget to commit.
676 changeset c373c8102e68 backed out, don't forget to commit.
677
677
678 $ hg up -C # discard changes
678 $ hg up -C # discard changes
679 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
679 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
680
680
681 pull
681 pull
682
682
683 $ cd ../tc
683 $ cd ../tc
684 $ hg pull
684 $ hg pull
685 pulling from $TESTTMP/t (glob)
685 pulling from $TESTTMP/t (glob)
686 searching for changes
686 searching for changes
687 adding changesets
687 adding changesets
688 adding manifests
688 adding manifests
689 adding file changes
689 adding file changes
690 added 1 changesets with 1 changes to 1 files
690 added 1 changesets with 1 changes to 1 files
691 (run 'hg update' to get a working copy)
691 (run 'hg update' to get a working copy)
692
692
693 should pull t
693 should pull t
694
694
695 $ hg incoming -S -r `hg log -r tip -T "{node|short}"`
695 $ hg incoming -S -r `hg log -r tip -T "{node|short}"`
696 comparing with $TESTTMP/t (glob)
696 comparing with $TESTTMP/t (glob)
697 no changes found
697 no changes found
698 comparing with $TESTTMP/t/s
698 comparing with $TESTTMP/t/s
699 searching for changes
699 searching for changes
700 no changes found
700 no changes found
701 comparing with $TESTTMP/t/s/ss
701 comparing with $TESTTMP/t/s/ss
702 searching for changes
702 searching for changes
703 no changes found
703 no changes found
704 comparing with $TESTTMP/t/t
704 comparing with $TESTTMP/t/t
705 searching for changes
705 searching for changes
706 changeset: 5:52c0adc0515a
706 changeset: 5:52c0adc0515a
707 tag: tip
707 tag: tip
708 user: test
708 user: test
709 date: Thu Jan 01 00:00:00 1970 +0000
709 date: Thu Jan 01 00:00:00 1970 +0000
710 summary: 13
710 summary: 13
711
711
712
712
713 $ hg up
713 $ hg up
714 pulling subrepo t from $TESTTMP/t/t
714 pulling subrepo t from $TESTTMP/t/t
715 searching for changes
715 searching for changes
716 adding changesets
716 adding changesets
717 adding manifests
717 adding manifests
718 adding file changes
718 adding file changes
719 added 1 changesets with 1 changes to 1 files
719 added 1 changesets with 1 changes to 1 files
720 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
720 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
721 $ cat t/t
721 $ cat t/t
722 blah
722 blah
723
723
724 bogus subrepo path aborts
724 bogus subrepo path aborts
725
725
726 $ echo 'bogus=[boguspath' >> .hgsub
726 $ echo 'bogus=[boguspath' >> .hgsub
727 $ hg ci -m 'bogus subrepo path'
727 $ hg ci -m 'bogus subrepo path'
728 abort: missing ] in subrepo source
728 abort: missing ] in subrepo source
729 [255]
729 [255]
730
730
731 Issue1986: merge aborts when trying to merge a subrepo that
731 Issue1986: merge aborts when trying to merge a subrepo that
732 shouldn't need merging
732 shouldn't need merging
733
733
734 # subrepo layout
734 # subrepo layout
735 #
735 #
736 # o 5 br
736 # o 5 br
737 # /|
737 # /|
738 # o | 4 default
738 # o | 4 default
739 # | |
739 # | |
740 # | o 3 br
740 # | o 3 br
741 # |/|
741 # |/|
742 # o | 2 default
742 # o | 2 default
743 # | |
743 # | |
744 # | o 1 br
744 # | o 1 br
745 # |/
745 # |/
746 # o 0 default
746 # o 0 default
747
747
748 $ cd ..
748 $ cd ..
749 $ rm -rf sub
749 $ rm -rf sub
750 $ hg init main
750 $ hg init main
751 $ cd main
751 $ cd main
752 $ hg init s
752 $ hg init s
753 $ cd s
753 $ cd s
754 $ echo a > a
754 $ echo a > a
755 $ hg ci -Am1
755 $ hg ci -Am1
756 adding a
756 adding a
757 $ hg branch br
757 $ hg branch br
758 marked working directory as branch br
758 marked working directory as branch br
759 (branches are permanent and global, did you want a bookmark?)
759 (branches are permanent and global, did you want a bookmark?)
760 $ echo a >> a
760 $ echo a >> a
761 $ hg ci -m1
761 $ hg ci -m1
762 $ hg up default
762 $ hg up default
763 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
763 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
764 $ echo b > b
764 $ echo b > b
765 $ hg ci -Am1
765 $ hg ci -Am1
766 adding b
766 adding b
767 $ hg up br
767 $ hg up br
768 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
768 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
769 $ hg merge tip
769 $ hg merge tip
770 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
770 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
771 (branch merge, don't forget to commit)
771 (branch merge, don't forget to commit)
772 $ hg ci -m1
772 $ hg ci -m1
773 $ hg up 2
773 $ hg up 2
774 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
774 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
775 $ echo c > c
775 $ echo c > c
776 $ hg ci -Am1
776 $ hg ci -Am1
777 adding c
777 adding c
778 $ hg up 3
778 $ hg up 3
779 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
779 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
780 $ hg merge 4
780 $ hg merge 4
781 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
781 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
782 (branch merge, don't forget to commit)
782 (branch merge, don't forget to commit)
783 $ hg ci -m1
783 $ hg ci -m1
784
784
785 # main repo layout:
785 # main repo layout:
786 #
786 #
787 # * <-- try to merge default into br again
787 # * <-- try to merge default into br again
788 # .`|
788 # .`|
789 # . o 5 br --> substate = 5
789 # . o 5 br --> substate = 5
790 # . |
790 # . |
791 # o | 4 default --> substate = 4
791 # o | 4 default --> substate = 4
792 # | |
792 # | |
793 # | o 3 br --> substate = 2
793 # | o 3 br --> substate = 2
794 # |/|
794 # |/|
795 # o | 2 default --> substate = 2
795 # o | 2 default --> substate = 2
796 # | |
796 # | |
797 # | o 1 br --> substate = 3
797 # | o 1 br --> substate = 3
798 # |/
798 # |/
799 # o 0 default --> substate = 2
799 # o 0 default --> substate = 2
800
800
801 $ cd ..
801 $ cd ..
802 $ echo 's = s' > .hgsub
802 $ echo 's = s' > .hgsub
803 $ hg -R s up 2
803 $ hg -R s up 2
804 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
804 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
805 $ hg ci -Am1
805 $ hg ci -Am1
806 adding .hgsub
806 adding .hgsub
807 $ hg branch br
807 $ hg branch br
808 marked working directory as branch br
808 marked working directory as branch br
809 (branches are permanent and global, did you want a bookmark?)
809 (branches are permanent and global, did you want a bookmark?)
810 $ echo b > b
810 $ echo b > b
811 $ hg -R s up 3
811 $ hg -R s up 3
812 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
812 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
813 $ hg ci -Am1
813 $ hg ci -Am1
814 adding b
814 adding b
815 $ hg up default
815 $ hg up default
816 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
816 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
817 $ echo c > c
817 $ echo c > c
818 $ hg ci -Am1
818 $ hg ci -Am1
819 adding c
819 adding c
820 $ hg up 1
820 $ hg up 1
821 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
821 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
822 $ hg merge 2
822 $ hg merge 2
823 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
823 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
824 (branch merge, don't forget to commit)
824 (branch merge, don't forget to commit)
825 $ hg ci -m1
825 $ hg ci -m1
826 $ hg up 2
826 $ hg up 2
827 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
827 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
828 $ hg -R s up 4
828 $ hg -R s up 4
829 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
829 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
830 $ echo d > d
830 $ echo d > d
831 $ hg ci -Am1
831 $ hg ci -Am1
832 adding d
832 adding d
833 $ hg up 3
833 $ hg up 3
834 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
834 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
835 $ hg -R s up 5
835 $ hg -R s up 5
836 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
836 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
837 $ echo e > e
837 $ echo e > e
838 $ hg ci -Am1
838 $ hg ci -Am1
839 adding e
839 adding e
840
840
841 $ hg up 5
841 $ hg up 5
842 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
842 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
843 $ hg merge 4 # try to merge default into br again
843 $ hg merge 4 # try to merge default into br again
844 subrepository s diverged (local revision: f8f13b33206e, remote revision: a3f9062a4f88)
844 subrepository s diverged (local revision: f8f13b33206e, remote revision: a3f9062a4f88)
845 (M)erge, keep (l)ocal or keep (r)emote? m
845 (M)erge, keep (l)ocal or keep (r)emote? m
846 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
846 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
847 (branch merge, don't forget to commit)
847 (branch merge, don't forget to commit)
848 $ cd ..
848 $ cd ..
849
849
850 test subrepo delete from .hgsubstate
850 test subrepo delete from .hgsubstate
851
851
852 $ hg init testdelete
852 $ hg init testdelete
853 $ mkdir testdelete/nested testdelete/nested2
853 $ mkdir testdelete/nested testdelete/nested2
854 $ hg init testdelete/nested
854 $ hg init testdelete/nested
855 $ hg init testdelete/nested2
855 $ hg init testdelete/nested2
856 $ echo test > testdelete/nested/foo
856 $ echo test > testdelete/nested/foo
857 $ echo test > testdelete/nested2/foo
857 $ echo test > testdelete/nested2/foo
858 $ hg -R testdelete/nested add
858 $ hg -R testdelete/nested add
859 adding testdelete/nested/foo (glob)
859 adding testdelete/nested/foo (glob)
860 $ hg -R testdelete/nested2 add
860 $ hg -R testdelete/nested2 add
861 adding testdelete/nested2/foo (glob)
861 adding testdelete/nested2/foo (glob)
862 $ hg -R testdelete/nested ci -m test
862 $ hg -R testdelete/nested ci -m test
863 $ hg -R testdelete/nested2 ci -m test
863 $ hg -R testdelete/nested2 ci -m test
864 $ echo nested = nested > testdelete/.hgsub
864 $ echo nested = nested > testdelete/.hgsub
865 $ echo nested2 = nested2 >> testdelete/.hgsub
865 $ echo nested2 = nested2 >> testdelete/.hgsub
866 $ hg -R testdelete add
866 $ hg -R testdelete add
867 adding testdelete/.hgsub (glob)
867 adding testdelete/.hgsub (glob)
868 $ hg -R testdelete ci -m "nested 1 & 2 added"
868 $ hg -R testdelete ci -m "nested 1 & 2 added"
869 $ echo nested = nested > testdelete/.hgsub
869 $ echo nested = nested > testdelete/.hgsub
870 $ hg -R testdelete ci -m "nested 2 deleted"
870 $ hg -R testdelete ci -m "nested 2 deleted"
871 $ cat testdelete/.hgsubstate
871 $ cat testdelete/.hgsubstate
872 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
872 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
873 $ hg -R testdelete remove testdelete/.hgsub
873 $ hg -R testdelete remove testdelete/.hgsub
874 $ hg -R testdelete ci -m ".hgsub deleted"
874 $ hg -R testdelete ci -m ".hgsub deleted"
875 $ cat testdelete/.hgsubstate
875 $ cat testdelete/.hgsubstate
876 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
876 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
877
877
878 test repository cloning
878 test repository cloning
879
879
880 $ mkdir mercurial mercurial2
880 $ mkdir mercurial mercurial2
881 $ hg init nested_absolute
881 $ hg init nested_absolute
882 $ echo test > nested_absolute/foo
882 $ echo test > nested_absolute/foo
883 $ hg -R nested_absolute add
883 $ hg -R nested_absolute add
884 adding nested_absolute/foo (glob)
884 adding nested_absolute/foo (glob)
885 $ hg -R nested_absolute ci -mtest
885 $ hg -R nested_absolute ci -mtest
886 $ cd mercurial
886 $ cd mercurial
887 $ hg init nested_relative
887 $ hg init nested_relative
888 $ echo test2 > nested_relative/foo2
888 $ echo test2 > nested_relative/foo2
889 $ hg -R nested_relative add
889 $ hg -R nested_relative add
890 adding nested_relative/foo2 (glob)
890 adding nested_relative/foo2 (glob)
891 $ hg -R nested_relative ci -mtest2
891 $ hg -R nested_relative ci -mtest2
892 $ hg init main
892 $ hg init main
893 $ echo "nested_relative = ../nested_relative" > main/.hgsub
893 $ echo "nested_relative = ../nested_relative" > main/.hgsub
894 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
894 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
895 $ hg -R main add
895 $ hg -R main add
896 adding main/.hgsub (glob)
896 adding main/.hgsub (glob)
897 $ hg -R main ci -m "add subrepos"
897 $ hg -R main ci -m "add subrepos"
898 $ cd ..
898 $ cd ..
899 $ hg clone mercurial/main mercurial2/main
899 $ hg clone mercurial/main mercurial2/main
900 updating to branch default
900 updating to branch default
901 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
901 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
902 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
902 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
903 > mercurial2/main/nested_relative/.hg/hgrc
903 > mercurial2/main/nested_relative/.hg/hgrc
904 [paths]
904 [paths]
905 default = $TESTTMP/mercurial/nested_absolute
905 default = $TESTTMP/mercurial/nested_absolute
906 [paths]
906 [paths]
907 default = $TESTTMP/mercurial/nested_relative
907 default = $TESTTMP/mercurial/nested_relative
908 $ rm -rf mercurial mercurial2
908 $ rm -rf mercurial mercurial2
909
909
910 Issue1977: multirepo push should fail if subrepo push fails
910 Issue1977: multirepo push should fail if subrepo push fails
911
911
912 $ hg init repo
912 $ hg init repo
913 $ hg init repo/s
913 $ hg init repo/s
914 $ echo a > repo/s/a
914 $ echo a > repo/s/a
915 $ hg -R repo/s ci -Am0
915 $ hg -R repo/s ci -Am0
916 adding a
916 adding a
917 $ echo s = s > repo/.hgsub
917 $ echo s = s > repo/.hgsub
918 $ hg -R repo ci -Am1
918 $ hg -R repo ci -Am1
919 adding .hgsub
919 adding .hgsub
920 $ hg clone repo repo2
920 $ hg clone repo repo2
921 updating to branch default
921 updating to branch default
922 cloning subrepo s from $TESTTMP/repo/s
922 cloning subrepo s from $TESTTMP/repo/s
923 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
923 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
924 $ hg -q -R repo2 pull -u
924 $ hg -q -R repo2 pull -u
925 $ echo 1 > repo2/s/a
925 $ echo 1 > repo2/s/a
926 $ hg -R repo2/s ci -m2
926 $ hg -R repo2/s ci -m2
927 $ hg -q -R repo2/s push
927 $ hg -q -R repo2/s push
928 $ hg -R repo2/s up -C 0
928 $ hg -R repo2/s up -C 0
929 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
929 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
930 $ echo 2 > repo2/s/b
930 $ echo 2 > repo2/s/b
931 $ hg -R repo2/s ci -m3 -A
931 $ hg -R repo2/s ci -m3 -A
932 adding b
932 adding b
933 created new head
933 created new head
934 $ hg -R repo2 ci -m3
934 $ hg -R repo2 ci -m3
935 $ hg -q -R repo2 push
935 $ hg -q -R repo2 push
936 abort: push creates new remote head cc505f09a8b2! (in subrepo s)
936 abort: push creates new remote head cc505f09a8b2! (in subrepo s)
937 (merge or see "hg help push" for details about pushing new heads)
937 (merge or see "hg help push" for details about pushing new heads)
938 [255]
938 [255]
939 $ hg -R repo update
939 $ hg -R repo update
940 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
940 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
941
941
942 test if untracked file is not overwritten
942 test if untracked file is not overwritten
943
943
944 (this also tests that updated .hgsubstate is treated as "modified",
944 (this also tests that updated .hgsubstate is treated as "modified",
945 when 'merge.update()' is aborted before 'merge.recordupdates()', even
945 when 'merge.update()' is aborted before 'merge.recordupdates()', even
946 if none of mode, size and timestamp of it isn't changed on the
946 if none of mode, size and timestamp of it isn't changed on the
947 filesystem (see also issue4583))
947 filesystem (see also issue4583))
948
948
949 $ echo issue3276_ok > repo/s/b
949 $ echo issue3276_ok > repo/s/b
950 $ hg -R repo2 push -f -q
950 $ hg -R repo2 push -f -q
951 $ touch -t 200001010000 repo/.hgsubstate
951 $ touch -t 200001010000 repo/.hgsubstate
952
952
953 $ cat >> repo/.hg/hgrc <<EOF
953 $ cat >> repo/.hg/hgrc <<EOF
954 > [fakedirstatewritetime]
954 > [fakedirstatewritetime]
955 > # emulate invoking dirstate.write() via repo.status()
955 > # emulate invoking dirstate.write() via repo.status()
956 > # at 2000-01-01 00:00
956 > # at 2000-01-01 00:00
957 > fakenow = 200001010000
957 > fakenow = 200001010000
958 >
958 >
959 > [extensions]
959 > [extensions]
960 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
960 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
961 > EOF
961 > EOF
962 $ hg -R repo update
962 $ hg -R repo update
963 b: untracked file differs
963 b: untracked file differs
964 abort: untracked files in working directory differ from files in requested revision (in subrepo s)
964 abort: untracked files in working directory differ from files in requested revision (in subrepo s)
965 [255]
965 [255]
966 $ cat >> repo/.hg/hgrc <<EOF
966 $ cat >> repo/.hg/hgrc <<EOF
967 > [extensions]
967 > [extensions]
968 > fakedirstatewritetime = !
968 > fakedirstatewritetime = !
969 > EOF
969 > EOF
970
970
971 $ cat repo/s/b
971 $ cat repo/s/b
972 issue3276_ok
972 issue3276_ok
973 $ rm repo/s/b
973 $ rm repo/s/b
974 $ touch -t 200001010000 repo/.hgsubstate
974 $ touch -t 200001010000 repo/.hgsubstate
975 $ hg -R repo revert --all
975 $ hg -R repo revert --all
976 reverting repo/.hgsubstate (glob)
976 reverting repo/.hgsubstate (glob)
977 reverting subrepo s
977 reverting subrepo s
978 $ hg -R repo update
978 $ hg -R repo update
979 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
979 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
980 $ cat repo/s/b
980 $ cat repo/s/b
981 2
981 2
982 $ rm -rf repo2 repo
982 $ rm -rf repo2 repo
983
983
984
984
985 Issue1852 subrepos with relative paths always push/pull relative to default
985 Issue1852 subrepos with relative paths always push/pull relative to default
986
986
987 Prepare a repo with subrepo
987 Prepare a repo with subrepo
988
988
989 $ hg init issue1852a
989 $ hg init issue1852a
990 $ cd issue1852a
990 $ cd issue1852a
991 $ hg init sub/repo
991 $ hg init sub/repo
992 $ echo test > sub/repo/foo
992 $ echo test > sub/repo/foo
993 $ hg -R sub/repo add sub/repo/foo
993 $ hg -R sub/repo add sub/repo/foo
994 $ echo sub/repo = sub/repo > .hgsub
994 $ echo sub/repo = sub/repo > .hgsub
995 $ hg add .hgsub
995 $ hg add .hgsub
996 $ hg ci -mtest
996 $ hg ci -mtest
997 committing subrepository sub/repo (glob)
997 committing subrepository sub/repo (glob)
998 $ echo test >> sub/repo/foo
998 $ echo test >> sub/repo/foo
999 $ hg ci -mtest
999 $ hg ci -mtest
1000 committing subrepository sub/repo (glob)
1000 committing subrepository sub/repo (glob)
1001 $ hg cat sub/repo/foo
1001 $ hg cat sub/repo/foo
1002 test
1002 test
1003 test
1003 test
1004 $ mkdir -p tmp/sub/repo
1004 $ mkdir -p tmp/sub/repo
1005 $ hg cat -r 0 --output tmp/%p_p sub/repo/foo
1005 $ hg cat -r 0 --output tmp/%p_p sub/repo/foo
1006 $ cat tmp/sub/repo/foo_p
1006 $ cat tmp/sub/repo/foo_p
1007 test
1007 test
1008 $ mv sub/repo sub_
1008 $ mv sub/repo sub_
1009 $ hg cat sub/repo/baz
1009 $ hg cat sub/repo/baz
1010 skipping missing subrepository: sub/repo
1010 skipping missing subrepository: sub/repo
1011 [1]
1011 [1]
1012 $ rm -rf sub/repo
1012 $ rm -rf sub/repo
1013 $ mv sub_ sub/repo
1013 $ mv sub_ sub/repo
1014 $ cd ..
1014 $ cd ..
1015
1015
1016 Create repo without default path, pull top repo, and see what happens on update
1016 Create repo without default path, pull top repo, and see what happens on update
1017
1017
1018 $ hg init issue1852b
1018 $ hg init issue1852b
1019 $ hg -R issue1852b pull issue1852a
1019 $ hg -R issue1852b pull issue1852a
1020 pulling from issue1852a
1020 pulling from issue1852a
1021 requesting all changes
1021 requesting all changes
1022 adding changesets
1022 adding changesets
1023 adding manifests
1023 adding manifests
1024 adding file changes
1024 adding file changes
1025 added 2 changesets with 3 changes to 2 files
1025 added 2 changesets with 3 changes to 2 files
1026 (run 'hg update' to get a working copy)
1026 (run 'hg update' to get a working copy)
1027 $ hg -R issue1852b update
1027 $ hg -R issue1852b update
1028 abort: default path for subrepository not found (in subrepo sub/repo) (glob)
1028 abort: default path for subrepository not found (in subrepo sub/repo) (glob)
1029 [255]
1029 [255]
1030
1030
1031 Ensure a full traceback, not just the SubrepoAbort part
1031 Ensure a full traceback, not just the SubrepoAbort part
1032
1032
1033 $ hg -R issue1852b update --traceback 2>&1 | grep 'raise error\.Abort'
1033 $ hg -R issue1852b update --traceback 2>&1 | grep 'raise error\.Abort'
1034 raise error.Abort(_("default path for subrepository not found"))
1034 raise error.Abort(_("default path for subrepository not found"))
1035
1035
1036 Pull -u now doesn't help
1036 Pull -u now doesn't help
1037
1037
1038 $ hg -R issue1852b pull -u issue1852a
1038 $ hg -R issue1852b pull -u issue1852a
1039 pulling from issue1852a
1039 pulling from issue1852a
1040 searching for changes
1040 searching for changes
1041 no changes found
1041 no changes found
1042
1042
1043 Try the same, but with pull -u
1043 Try the same, but with pull -u
1044
1044
1045 $ hg init issue1852c
1045 $ hg init issue1852c
1046 $ hg -R issue1852c pull -r0 -u issue1852a
1046 $ hg -R issue1852c pull -r0 -u issue1852a
1047 pulling from issue1852a
1047 pulling from issue1852a
1048 adding changesets
1048 adding changesets
1049 adding manifests
1049 adding manifests
1050 adding file changes
1050 adding file changes
1051 added 1 changesets with 2 changes to 2 files
1051 added 1 changesets with 2 changes to 2 files
1052 cloning subrepo sub/repo from issue1852a/sub/repo (glob)
1052 cloning subrepo sub/repo from issue1852a/sub/repo (glob)
1053 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1053 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1054
1054
1055 Try to push from the other side
1055 Try to push from the other side
1056
1056
1057 $ hg -R issue1852a push `pwd`/issue1852c
1057 $ hg -R issue1852a push `pwd`/issue1852c
1058 pushing to $TESTTMP/issue1852c (glob)
1058 pushing to $TESTTMP/issue1852c (glob)
1059 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo (glob)
1059 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo (glob)
1060 searching for changes
1060 searching for changes
1061 no changes found
1061 no changes found
1062 searching for changes
1062 searching for changes
1063 adding changesets
1063 adding changesets
1064 adding manifests
1064 adding manifests
1065 adding file changes
1065 adding file changes
1066 added 1 changesets with 1 changes to 1 files
1066 added 1 changesets with 1 changes to 1 files
1067
1067
1068 Incoming and outgoing should not use the default path:
1068 Incoming and outgoing should not use the default path:
1069
1069
1070 $ hg clone -q issue1852a issue1852d
1070 $ hg clone -q issue1852a issue1852d
1071 $ hg -R issue1852d outgoing --subrepos issue1852c
1071 $ hg -R issue1852d outgoing --subrepos issue1852c
1072 comparing with issue1852c
1072 comparing with issue1852c
1073 searching for changes
1073 searching for changes
1074 no changes found
1074 no changes found
1075 comparing with issue1852c/sub/repo
1075 comparing with issue1852c/sub/repo
1076 searching for changes
1076 searching for changes
1077 no changes found
1077 no changes found
1078 [1]
1078 [1]
1079 $ hg -R issue1852d incoming --subrepos issue1852c
1079 $ hg -R issue1852d incoming --subrepos issue1852c
1080 comparing with issue1852c
1080 comparing with issue1852c
1081 searching for changes
1081 searching for changes
1082 no changes found
1082 no changes found
1083 comparing with issue1852c/sub/repo
1083 comparing with issue1852c/sub/repo
1084 searching for changes
1084 searching for changes
1085 no changes found
1085 no changes found
1086 [1]
1086 [1]
1087
1087
1088 Check that merge of a new subrepo doesn't write the uncommitted state to
1088 Check that merge of a new subrepo doesn't write the uncommitted state to
1089 .hgsubstate (issue4622)
1089 .hgsubstate (issue4622)
1090
1090
1091 $ hg init issue1852a/addedsub
1091 $ hg init issue1852a/addedsub
1092 $ echo zzz > issue1852a/addedsub/zz.txt
1092 $ echo zzz > issue1852a/addedsub/zz.txt
1093 $ hg -R issue1852a/addedsub ci -Aqm "initial ZZ"
1093 $ hg -R issue1852a/addedsub ci -Aqm "initial ZZ"
1094
1094
1095 $ hg clone issue1852a/addedsub issue1852d/addedsub
1095 $ hg clone issue1852a/addedsub issue1852d/addedsub
1096 updating to branch default
1096 updating to branch default
1097 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1097 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1098
1098
1099 $ echo def > issue1852a/sub/repo/foo
1099 $ echo def > issue1852a/sub/repo/foo
1100 $ hg -R issue1852a ci -SAm 'tweaked subrepo'
1100 $ hg -R issue1852a ci -SAm 'tweaked subrepo'
1101 adding tmp/sub/repo/foo_p
1101 adding tmp/sub/repo/foo_p
1102 committing subrepository sub/repo (glob)
1102 committing subrepository sub/repo (glob)
1103
1103
1104 $ echo 'addedsub = addedsub' >> issue1852d/.hgsub
1104 $ echo 'addedsub = addedsub' >> issue1852d/.hgsub
1105 $ echo xyz > issue1852d/sub/repo/foo
1105 $ echo xyz > issue1852d/sub/repo/foo
1106 $ hg -R issue1852d pull -u
1106 $ hg -R issue1852d pull -u
1107 pulling from $TESTTMP/issue1852a (glob)
1107 pulling from $TESTTMP/issue1852a (glob)
1108 searching for changes
1108 searching for changes
1109 adding changesets
1109 adding changesets
1110 adding manifests
1110 adding manifests
1111 adding file changes
1111 adding file changes
1112 added 1 changesets with 2 changes to 2 files
1112 added 1 changesets with 2 changes to 2 files
1113 subrepository sub/repo diverged (local revision: f42d5c7504a8, remote revision: 46cd4aac504c)
1113 subrepository sub/repo diverged (local revision: f42d5c7504a8, remote revision: 46cd4aac504c)
1114 (M)erge, keep (l)ocal or keep (r)emote? m
1114 (M)erge, keep (l)ocal or keep (r)emote? m
1115 pulling subrepo sub/repo from $TESTTMP/issue1852a/sub/repo (glob)
1115 pulling subrepo sub/repo from $TESTTMP/issue1852a/sub/repo (glob)
1116 searching for changes
1116 searching for changes
1117 adding changesets
1117 adding changesets
1118 adding manifests
1118 adding manifests
1119 adding file changes
1119 adding file changes
1120 added 1 changesets with 1 changes to 1 files
1120 added 1 changesets with 1 changes to 1 files
1121 subrepository sources for sub/repo differ (glob)
1121 subrepository sources for sub/repo differ (glob)
1122 use (l)ocal source (f42d5c7504a8) or (r)emote source (46cd4aac504c)? l
1122 use (l)ocal source (f42d5c7504a8) or (r)emote source (46cd4aac504c)? l
1123 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1123 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1124 $ cat issue1852d/.hgsubstate
1124 $ cat issue1852d/.hgsubstate
1125 f42d5c7504a811dda50f5cf3e5e16c3330b87172 sub/repo
1125 f42d5c7504a811dda50f5cf3e5e16c3330b87172 sub/repo
1126
1126
1127 Check status of files when none of them belong to the first
1127 Check status of files when none of them belong to the first
1128 subrepository:
1128 subrepository:
1129
1129
1130 $ hg init subrepo-status
1130 $ hg init subrepo-status
1131 $ cd subrepo-status
1131 $ cd subrepo-status
1132 $ hg init subrepo-1
1132 $ hg init subrepo-1
1133 $ hg init subrepo-2
1133 $ hg init subrepo-2
1134 $ cd subrepo-2
1134 $ cd subrepo-2
1135 $ touch file
1135 $ touch file
1136 $ hg add file
1136 $ hg add file
1137 $ cd ..
1137 $ cd ..
1138 $ echo subrepo-1 = subrepo-1 > .hgsub
1138 $ echo subrepo-1 = subrepo-1 > .hgsub
1139 $ echo subrepo-2 = subrepo-2 >> .hgsub
1139 $ echo subrepo-2 = subrepo-2 >> .hgsub
1140 $ hg add .hgsub
1140 $ hg add .hgsub
1141 $ hg ci -m 'Added subrepos'
1141 $ hg ci -m 'Added subrepos'
1142 committing subrepository subrepo-2
1142 committing subrepository subrepo-2
1143 $ hg st subrepo-2/file
1143 $ hg st subrepo-2/file
1144
1144
1145 Check that share works with subrepo
1145 Check that share works with subrepo
1146 $ hg --config extensions.share= share . ../shared
1146 $ hg --config extensions.share= share . ../shared
1147 updating working directory
1147 updating working directory
1148 cloning subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
1148 cloning subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
1149 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1149 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1150 $ test -f ../shared/subrepo-1/.hg/sharedpath
1150 $ test -f ../shared/subrepo-1/.hg/sharedpath
1151 [1]
1151 [1]
1152 $ hg -R ../shared in
1152 $ hg -R ../shared in
1153 abort: repository default not found!
1153 abort: repository default not found!
1154 [255]
1154 [255]
1155 $ hg -R ../shared/subrepo-2 showconfig paths
1155 $ hg -R ../shared/subrepo-2 showconfig paths
1156 paths.default=$TESTTMP/subrepo-status/subrepo-2
1156 paths.default=$TESTTMP/subrepo-status/subrepo-2
1157 $ hg -R ../shared/subrepo-1 sum --remote
1157 $ hg -R ../shared/subrepo-1 sum --remote
1158 parent: -1:000000000000 tip (empty repository)
1158 parent: -1:000000000000 tip (empty repository)
1159 branch: default
1159 branch: default
1160 commit: (clean)
1160 commit: (clean)
1161 update: (current)
1161 update: (current)
1162 remote: (synced)
1162 remote: (synced)
1163
1163
1164 Check hg update --clean
1164 Check hg update --clean
1165 $ cd $TESTTMP/t
1165 $ cd $TESTTMP/t
1166 $ rm -r t/t.orig
1166 $ rm -r t/t.orig
1167 $ hg status -S --all
1167 $ hg status -S --all
1168 C .hgsub
1168 C .hgsub
1169 C .hgsubstate
1169 C .hgsubstate
1170 C a
1170 C a
1171 C s/.hgsub
1171 C s/.hgsub
1172 C s/.hgsubstate
1172 C s/.hgsubstate
1173 C s/a
1173 C s/a
1174 C s/ss/a
1174 C s/ss/a
1175 C t/t
1175 C t/t
1176 $ echo c1 > s/a
1176 $ echo c1 > s/a
1177 $ cd s
1177 $ cd s
1178 $ echo c1 > b
1178 $ echo c1 > b
1179 $ echo c1 > c
1179 $ echo c1 > c
1180 $ hg add b
1180 $ hg add b
1181 $ cd ..
1181 $ cd ..
1182 $ hg status -S
1182 $ hg status -S
1183 M s/a
1183 M s/a
1184 A s/b
1184 A s/b
1185 ? s/c
1185 ? s/c
1186 $ hg update -C
1186 $ hg update -C
1187 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1187 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1188 $ hg status -S
1188 $ hg status -S
1189 ? s/b
1189 ? s/b
1190 ? s/c
1190 ? s/c
1191
1191
1192 Sticky subrepositories, no changes
1192 Sticky subrepositories, no changes
1193 $ cd $TESTTMP/t
1193 $ cd $TESTTMP/t
1194 $ hg id
1194 $ hg id
1195 925c17564ef8 tip
1195 925c17564ef8 tip
1196 $ hg -R s id
1196 $ hg -R s id
1197 12a213df6fa9 tip
1197 12a213df6fa9 tip
1198 $ hg -R t id
1198 $ hg -R t id
1199 52c0adc0515a tip
1199 52c0adc0515a tip
1200 $ hg update 11
1200 $ hg update 11
1201 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1201 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1202 $ hg id
1202 $ hg id
1203 365661e5936a
1203 365661e5936a
1204 $ hg -R s id
1204 $ hg -R s id
1205 fc627a69481f
1205 fc627a69481f
1206 $ hg -R t id
1206 $ hg -R t id
1207 e95bcfa18a35
1207 e95bcfa18a35
1208
1208
1209 Sticky subrepositories, file changes
1209 Sticky subrepositories, file changes
1210 $ touch s/f1
1210 $ touch s/f1
1211 $ touch t/f1
1211 $ touch t/f1
1212 $ hg add -S s/f1
1212 $ hg add -S s/f1
1213 $ hg add -S t/f1
1213 $ hg add -S t/f1
1214 $ hg id
1214 $ hg id
1215 365661e5936a+
1215 365661e5936a+
1216 $ hg -R s id
1216 $ hg -R s id
1217 fc627a69481f+
1217 fc627a69481f+
1218 $ hg -R t id
1218 $ hg -R t id
1219 e95bcfa18a35+
1219 e95bcfa18a35+
1220 $ hg update tip
1220 $ hg update tip
1221 subrepository s diverged (local revision: fc627a69481f, remote revision: 12a213df6fa9)
1221 subrepository s diverged (local revision: fc627a69481f, remote revision: 12a213df6fa9)
1222 (M)erge, keep (l)ocal or keep (r)emote? m
1222 (M)erge, keep (l)ocal or keep (r)emote? m
1223 subrepository sources for s differ
1223 subrepository sources for s differ
1224 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)? l
1224 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)? l
1225 subrepository t diverged (local revision: e95bcfa18a35, remote revision: 52c0adc0515a)
1225 subrepository t diverged (local revision: e95bcfa18a35, remote revision: 52c0adc0515a)
1226 (M)erge, keep (l)ocal or keep (r)emote? m
1226 (M)erge, keep (l)ocal or keep (r)emote? m
1227 subrepository sources for t differ
1227 subrepository sources for t differ
1228 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)? l
1228 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)? l
1229 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1229 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1230 $ hg id
1230 $ hg id
1231 925c17564ef8+ tip
1231 925c17564ef8+ tip
1232 $ hg -R s id
1232 $ hg -R s id
1233 fc627a69481f+
1233 fc627a69481f+
1234 $ hg -R t id
1234 $ hg -R t id
1235 e95bcfa18a35+
1235 e95bcfa18a35+
1236 $ hg update --clean tip
1236 $ hg update --clean tip
1237 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1237 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1238
1238
1239 Sticky subrepository, revision updates
1239 Sticky subrepository, revision updates
1240 $ hg id
1240 $ hg id
1241 925c17564ef8 tip
1241 925c17564ef8 tip
1242 $ hg -R s id
1242 $ hg -R s id
1243 12a213df6fa9 tip
1243 12a213df6fa9 tip
1244 $ hg -R t id
1244 $ hg -R t id
1245 52c0adc0515a tip
1245 52c0adc0515a tip
1246 $ cd s
1246 $ cd s
1247 $ hg update -r -2
1247 $ hg update -r -2
1248 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1248 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1249 $ cd ../t
1249 $ cd ../t
1250 $ hg update -r 2
1250 $ hg update -r 2
1251 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1251 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1252 $ cd ..
1252 $ cd ..
1253 $ hg update 10
1253 $ hg update 10
1254 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1254 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1255 (M)erge, keep (l)ocal or keep (r)emote? m
1255 (M)erge, keep (l)ocal or keep (r)emote? m
1256 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 20a0db6fbf6c)
1256 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 20a0db6fbf6c)
1257 (M)erge, keep (l)ocal or keep (r)emote? m
1257 (M)erge, keep (l)ocal or keep (r)emote? m
1258 subrepository sources for t differ (in checked out version)
1258 subrepository sources for t differ (in checked out version)
1259 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)? l
1259 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)? l
1260 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1260 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1261 $ hg id
1261 $ hg id
1262 e45c8b14af55+
1262 e45c8b14af55+
1263 $ hg -R s id
1263 $ hg -R s id
1264 02dcf1d70411
1264 02dcf1d70411
1265 $ hg -R t id
1265 $ hg -R t id
1266 7af322bc1198
1266 7af322bc1198
1267
1267
1268 Sticky subrepository, file changes and revision updates
1268 Sticky subrepository, file changes and revision updates
1269 $ touch s/f1
1269 $ touch s/f1
1270 $ touch t/f1
1270 $ touch t/f1
1271 $ hg add -S s/f1
1271 $ hg add -S s/f1
1272 $ hg add -S t/f1
1272 $ hg add -S t/f1
1273 $ hg id
1273 $ hg id
1274 e45c8b14af55+
1274 e45c8b14af55+
1275 $ hg -R s id
1275 $ hg -R s id
1276 02dcf1d70411+
1276 02dcf1d70411+
1277 $ hg -R t id
1277 $ hg -R t id
1278 7af322bc1198+
1278 7af322bc1198+
1279 $ hg update tip
1279 $ hg update tip
1280 subrepository s diverged (local revision: 12a213df6fa9, remote revision: 12a213df6fa9)
1280 subrepository s diverged (local revision: 12a213df6fa9, remote revision: 12a213df6fa9)
1281 (M)erge, keep (l)ocal or keep (r)emote? m
1281 (M)erge, keep (l)ocal or keep (r)emote? m
1282 subrepository sources for s differ
1282 subrepository sources for s differ
1283 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)? l
1283 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)? l
1284 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 52c0adc0515a)
1284 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 52c0adc0515a)
1285 (M)erge, keep (l)ocal or keep (r)emote? m
1285 (M)erge, keep (l)ocal or keep (r)emote? m
1286 subrepository sources for t differ
1286 subrepository sources for t differ
1287 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)? l
1287 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)? l
1288 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1288 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1289 $ hg id
1289 $ hg id
1290 925c17564ef8+ tip
1290 925c17564ef8+ tip
1291 $ hg -R s id
1291 $ hg -R s id
1292 02dcf1d70411+
1292 02dcf1d70411+
1293 $ hg -R t id
1293 $ hg -R t id
1294 7af322bc1198+
1294 7af322bc1198+
1295
1295
1296 Sticky repository, update --clean
1296 Sticky repository, update --clean
1297 $ hg update --clean tip
1297 $ hg update --clean tip
1298 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1298 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1299 $ hg id
1299 $ hg id
1300 925c17564ef8 tip
1300 925c17564ef8 tip
1301 $ hg -R s id
1301 $ hg -R s id
1302 12a213df6fa9 tip
1302 12a213df6fa9 tip
1303 $ hg -R t id
1303 $ hg -R t id
1304 52c0adc0515a tip
1304 52c0adc0515a tip
1305
1305
1306 Test subrepo already at intended revision:
1306 Test subrepo already at intended revision:
1307 $ cd s
1307 $ cd s
1308 $ hg update fc627a69481f
1308 $ hg update fc627a69481f
1309 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1309 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1310 $ cd ..
1310 $ cd ..
1311 $ hg update 11
1311 $ hg update 11
1312 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1312 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1313 (M)erge, keep (l)ocal or keep (r)emote? m
1313 (M)erge, keep (l)ocal or keep (r)emote? m
1314 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1314 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1315 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1315 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1316 $ hg id -n
1316 $ hg id -n
1317 11+
1317 11+
1318 $ hg -R s id
1318 $ hg -R s id
1319 fc627a69481f
1319 fc627a69481f
1320 $ hg -R t id
1320 $ hg -R t id
1321 e95bcfa18a35
1321 e95bcfa18a35
1322
1322
1323 Test that removing .hgsubstate doesn't break anything:
1323 Test that removing .hgsubstate doesn't break anything:
1324
1324
1325 $ hg rm -f .hgsubstate
1325 $ hg rm -f .hgsubstate
1326 $ hg ci -mrm
1326 $ hg ci -mrm
1327 nothing changed
1327 nothing changed
1328 [1]
1328 [1]
1329 $ hg log -vr tip
1329 $ hg log -vr tip
1330 changeset: 13:925c17564ef8
1330 changeset: 13:925c17564ef8
1331 tag: tip
1331 tag: tip
1332 user: test
1332 user: test
1333 date: Thu Jan 01 00:00:00 1970 +0000
1333 date: Thu Jan 01 00:00:00 1970 +0000
1334 files: .hgsubstate
1334 files: .hgsubstate
1335 description:
1335 description:
1336 13
1336 13
1337
1337
1338
1338
1339
1339
1340 Test that removing .hgsub removes .hgsubstate:
1340 Test that removing .hgsub removes .hgsubstate:
1341
1341
1342 $ hg rm .hgsub
1342 $ hg rm .hgsub
1343 $ hg ci -mrm2
1343 $ hg ci -mrm2
1344 created new head
1344 created new head
1345 $ hg log -vr tip
1345 $ hg log -vr tip
1346 changeset: 14:2400bccd50af
1346 changeset: 14:2400bccd50af
1347 tag: tip
1347 tag: tip
1348 parent: 11:365661e5936a
1348 parent: 11:365661e5936a
1349 user: test
1349 user: test
1350 date: Thu Jan 01 00:00:00 1970 +0000
1350 date: Thu Jan 01 00:00:00 1970 +0000
1351 files: .hgsub .hgsubstate
1351 files: .hgsub .hgsubstate
1352 description:
1352 description:
1353 rm2
1353 rm2
1354
1354
1355
1355
1356 Test issue3153: diff -S with deleted subrepos
1356 Test issue3153: diff -S with deleted subrepos
1357
1357
1358 $ hg diff --nodates -S -c .
1358 $ hg diff --nodates -S -c .
1359 diff -r 365661e5936a -r 2400bccd50af .hgsub
1359 diff -r 365661e5936a -r 2400bccd50af .hgsub
1360 --- a/.hgsub
1360 --- a/.hgsub
1361 +++ /dev/null
1361 +++ /dev/null
1362 @@ -1,2 +0,0 @@
1362 @@ -1,2 +0,0 @@
1363 -s = s
1363 -s = s
1364 -t = t
1364 -t = t
1365 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
1365 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
1366 --- a/.hgsubstate
1366 --- a/.hgsubstate
1367 +++ /dev/null
1367 +++ /dev/null
1368 @@ -1,2 +0,0 @@
1368 @@ -1,2 +0,0 @@
1369 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1369 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1370 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
1370 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
1371
1371
1372 Test behavior of add for explicit path in subrepo:
1372 Test behavior of add for explicit path in subrepo:
1373 $ cd ..
1373 $ cd ..
1374 $ hg init explicit
1374 $ hg init explicit
1375 $ cd explicit
1375 $ cd explicit
1376 $ echo s = s > .hgsub
1376 $ echo s = s > .hgsub
1377 $ hg add .hgsub
1377 $ hg add .hgsub
1378 $ hg init s
1378 $ hg init s
1379 $ hg ci -m0
1379 $ hg ci -m0
1380 Adding with an explicit path in a subrepo adds the file
1380 Adding with an explicit path in a subrepo adds the file
1381 $ echo c1 > f1
1381 $ echo c1 > f1
1382 $ echo c2 > s/f2
1382 $ echo c2 > s/f2
1383 $ hg st -S
1383 $ hg st -S
1384 ? f1
1384 ? f1
1385 ? s/f2
1385 ? s/f2
1386 $ hg add s/f2
1386 $ hg add s/f2
1387 $ hg st -S
1387 $ hg st -S
1388 A s/f2
1388 A s/f2
1389 ? f1
1389 ? f1
1390 $ hg ci -R s -m0
1390 $ hg ci -R s -m0
1391 $ hg ci -Am1
1391 $ hg ci -Am1
1392 adding f1
1392 adding f1
1393 Adding with an explicit path in a subrepo with -S has the same behavior
1393 Adding with an explicit path in a subrepo with -S has the same behavior
1394 $ echo c3 > f3
1394 $ echo c3 > f3
1395 $ echo c4 > s/f4
1395 $ echo c4 > s/f4
1396 $ hg st -S
1396 $ hg st -S
1397 ? f3
1397 ? f3
1398 ? s/f4
1398 ? s/f4
1399 $ hg add -S s/f4
1399 $ hg add -S s/f4
1400 $ hg st -S
1400 $ hg st -S
1401 A s/f4
1401 A s/f4
1402 ? f3
1402 ? f3
1403 $ hg ci -R s -m1
1403 $ hg ci -R s -m1
1404 $ hg ci -Ama2
1404 $ hg ci -Ama2
1405 adding f3
1405 adding f3
1406 Adding without a path or pattern silently ignores subrepos
1406 Adding without a path or pattern silently ignores subrepos
1407 $ echo c5 > f5
1407 $ echo c5 > f5
1408 $ echo c6 > s/f6
1408 $ echo c6 > s/f6
1409 $ echo c7 > s/f7
1409 $ echo c7 > s/f7
1410 $ hg st -S
1410 $ hg st -S
1411 ? f5
1411 ? f5
1412 ? s/f6
1412 ? s/f6
1413 ? s/f7
1413 ? s/f7
1414 $ hg add
1414 $ hg add
1415 adding f5
1415 adding f5
1416 $ hg st -S
1416 $ hg st -S
1417 A f5
1417 A f5
1418 ? s/f6
1418 ? s/f6
1419 ? s/f7
1419 ? s/f7
1420 $ hg ci -R s -Am2
1420 $ hg ci -R s -Am2
1421 adding f6
1421 adding f6
1422 adding f7
1422 adding f7
1423 $ hg ci -m3
1423 $ hg ci -m3
1424 Adding without a path or pattern with -S also adds files in subrepos
1424 Adding without a path or pattern with -S also adds files in subrepos
1425 $ echo c8 > f8
1425 $ echo c8 > f8
1426 $ echo c9 > s/f9
1426 $ echo c9 > s/f9
1427 $ echo c10 > s/f10
1427 $ echo c10 > s/f10
1428 $ hg st -S
1428 $ hg st -S
1429 ? f8
1429 ? f8
1430 ? s/f10
1430 ? s/f10
1431 ? s/f9
1431 ? s/f9
1432 $ hg add -S
1432 $ hg add -S
1433 adding f8
1433 adding f8
1434 adding s/f10 (glob)
1434 adding s/f10 (glob)
1435 adding s/f9 (glob)
1435 adding s/f9 (glob)
1436 $ hg st -S
1436 $ hg st -S
1437 A f8
1437 A f8
1438 A s/f10
1438 A s/f10
1439 A s/f9
1439 A s/f9
1440 $ hg ci -R s -m3
1440 $ hg ci -R s -m3
1441 $ hg ci -m4
1441 $ hg ci -m4
1442 Adding with a pattern silently ignores subrepos
1442 Adding with a pattern silently ignores subrepos
1443 $ echo c11 > fm11
1443 $ echo c11 > fm11
1444 $ echo c12 > fn12
1444 $ echo c12 > fn12
1445 $ echo c13 > s/fm13
1445 $ echo c13 > s/fm13
1446 $ echo c14 > s/fn14
1446 $ echo c14 > s/fn14
1447 $ hg st -S
1447 $ hg st -S
1448 ? fm11
1448 ? fm11
1449 ? fn12
1449 ? fn12
1450 ? s/fm13
1450 ? s/fm13
1451 ? s/fn14
1451 ? s/fn14
1452 $ hg add 'glob:**fm*'
1452 $ hg add 'glob:**fm*'
1453 adding fm11
1453 adding fm11
1454 $ hg st -S
1454 $ hg st -S
1455 A fm11
1455 A fm11
1456 ? fn12
1456 ? fn12
1457 ? s/fm13
1457 ? s/fm13
1458 ? s/fn14
1458 ? s/fn14
1459 $ hg ci -R s -Am4
1459 $ hg ci -R s -Am4
1460 adding fm13
1460 adding fm13
1461 adding fn14
1461 adding fn14
1462 $ hg ci -Am5
1462 $ hg ci -Am5
1463 adding fn12
1463 adding fn12
1464 Adding with a pattern with -S also adds matches in subrepos
1464 Adding with a pattern with -S also adds matches in subrepos
1465 $ echo c15 > fm15
1465 $ echo c15 > fm15
1466 $ echo c16 > fn16
1466 $ echo c16 > fn16
1467 $ echo c17 > s/fm17
1467 $ echo c17 > s/fm17
1468 $ echo c18 > s/fn18
1468 $ echo c18 > s/fn18
1469 $ hg st -S
1469 $ hg st -S
1470 ? fm15
1470 ? fm15
1471 ? fn16
1471 ? fn16
1472 ? s/fm17
1472 ? s/fm17
1473 ? s/fn18
1473 ? s/fn18
1474 $ hg add -S 'glob:**fm*'
1474 $ hg add -S 'glob:**fm*'
1475 adding fm15
1475 adding fm15
1476 adding s/fm17 (glob)
1476 adding s/fm17 (glob)
1477 $ hg st -S
1477 $ hg st -S
1478 A fm15
1478 A fm15
1479 A s/fm17
1479 A s/fm17
1480 ? fn16
1480 ? fn16
1481 ? s/fn18
1481 ? s/fn18
1482 $ hg ci -R s -Am5
1482 $ hg ci -R s -Am5
1483 adding fn18
1483 adding fn18
1484 $ hg ci -Am6
1484 $ hg ci -Am6
1485 adding fn16
1485 adding fn16
1486
1486
1487 Test behavior of forget for explicit path in subrepo:
1487 Test behavior of forget for explicit path in subrepo:
1488 Forgetting an explicit path in a subrepo untracks the file
1488 Forgetting an explicit path in a subrepo untracks the file
1489 $ echo c19 > s/f19
1489 $ echo c19 > s/f19
1490 $ hg add s/f19
1490 $ hg add s/f19
1491 $ hg st -S
1491 $ hg st -S
1492 A s/f19
1492 A s/f19
1493 $ hg forget s/f19
1493 $ hg forget s/f19
1494 $ hg st -S
1494 $ hg st -S
1495 ? s/f19
1495 ? s/f19
1496 $ rm s/f19
1496 $ rm s/f19
1497 $ cd ..
1497 $ cd ..
1498
1498
1499 Courtesy phases synchronisation to publishing server does not block the push
1499 Courtesy phases synchronisation to publishing server does not block the push
1500 (issue3781)
1500 (issue3781)
1501
1501
1502 $ cp -r main issue3781
1502 $ cp -r main issue3781
1503 $ cp -r main issue3781-dest
1503 $ cp -r main issue3781-dest
1504 $ cd issue3781-dest/s
1504 $ cd issue3781-dest/s
1505 $ hg phase tip # show we have draft changeset
1505 $ hg phase tip # show we have draft changeset
1506 5: draft
1506 5: draft
1507 $ chmod a-w .hg/store/phaseroots # prevent phase push
1507 $ chmod a-w .hg/store/phaseroots # prevent phase push
1508 $ cd ../../issue3781
1508 $ cd ../../issue3781
1509 $ cat >> .hg/hgrc << EOF
1509 $ cat >> .hg/hgrc << EOF
1510 > [paths]
1510 > [paths]
1511 > default=../issue3781-dest/
1511 > default=../issue3781-dest/
1512 > EOF
1512 > EOF
1513 $ hg push --config experimental.bundle2-exp=False
1513 $ hg push --config experimental.bundle2-exp=False
1514 pushing to $TESTTMP/issue3781-dest (glob)
1514 pushing to $TESTTMP/issue3781-dest (glob)
1515 pushing subrepo s to $TESTTMP/issue3781-dest/s
1515 pushing subrepo s to $TESTTMP/issue3781-dest/s
1516 searching for changes
1516 searching for changes
1517 no changes found
1517 no changes found
1518 searching for changes
1518 searching for changes
1519 no changes found
1519 no changes found
1520 [1]
1520 [1]
1521 # clean the push cache
1521 # clean the push cache
1522 $ rm s/.hg/cache/storehash/*
1522 $ rm s/.hg/cache/storehash/*
1523 $ hg push --config experimental.bundle2-exp=True
1523 $ hg push --config experimental.bundle2-exp=True
1524 pushing to $TESTTMP/issue3781-dest (glob)
1524 pushing to $TESTTMP/issue3781-dest (glob)
1525 pushing subrepo s to $TESTTMP/issue3781-dest/s
1525 pushing subrepo s to $TESTTMP/issue3781-dest/s
1526 searching for changes
1526 searching for changes
1527 no changes found
1527 no changes found
1528 searching for changes
1528 searching for changes
1529 no changes found
1529 no changes found
1530 [1]
1530 [1]
1531 $ cd ..
1531 $ cd ..
1532
1532
1533 Test phase choice for newly created commit with "phases.subrepochecks"
1533 Test phase choice for newly created commit with "phases.subrepochecks"
1534 configuration
1534 configuration
1535
1535
1536 $ cd t
1536 $ cd t
1537 $ hg update -q -r 12
1537 $ hg update -q -r 12
1538
1538
1539 $ cat >> s/ss/.hg/hgrc <<EOF
1539 $ cat >> s/ss/.hg/hgrc <<EOF
1540 > [phases]
1540 > [phases]
1541 > new-commit = secret
1541 > new-commit = secret
1542 > EOF
1542 > EOF
1543 $ cat >> s/.hg/hgrc <<EOF
1543 $ cat >> s/.hg/hgrc <<EOF
1544 > [phases]
1544 > [phases]
1545 > new-commit = draft
1545 > new-commit = draft
1546 > EOF
1546 > EOF
1547 $ echo phasecheck1 >> s/ss/a
1547 $ echo phasecheck1 >> s/ss/a
1548 $ hg -R s commit -S --config phases.checksubrepos=abort -m phasecheck1
1548 $ hg -R s commit -S --config phases.checksubrepos=abort -m phasecheck1
1549 committing subrepository ss
1549 committing subrepository ss
1550 transaction abort!
1550 transaction abort!
1551 rollback completed
1551 rollback completed
1552 abort: can't commit in draft phase conflicting secret from subrepository ss
1552 abort: can't commit in draft phase conflicting secret from subrepository ss
1553 [255]
1553 [255]
1554 $ echo phasecheck2 >> s/ss/a
1554 $ echo phasecheck2 >> s/ss/a
1555 $ hg -R s commit -S --config phases.checksubrepos=ignore -m phasecheck2
1555 $ hg -R s commit -S --config phases.checksubrepos=ignore -m phasecheck2
1556 committing subrepository ss
1556 committing subrepository ss
1557 $ hg -R s/ss phase tip
1557 $ hg -R s/ss phase tip
1558 3: secret
1558 3: secret
1559 $ hg -R s phase tip
1559 $ hg -R s phase tip
1560 6: draft
1560 6: draft
1561 $ echo phasecheck3 >> s/ss/a
1561 $ echo phasecheck3 >> s/ss/a
1562 $ hg -R s commit -S -m phasecheck3
1562 $ hg -R s commit -S -m phasecheck3
1563 committing subrepository ss
1563 committing subrepository ss
1564 warning: changes are committed in secret phase from subrepository ss
1564 warning: changes are committed in secret phase from subrepository ss
1565 $ hg -R s/ss phase tip
1565 $ hg -R s/ss phase tip
1566 4: secret
1566 4: secret
1567 $ hg -R s phase tip
1567 $ hg -R s phase tip
1568 7: secret
1568 7: secret
1569
1569
1570 $ cat >> t/.hg/hgrc <<EOF
1570 $ cat >> t/.hg/hgrc <<EOF
1571 > [phases]
1571 > [phases]
1572 > new-commit = draft
1572 > new-commit = draft
1573 > EOF
1573 > EOF
1574 $ cat >> .hg/hgrc <<EOF
1574 $ cat >> .hg/hgrc <<EOF
1575 > [phases]
1575 > [phases]
1576 > new-commit = public
1576 > new-commit = public
1577 > EOF
1577 > EOF
1578 $ echo phasecheck4 >> s/ss/a
1578 $ echo phasecheck4 >> s/ss/a
1579 $ echo phasecheck4 >> t/t
1579 $ echo phasecheck4 >> t/t
1580 $ hg commit -S -m phasecheck4
1580 $ hg commit -S -m phasecheck4
1581 committing subrepository s
1581 committing subrepository s
1582 committing subrepository s/ss (glob)
1582 committing subrepository s/ss (glob)
1583 warning: changes are committed in secret phase from subrepository ss
1583 warning: changes are committed in secret phase from subrepository ss
1584 committing subrepository t
1584 committing subrepository t
1585 warning: changes are committed in secret phase from subrepository s
1585 warning: changes are committed in secret phase from subrepository s
1586 created new head
1586 created new head
1587 $ hg -R s/ss phase tip
1587 $ hg -R s/ss phase tip
1588 5: secret
1588 5: secret
1589 $ hg -R s phase tip
1589 $ hg -R s phase tip
1590 8: secret
1590 8: secret
1591 $ hg -R t phase tip
1591 $ hg -R t phase tip
1592 6: draft
1592 6: draft
1593 $ hg phase tip
1593 $ hg phase tip
1594 15: secret
1594 15: secret
1595
1595
1596 $ cd ..
1596 $ cd ..
1597
1597
1598
1598
1599 Test that commit --secret works on both repo and subrepo (issue4182)
1599 Test that commit --secret works on both repo and subrepo (issue4182)
1600
1600
1601 $ cd main
1601 $ cd main
1602 $ echo secret >> b
1602 $ echo secret >> b
1603 $ echo secret >> s/b
1603 $ echo secret >> s/b
1604 $ hg commit --secret --subrepo -m "secret"
1604 $ hg commit --secret --subrepo -m "secret"
1605 committing subrepository s
1605 committing subrepository s
1606 $ hg phase -r .
1606 $ hg phase -r .
1607 6: secret
1607 6: secret
1608 $ cd s
1608 $ cd s
1609 $ hg phase -r .
1609 $ hg phase -r .
1610 6: secret
1610 6: secret
1611 $ cd ../../
1611 $ cd ../../
1612
1612
1613 Test "subrepos" template keyword
1613 Test "subrepos" template keyword
1614
1614
1615 $ cd t
1615 $ cd t
1616 $ hg update -q 15
1616 $ hg update -q 15
1617 $ cat > .hgsub <<EOF
1617 $ cat > .hgsub <<EOF
1618 > s = s
1618 > s = s
1619 > EOF
1619 > EOF
1620 $ hg commit -m "16"
1620 $ hg commit -m "16"
1621 warning: changes are committed in secret phase from subrepository s
1621 warning: changes are committed in secret phase from subrepository s
1622
1622
1623 (addition of ".hgsub" itself)
1623 (addition of ".hgsub" itself)
1624
1624
1625 $ hg diff --nodates -c 1 .hgsubstate
1625 $ hg diff --nodates -c 1 .hgsubstate
1626 diff -r f7b1eb17ad24 -r 7cf8cfea66e4 .hgsubstate
1626 diff -r f7b1eb17ad24 -r 7cf8cfea66e4 .hgsubstate
1627 --- /dev/null
1627 --- /dev/null
1628 +++ b/.hgsubstate
1628 +++ b/.hgsubstate
1629 @@ -0,0 +1,1 @@
1629 @@ -0,0 +1,1 @@
1630 +e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1630 +e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1631 $ hg log -r 1 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1631 $ hg log -r 1 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1632 f7b1eb17ad24 000000000000
1632 f7b1eb17ad24 000000000000
1633 s
1633 s
1634
1634
1635 (modification of existing entry)
1635 (modification of existing entry)
1636
1636
1637 $ hg diff --nodates -c 2 .hgsubstate
1637 $ hg diff --nodates -c 2 .hgsubstate
1638 diff -r 7cf8cfea66e4 -r df30734270ae .hgsubstate
1638 diff -r 7cf8cfea66e4 -r df30734270ae .hgsubstate
1639 --- a/.hgsubstate
1639 --- a/.hgsubstate
1640 +++ b/.hgsubstate
1640 +++ b/.hgsubstate
1641 @@ -1,1 +1,1 @@
1641 @@ -1,1 +1,1 @@
1642 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1642 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1643 +dc73e2e6d2675eb2e41e33c205f4bdab4ea5111d s
1643 +dc73e2e6d2675eb2e41e33c205f4bdab4ea5111d s
1644 $ hg log -r 2 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1644 $ hg log -r 2 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1645 7cf8cfea66e4 000000000000
1645 7cf8cfea66e4 000000000000
1646 s
1646 s
1647
1647
1648 (addition of entry)
1648 (addition of entry)
1649
1649
1650 $ hg diff --nodates -c 5 .hgsubstate
1650 $ hg diff --nodates -c 5 .hgsubstate
1651 diff -r 7cf8cfea66e4 -r 1f14a2e2d3ec .hgsubstate
1651 diff -r 7cf8cfea66e4 -r 1f14a2e2d3ec .hgsubstate
1652 --- a/.hgsubstate
1652 --- a/.hgsubstate
1653 +++ b/.hgsubstate
1653 +++ b/.hgsubstate
1654 @@ -1,1 +1,2 @@
1654 @@ -1,1 +1,2 @@
1655 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1655 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1656 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1656 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1657 $ hg log -r 5 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1657 $ hg log -r 5 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1658 7cf8cfea66e4 000000000000
1658 7cf8cfea66e4 000000000000
1659 t
1659 t
1660
1660
1661 (removal of existing entry)
1661 (removal of existing entry)
1662
1662
1663 $ hg diff --nodates -c 16 .hgsubstate
1663 $ hg diff --nodates -c 16 .hgsubstate
1664 diff -r 8bec38d2bd0b -r f2f70bc3d3c9 .hgsubstate
1664 diff -r 8bec38d2bd0b -r f2f70bc3d3c9 .hgsubstate
1665 --- a/.hgsubstate
1665 --- a/.hgsubstate
1666 +++ b/.hgsubstate
1666 +++ b/.hgsubstate
1667 @@ -1,2 +1,1 @@
1667 @@ -1,2 +1,1 @@
1668 0731af8ca9423976d3743119d0865097c07bdc1b s
1668 0731af8ca9423976d3743119d0865097c07bdc1b s
1669 -e202dc79b04c88a636ea8913d9182a1346d9b3dc t
1669 -e202dc79b04c88a636ea8913d9182a1346d9b3dc t
1670 $ hg log -r 16 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1670 $ hg log -r 16 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1671 8bec38d2bd0b 000000000000
1671 8bec38d2bd0b 000000000000
1672 t
1672 t
1673
1673
1674 (merging)
1674 (merging)
1675
1675
1676 $ hg diff --nodates -c 9 .hgsubstate
1676 $ hg diff --nodates -c 9 .hgsubstate
1677 diff -r f6affe3fbfaa -r f0d2028bf86d .hgsubstate
1677 diff -r f6affe3fbfaa -r f0d2028bf86d .hgsubstate
1678 --- a/.hgsubstate
1678 --- a/.hgsubstate
1679 +++ b/.hgsubstate
1679 +++ b/.hgsubstate
1680 @@ -1,1 +1,2 @@
1680 @@ -1,1 +1,2 @@
1681 fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1681 fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1682 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1682 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1683 $ hg log -r 9 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1683 $ hg log -r 9 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1684 f6affe3fbfaa 1f14a2e2d3ec
1684 f6affe3fbfaa 1f14a2e2d3ec
1685 t
1685 t
1686
1686
1687 (removal of ".hgsub" itself)
1687 (removal of ".hgsub" itself)
1688
1688
1689 $ hg diff --nodates -c 8 .hgsubstate
1689 $ hg diff --nodates -c 8 .hgsubstate
1690 diff -r f94576341bcf -r 96615c1dad2d .hgsubstate
1690 diff -r f94576341bcf -r 96615c1dad2d .hgsubstate
1691 --- a/.hgsubstate
1691 --- a/.hgsubstate
1692 +++ /dev/null
1692 +++ /dev/null
1693 @@ -1,2 +0,0 @@
1693 @@ -1,2 +0,0 @@
1694 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1694 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1695 -7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4 t
1695 -7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4 t
1696 $ hg log -r 8 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1696 $ hg log -r 8 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1697 f94576341bcf 000000000000
1697 f94576341bcf 000000000000
1698
1698
1699 Test that '[paths]' is configured correctly at subrepo creation
1699 Test that '[paths]' is configured correctly at subrepo creation
1700
1700
1701 $ cd $TESTTMP/tc
1701 $ cd $TESTTMP/tc
1702 $ cat > .hgsub <<EOF
1702 $ cat > .hgsub <<EOF
1703 > # to clear bogus subrepo path 'bogus=[boguspath'
1703 > # to clear bogus subrepo path 'bogus=[boguspath'
1704 > s = s
1704 > s = s
1705 > t = t
1705 > t = t
1706 > EOF
1706 > EOF
1707 $ hg update -q --clean null
1707 $ hg update -q --clean null
1708 $ rm -rf s t
1708 $ rm -rf s t
1709 $ cat >> .hg/hgrc <<EOF
1709 $ cat >> .hg/hgrc <<EOF
1710 > [paths]
1710 > [paths]
1711 > default-push = /foo/bar
1711 > default-push = /foo/bar
1712 > EOF
1712 > EOF
1713 $ hg update -q
1713 $ hg update -q
1714 $ cat s/.hg/hgrc
1714 $ cat s/.hg/hgrc
1715 [paths]
1715 [paths]
1716 default = $TESTTMP/t/s
1716 default = $TESTTMP/t/s
1717 default-push = /foo/bar/s
1717 default-push = /foo/bar/s
1718 $ cat s/ss/.hg/hgrc
1718 $ cat s/ss/.hg/hgrc
1719 [paths]
1719 [paths]
1720 default = $TESTTMP/t/s/ss
1720 default = $TESTTMP/t/s/ss
1721 default-push = /foo/bar/s/ss
1721 default-push = /foo/bar/s/ss
1722 $ cat t/.hg/hgrc
1722 $ cat t/.hg/hgrc
1723 [paths]
1723 [paths]
1724 default = $TESTTMP/t/t
1724 default = $TESTTMP/t/t
1725 default-push = /foo/bar/t
1725 default-push = /foo/bar/t
1726
1726
1727 $ cd $TESTTMP/t
1727 $ cd $TESTTMP/t
1728 $ hg up -qC 0
1728 $ hg up -qC 0
1729 $ echo 'bar' > bar.txt
1729 $ echo 'bar' > bar.txt
1730 $ hg ci -Am 'branch before subrepo add'
1730 $ hg ci -Am 'branch before subrepo add'
1731 adding bar.txt
1731 adding bar.txt
1732 created new head
1732 created new head
1733 $ hg merge -r "first(subrepo('s'))"
1733 $ hg merge -r "first(subrepo('s'))"
1734 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1734 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1735 (branch merge, don't forget to commit)
1735 (branch merge, don't forget to commit)
1736 $ hg status -S -X '.hgsub*'
1736 $ hg status -S -X '.hgsub*'
1737 A s/a
1737 A s/a
1738 ? s/b
1738 ? s/b
1739 ? s/c
1739 ? s/c
1740 ? s/f1
1740 ? s/f1
1741 $ hg status -S --rev 'p2()'
1741 $ hg status -S --rev 'p2()'
1742 A bar.txt
1742 A bar.txt
1743 ? s/b
1743 ? s/b
1744 ? s/c
1744 ? s/c
1745 ? s/f1
1745 ? s/f1
1746 $ hg diff -S -X '.hgsub*' --nodates
1746 $ hg diff -S -X '.hgsub*' --nodates
1747 diff -r 000000000000 s/a
1747 diff -r 000000000000 s/a
1748 --- /dev/null
1748 --- /dev/null
1749 +++ b/s/a
1749 +++ b/s/a
1750 @@ -0,0 +1,1 @@
1750 @@ -0,0 +1,1 @@
1751 +a
1751 +a
1752 $ hg diff -S --rev 'p2()' --nodates
1752 $ hg diff -S --rev 'p2()' --nodates
1753 diff -r 7cf8cfea66e4 bar.txt
1753 diff -r 7cf8cfea66e4 bar.txt
1754 --- /dev/null
1754 --- /dev/null
1755 +++ b/bar.txt
1755 +++ b/bar.txt
1756 @@ -0,0 +1,1 @@
1756 @@ -0,0 +1,1 @@
1757 +bar
1757 +bar
1758
1758
1759 $ cd ..
1759 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now